[PATCH] xf86: Cleanup stale GPU screens

Thierry Reding thierry.reding at gmail.com
Wed Jun 25 05:36:19 PDT 2014


From: Thierry Reding <treding at nvidia.com>

When only non-PCI devices exist in the system, the platform probe code
will fail to recognize any of them as primary devices and therefore only
create GPU screens. However, higher-level logic will in that case fall
back to the legacy probe method. However the previously allocated GPU
screens are never cleaned up, so the devices remain claimed, which will
cause the legacy probe method to fail as well.

This patch attempts to fix this by cleaning up any GPU screens that have
been allocated and unclaim platform device slots if no primary screen
was found. That will allow the legacy probe fallback to run properly and
register the device itself.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
Note that this could possibly break multi-GPU setups again, so it might
be a good idea for someone to verify this on such a setup.

If so that should only be possible if the xf86platformProbeDev() probes all
the GPU screens whereas the primary screen is added via xf86PciProbeDev(),
which is somewhat weird.

 hw/xfree86/common/xf86platformBus.c | 58 +++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index dd118a28565b..5078ba388107 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -423,6 +423,64 @@ xf86platformProbeDev(DriverPtr drvp)
         }
     }
 
+    /*
+     * Note that the X server interface to drivers lacks a way to properly
+     * undo the changes done in platformProbe(). This causes a lot of stale
+     * global state when the above determines that no screens were found.
+     * This is a little white lie in itself, since in many cases a screen
+     * will in fact have been created.
+     *
+     * Currently the server doesn't allow non-PCI devices as primary devices
+     * and therefore will only add GPU screens for them.
+     *
+     * Drivers usually call xf86AllocateScreen(), which modifies the global
+     * list of screens, but since the X server doesn't call back into them
+     * upon failure, they have no way of cleaning up what they did via the
+     * xf86DeleteScreen() function.
+     *
+     * To work around this, clean up the global state that was left over by
+     * any of the drivers' platformProbe() implementations. This currently
+     * assumes that drivers won't do more than allocate a screen and claim
+     * a platform slot. Anything beyond that would be driver-specific and
+     * not easy to undo here.
+     */
+    if (!foundScreen) {
+        /* Unclaim platform slots. */
+        for (i = 0; i < xf86_num_platform_devices; i++) {
+            struct xf86_platform_device *dev = &xf86_platform_devices[i];
+
+            /*
+             * We don't have a way to match the device to the proper entry in
+             * devList. However, this cleanup will only be done if no primary
+             * device was found in which case the only slots that have been
+             * claimed are those that correspond to the GPU screens added in
+             * the xf86Info.autoAddGPU conditional above and which did claim
+             * devList[0].
+             */
+            xf86UnclaimPlatformSlot(dev, devList[0]);
+        }
+
+        /* Remove all GPU screens if any. */
+        for (i = 0; i < xf86NumGPUScreens; i++) {
+            if (xf86GPUScreens[i]) {
+                if (xf86GPUScreens[i]->pScreen)
+                    RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
+
+                xf86DeleteScreen(xf86GPUScreens[i]);
+            }
+        }
+
+        /*
+         * Remove all screens if any. (Note that this shouldn't strictly be
+         * necessary since all screens registered in this case should be GPU
+         * screens (from the xf86Info.autoAddGPU conditional above). However
+         * drivers could have ignored the PLATFORM_PROBE_GPU_SCREEN flag and
+         * allocated a regular screen.
+         */
+        for (i = 0; i < xf86NumScreens; i++)
+            xf86DeleteScreen(xf86Screens[i]);
+    }
+
     return foundScreen;
 }
 
-- 
2.0.0



More information about the xorg-devel mailing list