[igt-dev] [PATCH i-g-t 2/3] Introduce device selection lsgpu tool

Arkadiusz Hiler arkadiusz.hiler at intel.com
Mon Dec 2 12:25:02 UTC 2019


From: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>

Tool uses device selection API to scan and display GPU devices.
It can be used to check filter correctness as well as order
of applying the filters (.igtrc, IGT_DEVICE and --device argument).

v2 (Arek):
 * don't print chip as it's no longer there
 * make it a second patch, before any alterations to igt_core or drmtest
 * use only a single filter

v3 (Arek):
 * use igt_load_igtrc() (Petri)
 * add usage example (Chris)
 * general logic cleanup

LONG EXAMPLE:

$ ./build/tools/lsgpu --help
  usage: lsgpu [options]

  Options:
    -p, --print-details         Print devices with details
    -v, --list-vendors          List recognized vendors
    -l, --list-filter-types     List registered device filters types
    -d, --device filter         Device filter, can be given multiple times
    -h, --help                  Show this help message and exit

$ ./build/tools/lsgpu
  sys:/sys/devices/pci0000:00/0000:00:02.0/drm/card0
      subsystem       : drm
      drm card        : /dev/dri/card0
      parent          : sys:/sys/devices/pci0000:00/0000:00:02.0

  sys:/sys/devices/pci0000:00/0000:00:02.0/drm/renderD128
      subsystem       : drm
      drm render      : /dev/dri/renderD128
      parent          : sys:/sys/devices/pci0000:00/0000:00:02.0

  sys:/sys/devices/platform/vgem/drm/card1
      subsystem       : drm
      drm card        : /dev/dri/card1
      parent          : sys:/sys/devices/platform/vgem

  sys:/sys/devices/platform/vgem/drm/renderD129
      subsystem       : drm
      drm render      : /dev/dri/renderD129
      parent          : sys:/sys/devices/platform/vgem

  sys:/sys/devices/pci0000:00/0000:00:02.0
      subsystem       : pci
      drm card        : /dev/dri/card0
      drm render      : /dev/dri/renderD128
      vendor          : 8086
      device          : 5927

  sys:/sys/devices/platform/vgem
      subsystem       : platform
      drm card        : /dev/dri/card1
      drm render      : /dev/dri/renderD129

