[PATCH i-g-t v2] tools/lsgpu: Add switch to display gpu pci devices
Kamil Konieczny
kamil.konieczny at linux.intel.com
Fri Jun 14 15:16:28 UTC 2024
Hi Zbigniew,
On 2024-06-05 at 06:53:08 +0200, Zbigniew Kempczyński wrote:
> Device scanning in IGT is based on iterating over udev drm devices. This
> limits to display only to devices which have driver loaded.
>
> To remove this limitation add dedicated udev pci scanning in lsgpu which
> displays all gpu devices (pci class 0x30000).
This or class 0x38000. 0x30000 catches aspeed display card and others
but I do not see ATS-M cards, after loading Xe driver:
sudo build/tools/lsgpu
card0 Intel Ats_m (Gen12) drm:/dev/dri/card0
└─renderD128 drm:/dev/dri/renderD128
sudo build/tools/lsgpu -pn |grep -i class
ID_PCI_CLASS_FROM_DATABASE : Display controller
ID_PCI_SUBCLASS_FROM_DATABASE : Display controller
PCI_CLASS : 38000
class : 0x038000
>
> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
> Cc: Jani Nikula <jani.nikula at intel.com>
>
> ---
> v2: Remove unnecessary variable
> Add pci-id and use codename only when is pretty
> ---
> tools/lsgpu.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 87 insertions(+), 2 deletions(-)
>
> diff --git a/tools/lsgpu.c b/tools/lsgpu.c
> index da84e20505..23ea8ccdd7 100644
> --- a/tools/lsgpu.c
> +++ b/tools/lsgpu.c
> @@ -30,6 +30,7 @@
> #include <string.h>
> #include <signal.h>
> #include <glib.h>
> +#include <libudev.h>
>
> /**
> * SECTION:lsgpu
> @@ -77,12 +78,14 @@ enum {
> OPT_LIST_VENDORS = 'v',
> OPT_LIST_FILTERS = 'l',
> OPT_DEVICE = 'd',
> - OPT_HELP = 'h'
> + OPT_HELP = 'h',
> + OPT_PCISCAN = 'P',
> };
I do not see description of 'P' option after --help?
>
> static bool g_show_vendors;
> static bool g_list_filters;
> static bool g_help;
> +static bool g_pciscan;
> static char *igt_device;
>
> static const char *usage_str =
> @@ -158,6 +161,82 @@ static char *get_device_from_rc(void)
> return rc_device;
> }
>
> +static int pciscan(void)
> +{
> + struct udev *udev;
> + struct udev_enumerate *enumerate;
> + struct udev_list_entry *devices, *dev_list_entry;
> + struct igt_device_card card;
> + char pcistr[10];
> + int ret;
> +
> + udev = udev_new();
> + igt_assert(udev);
> +
> + enumerate = udev_enumerate_new(udev);
> + igt_assert(enumerate);
> +
> + printf("Scanning pci subsystem\n");
> + printf("----------------------\n");
> + ret = udev_enumerate_add_match_subsystem(enumerate, "pci");
> + igt_assert(!ret);
> +
> + ret = udev_enumerate_add_match_property(enumerate, "PCI_CLASS", "30000");
> + igt_assert(!ret);
I am not sure if assert is good here, why not gracefull return?
Print info and return.
> +
> + ret = udev_enumerate_scan_devices(enumerate);
> + igt_assert(!ret);
Same here.
> +
> + devices = udev_enumerate_get_list_entry(enumerate);
> + if (!devices) {
> + printf("No pci devices with class 0x30000 found\n");
Why not make class a param?
Regards,
Kamil
> + return 0;
> + }
> +
> + udev_list_entry_foreach(dev_list_entry, devices) {
> + const char *path;
> + struct udev_device *udev_dev;
> + struct udev_list_entry *entry;
> + char *codename;
> +
> + path = udev_list_entry_get_name(dev_list_entry);
> + udev_dev = udev_device_new_from_syspath(udev, path);
> + printf("[%s]\n", path);
> +
> + strcpy(card.pci_slot_name, "-");
> + entry = udev_device_get_properties_list_entry(udev_dev);
> + while (entry) {
> + const char *name = udev_list_entry_get_name(entry);
> + const char *value = udev_list_entry_get_value(entry);
> +
> + entry = udev_list_entry_get_next(entry);
> + if (!strcmp(name, "ID_VENDOR_FROM_DATABASE"))
> + printf(" vendor [db]: %s\n", value);
> + else if (!strcmp(name, "ID_MODEL_FROM_DATABASE"))
> + printf(" model [db]: %s\n", value);
> + else if (!strcmp(name, "DRIVER"))
> + printf(" driver : %s\n", value);
> + else if (!strcmp(name, "PCI_ID"))
> + igt_assert_eq(sscanf(value, "%hx:%hx",
> + &card.pci_vendor, &card.pci_device), 2);
> + }
> + snprintf(pcistr, sizeof(pcistr), "%04x:%04x",
> + card.pci_vendor, card.pci_device);
> + printf(" pci id : %s\n", pcistr);
> + codename = igt_device_get_pretty_name(&card, false);
> + if (strcmp(pcistr, codename))
> + printf(" codename : %s\n", codename);
> + free(codename);
> +
> + udev_device_unref(udev_dev);
> + }
> +
> + udev_enumerate_unref(enumerate);
> + udev_unref(udev);
> +
> + return 0;
> +}
> +
> int main(int argc, char *argv[])
> {
> static struct option long_options[] = {
> @@ -180,7 +259,7 @@ int main(int argc, char *argv[])
> .type = IGT_PRINT_USER,
> };
>
> - while ((c = getopt_long(argc, argv, "ncspvld:h",
> + while ((c = getopt_long(argc, argv, "ncspvld:hP",
> long_options, &index)) != -1) {
> switch(c) {
>
> @@ -208,6 +287,9 @@ int main(int argc, char *argv[])
> case OPT_HELP:
> g_help = true;
> break;
> + case OPT_PCISCAN:
> + g_pciscan = true;
> + break;
> case 0:
> fmt.option = IGT_PRINT_DRM;
> break;
> @@ -220,6 +302,9 @@ int main(int argc, char *argv[])
> }
> }
>
> + if (g_pciscan)
> + return pciscan();
> +
> if (g_help) {
> printf("%s\n", usage_str);
> exit(0);
> --
> 2.34.1
>
More information about the igt-dev
mailing list