Users of Intel discrete graphics adapters are confused with fake information on PCIe link bandwidth (speed and size) of their GPU devices reported by sysfs and userspace tools, including our lsgpu utility. In order for the lsgpu to show correct link bandwidth information, we need to identify an upstream port of a PCIe bridge that sits on the GPU card and get that information from that port.
Since the tool uses our udev based igt_device_scan library for identifying GPU devices and printing their properties and attributes, modifications that we need apply to that library. Refactor the library so a part of it can be reused for processing the bridge port. There are no functional changes introduced with this patch. Link: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10753 Signed-off-by: Janusz Krzysztofik <[email protected]> --- lib/igt_device_scan.c | 68 ++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c index 7753262a53..d3a2ebe8d2 100644 --- a/lib/igt_device_scan.c +++ b/lib/igt_device_scan.c @@ -910,32 +910,20 @@ static struct igt_device *igt_device_from_syspath(const char *syspath) } #define RETRIES_GET_PARENT 5 -/* For each drm igt_device add or update its parent igt_device to the array. - * As card/render drm devices mostly have same parent (vkms is an exception) - * link to it and update corresponding drm_card / drm_render fields. - */ -static void update_or_add_parent(struct udev *udev, - struct udev_device *dev, - struct igt_device *idev, - bool limit_attrs) + +static struct igt_device *find_or_add_igt_device(struct udev *udev, + struct udev_device *dev, + bool limit_attrs) { - struct udev_device *parent_dev; - struct igt_device *parent_idev; - const char *subsystem, *syspath, *devname; int retries = RETRIES_GET_PARENT; + const char *subsystem, *syspath; + struct igt_device *idev; - /* - * Get parent for drm node. It caches parent in udev device - * and will be destroyed along with the node. - */ - parent_dev = udev_device_get_parent(dev); - igt_assert(parent_dev); - - subsystem = udev_device_get_subsystem(parent_dev); - syspath = udev_device_get_syspath(parent_dev); + subsystem = udev_device_get_subsystem(dev); + syspath = udev_device_get_syspath(dev); - parent_idev = igt_device_find(subsystem, syspath); - while (!parent_idev && retries--) { + idev = igt_device_find(subsystem, syspath); + while (!idev && retries--) { /* * Don't care about previous parent_dev, it is tracked * by the child node. There's very rare race when driver module @@ -947,15 +935,41 @@ static void update_or_add_parent(struct udev *udev, * only udev_device_new*() will scan sys directory and * return fresh udev device. */ - parent_dev = udev_device_new_from_syspath(udev, syspath); - parent_idev = igt_device_new_from_udev(parent_dev, limit_attrs); - udev_device_unref(parent_dev); + dev = udev_device_new_from_syspath(udev, syspath); + idev = igt_device_new_from_udev(dev, limit_attrs); + udev_device_unref(dev); - if (parent_idev) - igt_list_add_tail(&parent_idev->link, &igt_devs.all); + if (idev) + igt_list_add_tail(&idev->link, &igt_devs.all); else usleep(100000); /* arbitrary, 100ms should be enough */ } + + return idev; +} + +/* + * For each drm igt_device add or update its parent igt_device to the array. + * As card/render drm devices mostly have same parent (vkms is an exception) + * link to it and update corresponding drm_card / drm_render fields. + */ +static void update_or_add_parent(struct udev *udev, + struct udev_device *dev, + struct igt_device *idev, + bool limit_attrs) +{ + struct udev_device *parent_dev; + struct igt_device *parent_idev; + const char *devname; + + /* + * Get parent for drm node. It caches parent in udev device + * and will be destroyed along with the node. + */ + parent_dev = udev_device_get_parent(dev); + igt_assert(parent_dev); + + parent_idev = find_or_add_igt_device(udev, parent_dev, limit_attrs); igt_assert(parent_idev); devname = udev_device_get_devnode(dev); -- 2.52.0
