xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Nov 17 00:10:31 UTC 2022


 hw/xfree86/common/xf86platformBus.c        |   55 +++++++++++++++++++++++++----
 hw/xfree86/common/xf86platformBus.h        |    4 +-
 hw/xfree86/man/xorg.conf.man               |   15 +++++++
 hw/xfree86/os-support/linux/lnx_platform.c |   10 ++++-
 4 files changed, 74 insertions(+), 10 deletions(-)

New commits:
commit 82bf391c933cd14b92f0ac96b7937497353c1b30
Author: Shashank Sharma <shashank.sharma at amd.com>
Date:   Tue Aug 16 13:39:59 2022 +0200

    xf86: allow DDX driver for GPU/PCI hot-plug
    
    The current X server infrastructure sets modesetting driver as default driver
    to handle PCI-hotplug of a GPU device. This prevents the respective DDX driver
    (like AMDGPU DDX driver) to take control of the card.
    
    This patch:
    - Adds a few functions and fine-tunes the GPU hotplug infrastructure to allow
      the DDX driver to be loaded, if it is configured in the X config file
      options as "hotplug-driver".
    - Scans and updates the PCI device list before adding the new GPU device
      in platform, so that the association of the platform device and PCI device
      is in place (dev->pdev).
    - Adds documentation of this new option
    
    An example usage in the config file would look like:
    
    Section "OutputClass"
            Identifier "AMDgpu"
            MatchDriver "amdgpu"
            Driver "amdgpu"
            HotplugDriver "amdgpu"
    EndSection
    
    V2:
    Fixed typo in commit message (Martin)
    Added R-B from Adam.
    Added ACK from Alex and Martin.
    
    V3:
    Added an output class based approach for finding the DDX driver (Aaron)
    Rebase
    
    V4:
    Addressed review comment from Aaron:
    GPU hot-plug handling driver's name to be read from the DDX config file options.
    In this way only the DDX drivers interested in handling GPU hot-plug will be
    picked and loaded, for others modesetting driver will be used as usual.
    
    V5:
    Addressed review comments from Aaron:
    - X config option to be listed in CamelCase.
    - Indentation fix at one place.
    - Code readability related optimization.
    
    V6:
    Addressed review comments from Aaron:
    - Squash the doc in the same patch
    - Doc formatting changes
    
    Cc: Alex Deucher <alexander.deucher at amd.com>
    Suggested-by: Aaron Plattner aplattner at nvidia.com (v3)
    Acked-by: Martin Roukala martin.roukala at mupuf.org(v1)
    Acked-by: Alex Deucher alexander.deucher at amd.com (v1)
    Reviewed-by: Adam Jackson ajax at redhat.com(v1)
    Signed-off-by: Shashank Sharma shashank.sharma at amd.com

diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 071f44b2a..1d1f87c74 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -272,6 +272,22 @@ xf86PlatformMatchDriver(XF86MatchedDrivers *md)
     }
 }
 
+void xf86PlatformScanPciDev(void)
+{
+    int i;
+
+    if (!xf86scanpci())
+        return;
+
+    xf86Msg(X_CONFIG, "Scanning the platform PCI devices\n");
+    for (i = 0; i < xf86_num_platform_devices; i++) {
+        char *busid = xf86_platform_odev_attributes(i)->busid;
+
+        if (strncmp(busid, "pci:", 4) == 0)
+            platform_find_pci_info(&xf86_platform_devices[i], busid);
+    }
+}
+
 int
 xf86platformProbe(void)
 {
@@ -613,31 +629,58 @@ xf86platformAddGPUDevices(DriverPtr drvp)
     return foundScreen;
 }
 
+const char *
+xf86PlatformFindHotplugDriver(int dev_index)
+{
+    XF86ConfOutputClassPtr cl;
+    const char *hp_driver = NULL;
+    struct xf86_platform_device *dev = &xf86_platform_devices[dev_index];
+
+    for (cl = xf86configptr->conf_outputclass_lst; cl; cl = cl->list.next) {
+        if (!OutputClassMatches(cl, dev) || !cl->option_lst)
+	    continue;
+
+        hp_driver = xf86FindOptionValue(cl->option_lst, "HotplugDriver");
+        if (hp_driver)
+            xf86MarkOptionUsed(cl->option_lst);
+    }
+
+    /* Return the first driver from the match list */
+    xf86Msg(X_INFO, "matching hotplug-driver is %s\n",
+            hp_driver ? hp_driver : "none");
+    return hp_driver;
+}
+
 int