$ ./build/tools/lsgpu -l
  Filter types:
  ---
  filter        syntax
  ---
  sys           sys:/sys/devices/pci0000:00/0000:00:02.0
                find device by its sysfs path

  drm           drm:/dev/dri/* path
                find drm device by /dev/dri/* node

  pci           pci:[vendor=%04x/name][,device=%04x][,card=%d]
                vendor is hex number or vendor name

$ ./build/tools/lsgpu -d pci:vendor=Intel
  Notice: Using --device filters
  === Device filter ===
  pci:vendor=Intel

  === Testing device open ===
  Device detail:
  subsystem   : pci
  drm card    : /dev/dri/card0
  drm render  : /dev/dri/renderD128
  Device /dev/dri/card0 successfully opened
  Device /dev/dri/renderD128 successfully opened
  -------------------------------------------

  $ ./build/tools/lsgpu -d pci:vendor=intel
  Notice: Using --device filters
  === Device filter ===
  pci:vendor=intel

  === Testing device open ===
  Device detail:
  subsystem   : pci
  drm card    : /dev/dri/card0
  drm render  : /dev/dri/renderD128
  Device /dev/dri/card0 successfully opened
  Device /dev/dri/renderD128 successfully opened
  -------------------------------------------

$ ./build/tools/lsgpu -d pci:vendor=intel -p
  Notice: Using --device filters
  === Device filter ===
  pci:vendor=intel

  === Testing device open ===
  Device detail:
  subsystem   : pci
  drm card    : /dev/dri/card0
  drm render  : /dev/dri/renderD128
  Device /dev/dri/card0 successfully opened
  Device /dev/dri/renderD128 successfully opened

  ========== pci:/sys/devices/pci0000:00/0000:00:02.0 ==========
  card device                     : /dev/dri/card0
  render device                   : /dev/dri/renderD128

  [properties]
  DEVPATH                         : /devices/pci0000:00/0000:00:02.0
  DRIVER                          : i915
  FWUPD_GUID                      : 0x8086:0x5927
  ID_MODEL_FROM_DATABASE          : Iris Plus Graphics 650
  ID_PCI_CLASS_FROM_DATABASE      : Display controller
  ID_PCI_INTERFACE_FROM_DATABASE  : VGA controller
  ID_PCI_SUBCLASS_FROM_DATABASE   : VGA compatible controller
  ID_VENDOR_FROM_DATABASE         : Intel Corporation
  MODALIAS                        : pci:v00008086d00005927sv00008086sd00002068bc03sc00i00
  PCI_CLASS                       : 30000
  PCI_ID                          : 8086:5927
  PCI_SLOT_NAME                   : 0000:00:02.0
  PCI_SUBSYS_ID                   : 8086:2068
  SUBSYSTEM                       : pci
  USEC_INITIALIZED                : 22881171

  [attributes]
  ari_enabled                     : 0
  boot_vga                        : 1
  broken_parity_status            : 0
  class                           : 0x030000
  consistent_dma_mask_bits        : 39
  current_link_speed              : Unknown speed
  current_link_width              : 0
  d3cold_allowed                  : 1
  device                          : 0x5927
  dma_mask_bits                   : 39
  driver_override                 : (null)
  enable                          : 1
  firmware_node                   : LNXVIDEO:00
  index                           : 1
  irq                             : 129
  label                           :  CPU
  local_cpulist                   : 0-3
  local_cpus                      : f
  max_link_speed                  : Unknown speed
  max_link_width                  : 255
  msi_bus                         : 1
  numa_node                       : -1
  revision                        : 0x06
  subsystem                       : pci
  subsystem_device                : 0x2068
  subsystem_vendor                : 0x8086
  vendor                          : 0x8086

  -------------------------------------------

Cc: Petri Latvala <petri.latvala at intel.com>
Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler at intel.com>
Reviewed-by: Petri Latvala <petri.latvala at intel.com>
---
 tools/Makefile.sources |   1 +
 tools/lsgpu.c          | 250 +++++++++++++++++++++++++++++++++++++++++
 tools/meson.build      |   1 +
 3 files changed, 252 insertions(+)
 create mode 100644 tools/lsgpu.c

diff --git a/tools/Makefile.sources b/tools/Makefile.sources
index d764895d..b7a43d47 100644
--- a/tools/Makefile.sources
+++ b/tools/Makefile.sources
@@ -33,6 +33,7 @@ tools_prog_lists =		\
 	intel_watermark		\
 	intel_gem_info		\
 	intel_gvtg_test     \
+	lsgpu			\
 	$(NULL)
 
 dist_bin_SCRIPTS = intel_gpu_abrt
diff --git a/tools/lsgpu.c b/tools/lsgpu.c
new file mode 100644
index 00000000..2541d1c2
--- /dev/null
+++ b/tools/lsgpu.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "igt_device_scan.h"
+#include "igt.h"
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <glib.h>
+
+/**
+ * SECTION:lsgpu
+ * @short_description: lsgpu
+ * @title: lsgpu
+ * @include: lsgpu.c
+ *
+ * # lsgpu
+ *
+ * The devices can be scanned and displayed using 'lsgpu' tool. Tool also
+ * displays properties and sysattrs (-p switch, means print detail) which
+ * can be used during filter implementation.
+ *
+ * Tool can also be used to try out filters.
+ * To select device use '-d' or '--device' argument like:
+ *
+ * |[<!-- language="plain" -->
+ * ./lsgpu -d 'pci:vendor=Intel'
+ * === Device filter list ===
+ * [ 0]: pci:vendor=Intel
+
+ * === Testing device open ===
+ * subsystem   : pci
+ * drm card    : /dev/dri/card0
+ * drm render  : /dev/dri/renderD128
+ * Device /dev/dri/card0 successfully opened
+ * Device /dev/dri/renderD128 successfully opened
+ * ]|
+ *
+ * NOTE: When using filters only the first matching device is printed.
+ *
+ * Additionally lsgpu tries to open the card and render nodes to verify
+ * permissions. It also uses IGT variable search order:
+ * - use --device first (it overrides IGT_DEVICE and .igtrc Common::Device
+ *   settings)
+ * - use IGT_DEVICE enviroment variable if no --device are passed
+ * - use .igtrc Common::Device if no --device nor IGT_DEVICE are passed
+ */
+
+enum {
+	OPT_PRINT_DETAIL   = 'p',
+	OPT_LIST_VENDORS   = 'v',
+	OPT_LIST_FILTERS   = 'l',
+	OPT_DEVICE         = 'd',
+	OPT_HELP           = 'h'
+};
+
+static bool g_show_vendors;
+static bool g_list_filters;
+static bool g_help;
+static char *igt_device;
+
+static const char *usage_str =
+	"usage: lsgpu [options]\n\n"
+	"Options:\n"
+	"  -p, --print-details         Print devices with details\n"
+	"  -v, --list-vendors          List recognized vendors\n"
+	"  -l, --list-filter-types     List registered device filters types\n"
+	"  -d, --device filter         Device filter, can be given multiple times\n"
+	"  -h, --help                  Show this help message and exit\n";
+
+static void test_device_open(struct igt_device_card *card)
+{
+	int fd;
+
+	if (!card)
+		return;
+
+	fd = igt_open_card(card);
+	if (fd >= 0) {
+		printf("Device %s successfully opened\n", card->card);
+		close(fd);
+	} else {
+		if (strlen(card->card))
+			printf("Cannot open card %s device\n", card->card);
+		else
+			printf("Cannot open card device, empty name\n");
+	}
+
+	fd = igt_open_render(card);
+	if (fd >= 0) {
+		printf("Device %s successfully opened\n", card->render);
+		close(fd);
+	} else {
+		if (strlen(card->render))
+			printf("Cannot open render %s device\n", card->render);
+		else
+			printf("Cannot open render device, empty name\n");
+	}
+}
+
+static void print_card(struct igt_device_card *card)
+{
+	if (!card)
+		return;
+
+	printf("subsystem   : %s\n", card->subsystem);
+	printf("drm card    : %s\n", card->card);
+	printf("drm render  : %s\n", card->render);
+}
+
+static char *get_device_from_rc(void)
+{
+	char *rc_device = NULL;
+	GError *error = NULL;
+	GKeyFile *key_file = igt_load_igtrc();
+
+	if (key_file == NULL)
+		return NULL;
+
+	rc_device = g_key_file_get_string(key_file, "Common",
+					  "Device", &error);
+
+	g_clear_error(&error);
+
+	return rc_device;
+}
+
+int main(int argc, char *argv[])
+{
+	static struct option long_options[] = {
+		{"print-detail",      no_argument,       NULL, OPT_PRINT_DETAIL},
+		{"list-vendors",      no_argument,       NULL, OPT_LIST_VENDORS},
+		{"list-filter-types", no_argument,       NULL, OPT_LIST_FILTERS},
+		{"device",            required_argument, NULL, OPT_DEVICE},
+		{"help",              no_argument,       NULL, OPT_HELP},
+		{0, 0, 0, 0}
+	};
+	int c, index = 0;
+	char *env_device = NULL, *opt_device = NULL, *rc_device = NULL;
+	enum igt_devices_print_type printtype = IGT_PRINT_SIMPLE;
+
+	while ((c = getopt_long(argc, argv, "pvld:h",
+				long_options, &index)) != -1) {
+		switch(c) {
+
+		case OPT_PRINT_DETAIL:
+			printtype = IGT_PRINT_DETAIL;
+			break;
+		case OPT_LIST_VENDORS:
+			g_show_vendors = true;
+			break;
+		case OPT_LIST_FILTERS:
+			g_list_filters = true;
+			break;
+		case OPT_DEVICE:
+			opt_device = strdup(optarg);
+			break;
+		case OPT_HELP:
+			g_help = true;
+			break;
+		}
+	}
+
+	if (g_help) {
+		printf("%s\n", usage_str);
+		exit(0);
+	}
+
+	if (g_show_vendors) {
+		igt_devices_print_vendors();
+		return 0;
+	}
+
+	if (g_list_filters) {
+		igt_device_print_filter_types();
+		return 0;
+	}
+
+	env_device = getenv("IGT_DEVICE");
+	rc_device = get_device_from_rc();
+
+	if (opt_device != NULL) {
+		igt_device = opt_device;
+		printf("Notice: Using filter supplied via --device\n");
+	}
+	else if (env_device != NULL) {
+		igt_device = env_device;
+		printf("Notice: Using filter from IGT_DEVICE env variable\n");
+	}
+	else if (rc_device != NULL) {
+		igt_device = rc_device;
+		printf("Notice: Using filter from .igtrc\n");
+	}
+
+	igt_devices_scan(false);
+
+	if (igt_device != NULL) {
+		struct igt_device_card card;
+
+		printf("=== Device filter ===\n");
+		printf("%s\n\n", igt_device);
+
+		printf("=== Testing device open ===\n");
+
+		if (!igt_device_card_match(igt_device, &card)) {
+			printf("No device found for the filter\n\n");
+			return -1;
+		}
+
+		printf("Device detail:\n");
+		print_card(&card);
+		test_device_open(&card);
+		if (printtype == IGT_PRINT_DETAIL) {
+			printf("\n");
+			igt_devices_print(printtype);
+		}
+		printf("-------------------------------------------\n");
+
+	} else {
+		igt_devices_print(printtype);
+	}
+
+	free(rc_device);
+	free(opt_device);
+
+	return 0;
+}
diff --git a/tools/meson.build b/tools/meson.build
index eecb122b..74822a33 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -36,6 +36,7 @@ tools_progs = [
 	'intel_gem_info',
 	'intel_gvtg_test',
 	'dpcd_reg',
+	'lsgpu',
 ]
 tool_deps = igt_deps
 
-- 
2.23.0



More information about the igt-dev mailing list