fix bug with GPU hotplugging while VT switched
This commit is contained in:
parent
528aae170f
commit
becc53e876
@ -42,7 +42,7 @@
|
||||
Summary: X.Org X11 X server
|
||||
Name: xorg-x11-server
|
||||
Version: 1.14.0
|
||||
Release: 3%{?gitdate:.%{gitdate}}%{dist}
|
||||
Release: 4%{?gitdate:.%{gitdate}}%{dist}
|
||||
URL: http://www.x.org
|
||||
License: MIT
|
||||
Group: User Interface/X
|
||||
@ -118,6 +118,9 @@ Patch7070: 0001-randr-report-changes-when-we-disconnect-a-GPU-slave.patch
|
||||
Patch7071: 0001-os-use-libunwind-to-generate-backtraces.patch
|
||||
%endif
|
||||
|
||||
# upstream submitted
|
||||
Patch7072: xserver-1.14.0-fix-gpu-hotplug-vt-switch.patch
|
||||
|
||||
%global moduledir %{_libdir}/xorg/modules
|
||||
%global drimoduledir %{_libdir}/dri
|
||||
%global sdkdir %{_includedir}/xorg
|
||||
@ -590,6 +593,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{xserver_source_dir}
|
||||
|
||||
%changelog
|
||||
* Fri Apr 12 2013 Dave Airlie <airlied@redhat.com> 1.14.0-4
|
||||
- fix bug with GPU hotplugging while VT switched
|
||||
|
||||
* Fri Mar 22 2013 Dan Horák <dan@danny.cz> 1.14.0-3
|
||||
- libunwind exists only on selected arches
|
||||
|
||||
|
293
xserver-1.14.0-fix-gpu-hotplug-vt-switch.patch
Normal file
293
xserver-1.14.0-fix-gpu-hotplug-vt-switch.patch
Normal file
@ -0,0 +1,293 @@
|
||||
From 5e9e979fae229480d1a4af4f247c0251cb2852f9 Mon Sep 17 00:00:00 2001
|
||||
From: Fedora X Ninjas <x@fedoraproject.org>
|
||||
Date: Fri, 12 Apr 2013 10:16:21 +1000
|
||||
Subject: [PATCH] fix GPU hotplugging while VT switched.
|
||||
|
||||
Backports 3 patches from upstream into one.
|
||||
---
|
||||
hw/xfree86/common/xf86.h | 1 +
|
||||
hw/xfree86/common/xf86Events.c | 15 +++++++++-
|
||||
hw/xfree86/common/xf86Init.c | 2 +-
|
||||
hw/xfree86/common/xf86Xinput.c | 2 +-
|
||||
hw/xfree86/common/xf86platformBus.c | 19 +++++++++++++
|
||||
hw/xfree86/common/xf86platformBus.h | 4 +++
|
||||
hw/xfree86/os-support/linux/lnx_platform.c | 45 ++++++++++++++++++++++++++----
|
||||
hw/xfree86/os-support/solaris/sun_init.c | 2 +-
|
||||
hw/xfree86/os-support/xf86_OSproc.h | 3 ++
|
||||
include/hotplug.h | 1 +
|
||||
10 files changed, 85 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
|
||||
index 1514c26..828d958 100644
|
||||
--- a/hw/xfree86/common/xf86.h
|
||||
+++ b/hw/xfree86/common/xf86.h
|
||||
@@ -243,6 +243,7 @@ extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler) (void));
|
||||
extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
|
||||
extern _X_EXPORT void xf86ProcessActionEvent(ActionEvent action, void *arg);
|
||||
extern _X_EXPORT void xf86PrintBacktrace(void);
|
||||
+extern _X_EXPORT Bool xf86VTOwner(void);
|
||||
|
||||
/* xf86Helper.c */
|
||||
|
||||
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
|
||||
index d92174e..7a35250 100644
|
||||
--- a/hw/xfree86/common/xf86Events.c
|
||||
+++ b/hw/xfree86/common/xf86Events.c
|
||||
@@ -84,6 +84,7 @@
|
||||
#include "dpmsproc.h"
|
||||
#endif
|
||||
|
||||
+#include "xf86platformBus.h"
|
||||
/*
|
||||
* This is a toggling variable:
|
||||
* FALSE = No VT switching keys have been pressed last time around
|
||||
@@ -428,7 +429,7 @@ xf86VTSwitch(void)
|
||||
* Since all screens are currently all in the same state it is sufficient
|
||||
* check the first. This might change in future.
|
||||
*/
|
||||
- if (xf86Screens[0]->vtSema) {
|
||||
+ if (xf86VTOwner()) {
|
||||
|
||||
DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
|
||||
BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
|
||||
@@ -561,6 +562,9 @@ xf86VTSwitch(void)
|
||||
for (ih = InputHandlers; ih; ih = ih->next)
|
||||
xf86EnableInputHandler(ih);
|
||||
|
||||
+ /* check for any new output devices */
|
||||
+ xf86platformVTProbe();
|
||||
+
|
||||
OsReleaseSIGIO();
|
||||
}
|
||||
}
|
||||
@@ -769,3 +773,12 @@ DDXRingBell(int volume, int pitch, int duration)
|
||||
{
|
||||
xf86OSRingBell(volume, pitch, duration);
|
||||
}
|
||||
+
|
||||
+Bool
|
||||
+xf86VTOwner(void)
|
||||
+{
|
||||
+ /* at system startup xf86Screens[0] won't be set - but we will own the VT */
|
||||
+ if (xf86NumScreens == 0)
|
||||
+ return TRUE;
|
||||
+ return xf86Screens[0]->vtSema;
|
||||
+}
|
||||
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
|
||||
index a34d7c1..142ce95 100644
|
||||
--- a/hw/xfree86/common/xf86Init.c
|
||||
+++ b/hw/xfree86/common/xf86Init.c
|
||||
@@ -829,7 +829,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
|
||||
if (serverGeneration != 1) {
|
||||
xf86Resetting = TRUE;
|
||||
/* All screens are in the same state, so just check the first */
|
||||
- if (!xf86Screens[0]->vtSema) {
|
||||
+ if (!xf86VTOwner()) {
|
||||
#ifdef HAS_USL_VTS
|
||||
ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
|
||||
#endif
|
||||
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
|
||||
index bee407b..26c03c6 100644
|
||||
--- a/hw/xfree86/common/xf86Xinput.c
|
||||
+++ b/hw/xfree86/common/xf86Xinput.c
|
||||
@@ -870,7 +870,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
|
||||
}
|
||||
|
||||
/* Enable it if it's properly initialised and we're currently in the VT */
|
||||
- if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema) {
|
||||
+ if (enable && dev->inited && dev->startup && xf86VTOwner()) {
|
||||
OsBlockSignals();
|
||||
EnableDevice(dev, TRUE);
|
||||
if (!dev->enabled) {
|
||||
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
|
||||
index 4ccb005..0b0f846 100644
|
||||
--- a/hw/xfree86/common/xf86platformBus.c
|
||||
+++ b/hw/xfree86/common/xf86platformBus.c
|
||||
@@ -114,6 +114,11 @@ xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+Bool
|
||||
+xf86_get_platform_device_unowned(int index)
|
||||
+{
|
||||
+ return xf86_platform_devices[index].attribs->unowned;
|
||||
+}
|
||||
|
||||
/*
|
||||
* xf86IsPrimaryPlatform() -- return TRUE if primary device
|
||||
@@ -502,4 +507,18 @@ xf86platformRemoveDevice(int index)
|
||||
out:
|
||||
return;
|
||||
}
|
||||
+
|
||||
+/* called on return from VT switch to find any new devices */
|
||||
+void xf86platformVTProbe(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < xf86_num_platform_devices; i++) {
|
||||
+ if (xf86_platform_devices[i].attribs->unowned == FALSE)
|
||||
+ continue;
|
||||
+
|
||||
+ xf86_platform_devices[i].attribs->unowned = FALSE;
|
||||
+ xf86PlatformReprobeDevice(i, xf86_platform_devices[i].attribs);
|
||||
+ }
|
||||
+}
|
||||
#endif
|
||||
diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h
|
||||
index 49afc24..4e17578 100644
|
||||
--- a/hw/xfree86/common/xf86platformBus.h
|
||||
+++ b/hw/xfree86/common/xf86platformBus.h
|
||||
@@ -46,6 +46,8 @@ extern int
|
||||
xf86_remove_platform_device(int dev_index);
|
||||
extern Bool
|
||||
xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
|
||||
+extern Bool
|
||||
+xf86_get_platform_device_unowned(int index);
|
||||
|
||||
extern int
|
||||
xf86platformAddDevice(int index);
|
||||
@@ -59,6 +61,8 @@ xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *bu
|
||||
|
||||
extern _X_EXPORT int
|
||||
xf86PlatformMatchDriver(char *matches[], int nmatches);
|
||||
+
|
||||
+extern void xf86platformVTProbe(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c
|
||||
index 76f5583..21768ee 100644
|
||||
--- a/hw/xfree86/os-support/linux/lnx_platform.c
|
||||
+++ b/hw/xfree86/os-support/linux/lnx_platform.c
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "hotplug.h"
|
||||
|
||||
static Bool
|
||||
-get_drm_info(struct OdevAttributes *attribs, char *path)
|
||||
+get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
|
||||
{
|
||||
drmSetVersion sv;
|
||||
char *buf;
|
||||
@@ -37,10 +37,14 @@ get_drm_info(struct OdevAttributes *attribs, char *path)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- xf86_add_platform_device(attribs);
|
||||
+ /* for a delayed probe we've already added the device */
|
||||
+ if (delayed_index == -1) {
|
||||
+ xf86_add_platform_device(attribs);
|
||||
+ delayed_index = xf86_num_platform_devices - 1;
|
||||
+ }
|
||||
|
||||
buf = drmGetBusid(fd);
|
||||
- xf86_add_platform_device_attrib(xf86_num_platform_devices - 1,
|
||||
+ xf86_add_platform_device_attrib(delayed_index,
|
||||
ODEV_ATTRIB_BUSID, buf);
|
||||
drmFreeBusid(buf);
|
||||
close(fd);
|
||||
@@ -89,6 +93,23 @@ xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *bu
|
||||
}
|
||||
|
||||
void
|
||||
+xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs)
|
||||
+{
|
||||
+ Bool ret;
|
||||
+ char *dpath;
|
||||
+ dpath = xf86_get_platform_attrib(index, ODEV_ATTRIB_PATH);
|
||||
+
|
||||
+ ret = get_drm_info(attribs, dpath, index);
|
||||
+ if (ret == FALSE) {
|
||||
+ xf86_remove_platform_device(index);
|
||||
+ return;
|
||||
+ }
|
||||
+ ret = xf86platformAddDevice(index);
|
||||
+ if (ret == -1)
|
||||
+ xf86_remove_platform_device(index);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
|
||||
{
|
||||
struct OdevAttribute *attrib;
|
||||
@@ -119,7 +140,15 @@ xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
|
||||
LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n",
|
||||
path);
|
||||
|
||||
- ret = get_drm_info(attribs, path);
|
||||
+ if (!xf86VTOwner()) {
|
||||
+ /* if we don't currently own the VT then don't probe the device,
|
||||
+ just mark it as unowned for later use */
|
||||
+ attribs->unowned = TRUE;
|
||||
+ xf86_add_platform_device(attribs);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ret = get_drm_info(attribs, path, -1);
|
||||
if (ret == FALSE)
|
||||
goto out_free;
|
||||
|
||||
@@ -138,6 +167,9 @@ void NewGPUDeviceRequest(struct OdevAttributes *attribs)
|
||||
if (old_num == xf86_num_platform_devices)
|
||||
return;
|
||||
|
||||
+ if (xf86_get_platform_device_unowned(xf86_num_platform_devices - 1) == TRUE)
|
||||
+ return;
|
||||
+
|
||||
ret = xf86platformAddDevice(xf86_num_platform_devices-1);
|
||||
if (ret == -1)
|
||||
xf86_remove_platform_device(xf86_num_platform_devices-1);
|
||||
@@ -171,7 +203,10 @@ void DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
|
||||
|
||||
ErrorF("xf86: remove device %d %s\n", index, syspath);
|
||||
|
||||
- xf86platformRemoveDevice(index);
|
||||
+ if (xf86_get_platform_device_unowned(index) == TRUE)
|
||||
+ xf86_remove_platform_device(index);
|
||||
+ else
|
||||
+ xf86platformRemoveDevice(index);
|
||||
out:
|
||||
config_odev_free_attribute_list(attribs);
|
||||
}
|
||||
diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
|
||||
index 4b75a98..68527a5 100644
|
||||
--- a/hw/xfree86/os-support/solaris/sun_init.c
|
||||
+++ b/hw/xfree86/os-support/solaris/sun_init.c
|
||||
@@ -274,7 +274,7 @@ xf86OpenConsole(void)
|
||||
* this is to make sure we don't continue until the activate
|
||||
* signal is received.
|
||||
*/
|
||||
- if (!xf86Screens[0]->vtSema)
|
||||
+ if (!xf86VTOwner())
|
||||
sleep(5);
|
||||
}
|
||||
#endif /* HAS_USL_VTS */
|
||||
diff --git a/hw/xfree86/os-support/xf86_OSproc.h b/hw/xfree86/os-support/xf86_OSproc.h
|
||||
index ea2b16e..6be5946 100644
|
||||
--- a/hw/xfree86/os-support/xf86_OSproc.h
|
||||
+++ b/hw/xfree86/os-support/xf86_OSproc.h
|
||||
@@ -223,6 +223,9 @@ extern _X_EXPORT void xf86InitVidMem(void);
|
||||
#include "hotplug.h"
|
||||
void
|
||||
xf86PlatformDeviceProbe(struct OdevAttributes *attribs);
|
||||
+
|
||||
+void
|
||||
+xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs);
|
||||
#endif
|
||||
|
||||
_XFUNCPROTOEND
|
||||
diff --git a/include/hotplug.h b/include/hotplug.h
|
||||
index 2a95b45..29a22c4 100644
|
||||
--- a/include/hotplug.h
|
||||
+++ b/include/hotplug.h
|
||||
@@ -40,6 +40,7 @@ struct OdevAttribute {
|
||||
|
||||
struct OdevAttributes {
|
||||
struct xorg_list list;
|
||||
+ Bool unowned;
|
||||
};
|
||||
|
||||
struct OdevAttributes *
|
||||
--
|
||||
1.8.2
|
||||
|
Loading…
Reference in New Issue
Block a user