-xf86platformAddDevice(int index)
+xf86platformAddDevice(const char *driver_name, int index)
 {
     int i, old_screens, scr_index, scrnum;
     DriverPtr drvp = NULL;
     screenLayoutPtr layout;
-    static const char *hotplug_driver_name = "modesetting";
 
     if (!xf86Info.autoAddGPU)
         return -1;
 
-    /* force load the driver for now */
-    xf86LoadOneModule(hotplug_driver_name, NULL);
+    /* Load modesetting driver if no driver given, or driver open failed */
+    if (!driver_name || !xf86LoadOneModule(driver_name, NULL)) {
+        driver_name = "modesetting";
+        xf86LoadOneModule(driver_name, NULL);
+    }
 
     for (i = 0; i < xf86NumDrivers; i++) {
         if (!xf86DriverList[i])
             continue;
 
-        if (!strcmp(xf86DriverList[i]->driverName, hotplug_driver_name)) {
+        if (!strcmp(xf86DriverList[i]->driverName, driver_name)) {
             drvp = xf86DriverList[i];
             break;
         }
     }
-    if (i == xf86NumDrivers)
+
+    if (i == xf86NumDrivers) {
+        ErrorF("can't find driver %s for hotplugged device\n", driver_name);
         return -1;
+    }
 
     old_screens = xf86NumGPUScreens;
     doPlatformProbe(&xf86_platform_devices[index], drvp, NULL,
diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h
index 1e75e6352..9979106a1 100644
--- a/hw/xfree86/common/xf86platformBus.h
+++ b/hw/xfree86/common/xf86platformBus.h
@@ -44,6 +44,8 @@ int xf86platformProbe(void);
 int xf86platformProbeDev(DriverPtr drvp);
 int xf86platformAddGPUDevices(DriverPtr drvp);
 void xf86MergeOutputClassOptions(int entityIndex, void **options);
+void xf86PlatformScanPciDev(void);
+const char *xf86PlatformFindHotplugDriver(int dev_index);
 
 extern int xf86_num_platform_devices;
 extern struct xf86_platform_device *xf86_platform_devices;
@@ -56,7 +58,7 @@ extern Bool
 xf86_get_platform_device_unowned(int index);
 
 extern int
-xf86platformAddDevice(int index);
+xf86platformAddDevice(const char *driver_name, int index);
 extern void
 xf86platformRemoveDevice(int index);
 
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index ac88d7e7a..01b47247e 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -1296,7 +1296,20 @@ This option specifies that the matched device should be treated as the
 primary GPU, replacing the selection of the GPU used as output by the
 firmware. If multiple output devices match an OutputClass section with
 the PrimaryGPU option set, the first one enumerated becomes the primary GPU.
-.PP
+.TP 7
+.BI "Option \*qHotplugDriver\*q \*q" driver \*q
+This option specifies that the matched driver should be used to handle a
+hot-plugged GPU device.
+The module specified by
+.I driver
+will be loaded during setup of the GPU device.
+If loading of this module fails or there is no driver by that name, the
+modesetting driver will be used, which is the default behavior.
+If multiple output devices match an
+.B OutputClass
+section with the
+.B HotplugDriver
+option, the first one enumerated becomes the hotplug driver.
 A
 .B OutputClass
 Section may contain
diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c
index 8a6be97aa..90013573c 100644
--- a/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/hw/xfree86/os-support/linux/lnx_platform.c
@@ -125,7 +125,7 @@ xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs)
         xf86_remove_platform_device(index);
         return;
     }
-    ret = xf86platformAddDevice(index);
+    ret = xf86platformAddDevice(xf86PlatformFindHotplugDriver(index), index);
     if (ret == -1)
         xf86_remove_platform_device(index);
 }
@@ -173,6 +173,8 @@ void NewGPUDeviceRequest(struct OdevAttributes *attribs)
 {
     int old_num = xf86_num_platform_devices;
     int ret;
+    const char *driver_name;
+
     xf86PlatformDeviceProbe(attribs);
 
     if (old_num == xf86_num_platform_devices)
@@ -181,7 +183,11 @@ void NewGPUDeviceRequest(struct OdevAttributes *attribs)
     if (xf86_get_platform_device_unowned(xf86_num_platform_devices - 1) == TRUE)
         return;
 
-    ret = xf86platformAddDevice(xf86_num_platform_devices-1);
+    /* Scan and update PCI devices before adding new platform device */
+    xf86PlatformScanPciDev();
+    driver_name = xf86PlatformFindHotplugDriver(xf86_num_platform_devices - 1);
+
+    ret = xf86platformAddDevice(driver_name, xf86_num_platform_devices-1);
     if (ret == -1)
         xf86_remove_platform_device(xf86_num_platform_devices-1);
 


More information about the xorg-commit mailing list