diff options
author | Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> | 2019-10-24 14:05:14 +0300 |
---|---|---|
committer | Arkadiusz Hiler <arkadiusz.hiler@intel.com> | 2019-12-04 13:26:53 +0200 |
commit | 8616126e809bbd94df7581599e4ee030742c3781 (patch) | |
tree | 3062f264e09629da6611dce61cee53bb87dbdcb5 /tools/lsgpu.c | |
parent | 97fe403ac98b82d33280850b5ba18ee22686a678 (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.c | 250 |
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; +} |