summaryrefslogtreecommitdiff
path: root/tools/lsgpu.c
diff options
context:
space:
mode:
authorZbigniew Kempczyński <zbigniew.kempczynski@intel.com>2019-10-24 14:05:14 +0300
committerArkadiusz Hiler <arkadiusz.hiler@intel.com>2019-12-04 13:26:53 +0200
commit8616126e809bbd94df7581599e4ee030742c3781 (patch)
tree3062f264e09629da6611dce61cee53bb87dbdcb5 /tools/lsgpu.c
parent97fe403ac98b82d33280850b5ba18ee22686a678 (diff)
Introduce device selection lsgpu tool
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@intel.com> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com> Reviewed-by: Petri Latvala <petri.latvala@intel.com>
Diffstat (limited to 'tools/lsgpu.c')
-rw-r--r--tools/lsgpu.c250
1 files changed, 250 insertions, 0 deletions
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;
+}