* [igt-dev] [PATCH i-g-t v2 0/1] Add device selection methods
@ 2019-07-19 9:50 Zbigniew Kempczyński
2019-07-19 9:50 ` [igt-dev] [PATCH i-g-t v2 1/1] Introduce new method of device selection Zbigniew Kempczyński
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Zbigniew Kempczyński @ 2019-07-19 9:50 UTC (permalink / raw)
To: igt-dev
v2: In this series I've removed module management and hand device classes
filtering (udev filters are now used in this case). Lsgpu was
simplified (some options were unreadable and they were removed).
Still migration to gtkdoc is necessary which will be made in v3.
Zbigniew Kempczyński (1):
Introduce new method of device selection
docs/multi-device-selection.txt | 108 +++
lib/Makefile.sources | 2 +
lib/drmtest.c | 151 ++++-
lib/drmtest.h | 9 +
lib/igt_core.c | 13 +
lib/igt_device_scan.c | 1084 +++++++++++++++++++++++++++++++
lib/igt_device_scan.h | 82 +++
lib/meson.build | 1 +
tools/Makefile.sources | 1 +
tools/lsgpu.c | 221 +++++++
tools/meson.build | 1 +
11 files changed, 1671 insertions(+), 2 deletions(-)
create mode 100644 docs/multi-device-selection.txt
create mode 100644 lib/igt_device_scan.c
create mode 100644 lib/igt_device_scan.h
create mode 100644 tools/lsgpu.c
--
2.21.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 4+ messages in thread
* [igt-dev] [PATCH i-g-t v2 1/1] Introduce new method of device selection
2019-07-19 9:50 [igt-dev] [PATCH i-g-t v2 0/1] Add device selection methods Zbigniew Kempczyński
@ 2019-07-19 9:50 ` Zbigniew Kempczyński
2019-07-19 11:05 ` [igt-dev] ✓ Fi.CI.BAT: success for Add device selection methods (rev2) Patchwork
2019-07-19 12:09 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2 siblings, 0 replies; 4+ messages in thread
From: Zbigniew Kempczyński @ 2019-07-19 9:50 UTC (permalink / raw)
To: igt-dev; +Cc: Daniel Vetter, Petri Latvala
Change adds device selection based on implemented filters.
Different filters can be added to address different device
selection possibilities.
New device selection uses --device filter or IGT_DEVICE environent
variable. Selection of many devices can be done by using --device
argument multiple times. As IGT_DEVICE enviroment can be set
once ';' is recognized as filter separator.
Tool 'lsgpu' which uses device scanning feature was added.
---
v2: removing module management, keeping only simple device pci/
platform scanning
Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Petri Latvala <petri.latvala@intel.com>
---
docs/multi-device-selection.txt | 108 +++
lib/Makefile.sources | 2 +
lib/drmtest.c | 151 ++++-
lib/drmtest.h | 9 +
lib/igt_core.c | 13 +
lib/igt_device_scan.c | 1084 +++++++++++++++++++++++++++++++
lib/igt_device_scan.h | 82 +++
lib/meson.build | 1 +
tools/Makefile.sources | 1 +
tools/lsgpu.c | 221 +++++++
tools/meson.build | 1 +
11 files changed, 1671 insertions(+), 2 deletions(-)
create mode 100644 docs/multi-device-selection.txt
create mode 100644 lib/igt_device_scan.c
create mode 100644 lib/igt_device_scan.h
create mode 100644 tools/lsgpu.c
diff --git a/docs/multi-device-selection.txt b/docs/multi-device-selection.txt
new file mode 100644
index 00000000..1e8bc7b9
--- /dev/null
+++ b/docs/multi-device-selection.txt
@@ -0,0 +1,108 @@
+Multi-device scanning and selection
+-----------------------------------
+
+1. Scanning
+
+Device selection is build around scanning buses using udev (PCI and platform),
+gathering information about matching devices and using filters on discovered
+data.
+
+PCI scanning is easy and gives all information regarding devices (module doesn't
+need to be loaded). Problems occurs when platform devices are taken into
+account. Some of them have appropriate entries in device tree (like
+Raspberry Pi vc4 driver), so displaying them without loaded module is possible.
+Such devices expose OF_COMPATIBLE_X properties which are matched against
+appropriate driver. Some devices are registered inside platform tree at driver
+loading time so discovering such devices is not possible unless driver is loaded.
+
+
+2. Filtering
+
+After scanning all gathered information are stored in devices array. Filtering
+means creating a view that matches filter on devices array. Filters defined
+on non-discoverable devices loads module (if not already loaded) and execute
+device discovery again.
+
+Using 'lsgpu' tool we can get list of defined filter types ('-l' switch):
+...
+pci pci:[vendor=%04x/name][,device=%04x][,card=%d]
+ vendor is hex number or name
+...
+
+pci is filter name, it calls filter on devices array to select only PCI
+devices. For example:
+
+pci:vendor=8086
+find first pci card on the bus with 8086 PCI device ID
+
+pci:vendor=intel
+same as above but uses vendor name (see lsgpu -v)
+
+pci:vendor=8086,card=0
+same as above, card=0 is default
+
+pci:vendor=intel,device=1234,card=1
+finds second Intel card which device ID is 0x1234
+
+
+3. lsgpu
+
+To play with devices 'lsgpu' tool was written. It is mostly wrapper to igt
+devices scan code (igt_device_scan.c).
+
+If run without arguments it displays all recognized cards.
+Usage examples:
+
+# lsgpu -d
+displays devices in 'detail' mode, with all properties and attributes. Some
+attributes are skipped because acquiring value can take even seconds (there's
+special blacklist hash table inside the code)
+
+# lsgpu -v
+displays recognized vendors
+
+# lsgpu -l
+displays defined filter types
+
+# lsgpu --device 'pci:card=0;vgem:card=0;vkms:card=0'
+and
+# lsgpu --device 'pci:card=0' --device 'vgem:card=0' --device 'vkms:card=0'
+and
+# export IGT_DEVICE='pci:card=0;vgem:card=0;vkms:card=0'
+# lsgpu
+matches multiple cards. IGT_DEVICE uses ';' separated filter syntax, it is also
+permitted in --device (function splits argument against ';').
+
+
+4. Compatibility with current device open API
+
+Practically all IGT tests use:
+int __drm_open_driver(int chipset);
+int __drm_open_driver_render(int chipset);
+
+Above functions were extended to use --device / env IGT_DEVICE filters
+(if given during IGT test run). If more than single device were passed
+first matching filter against chipset is selected. This allows test like
+prime_vgem to work, ex:
+
+# ./prime_vgem --r basic-read --device 'pci:card=0' --device 'vgem:card=0'
+# ./prime_vgem --r basic-read --device 'vgem:card=0' --device 'pci:card=0'
+
+
+5. New device selection API
+
+Following prototypes define new API:
+
+/* Multi device API */
+int __drm_open_card_with_nth_filter(int num, int chipset);
+int __drm_open_render_with_nth_filter(int num, int chipset);
+
+When test require DRIVER_INTEL it has to be sure that user didn't passed
+another device (vc4 for example). So if user passed --device vc4:card=0
+this open will fail.
+
+struct igt_device_card;
+int __drm_open_card(struct igt_device_card *card);
+int __drm_open_render(struct igt_device_card *card);
+
+These functions allows to open device regardless chip requirement.
diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index e16de86e..c383a817 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -25,6 +25,8 @@ lib_source_list = \
igt_debugfs.h \
igt_device.c \
igt_device.h \
+ igt_device_scan.c \
+ igt_device_scan.h \
igt_aux.c \
igt_aux.h \
igt_color_encoding.c \
diff --git a/lib/drmtest.c b/lib/drmtest.c
index c379a7b7..434066ee 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -55,6 +55,7 @@
#include "igt_gt.h"
#include "igt_kmod.h"
#include "igt_sysfs.h"
+#include "igt_device_scan.h"
#include "version.h"
#include "config.h"
#include "intel_reg.h"
@@ -289,25 +290,171 @@ static int __open_driver(const char *base, int offset, unsigned int chipset)
return __search_and_open(base, offset, chipset);
}
+static int __open_driver_exact(const char *name, unsigned int chipset)
+{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ int fd;
+
+ fd = open_device(name, chipset);
+ if (fd != -1)
+ return fd;
+
+ pthread_mutex_lock(&mutex);
+ for (const struct module *m = modules; m->module; m++) {
+ if (chipset & m->bit) {
+ if (m->modprobe)
+ m->modprobe(m->module);
+ else
+ modprobe(m->module);
+ }
+ }
+ pthread_mutex_unlock(&mutex);
+
+ return open_device(name, chipset);
+}
+
+/**
+ * __find_card_with_chipset
+ * @chipset: chipset for compare with card match
+ * @card: pointer where card information will be stored
+ *
+ * For compatibility mode when multiple --device argument were passed
+ * this function tries to be smart enough to handle tests which opens
+ * more than single device. It iterates over filter list and
+ * compares chipset to card chipset for filter matched.
+ *
+ * Returns:
+ * True if card according to filters added and chipset was found,
+ * false othwerwise.
+ */
+static bool __find_card_with_chipset(int chipset, struct igt_device_card *card)
+{
+ int i, n = igt_device_filter_count();
+ const char *filter;
+ bool match;
+
+ for (i = 0; i < n; i++) {
+ filter = igt_device_filter_get(i);
+ match = igt_device_card_match(filter, card);
+ if (match && (card->chipset == chipset || chipset == DRIVER_ANY))
+ return true;
+ }
+
+ return false;
+}
+
/**
* __drm_open_driver:
* @chipset: OR'd flags for each chipset to search, eg. #DRIVER_INTEL
*
- * Open the first DRM device we can find, searching up to 16 device nodes
+ * Function opens device with following order:
+ * 1. when --device arguments are present device scanning will be executed,
+ * then matching considers all device which matches filter argument will be selected.
+ * 2. compatibility mode - open the first DRM device we can find,
+ * searching up to 16 device nodes.
*
* Returns:
* An open DRM fd or -1 on error
*/
int __drm_open_driver(int chipset)
{
+ int n = igt_device_filter_count();
+
+ if (n) {
+ bool found;
+ struct igt_device_card card;
+
+ found = __find_card_with_chipset(chipset, &card);
+ if (!found || !strlen(card.card))
+ return -1;
+
+ return __open_driver_exact(card.card, chipset);
+ }
+
return __open_driver("/dev/dri/card", 0, chipset);
}
-static int __drm_open_driver_render(int chipset)
+int __drm_open_driver_render(int chipset)
{
+ int n = igt_device_filter_count();
+
+ if (n) {
+ bool found;
+ struct igt_device_card card;
+
+ found = __find_card_with_chipset(chipset, &card);
+ if (!found || !strlen(card.render))
+ return -1;
+
+ return __open_driver_exact(card.render, chipset);
+ }
+
return __open_driver("/dev/dri/renderD", 128, chipset);
}
+static int __drm_open_with_nth_filter(int num, int chipset, bool open_render)
+{
+ struct igt_device_card card;
+ const char *filter, *devname;
+ bool match;
+ int n = igt_device_filter_count();
+
+ if (!n || num < 0 || num >= n) {
+ igt_warn("No device filter num == %d passed\n", num);
+ return -1;
+ }
+
+ filter = igt_device_filter_get(num);
+ match = igt_device_card_match(filter, &card);
+ if (!match) {
+ igt_warn("No device match filter: %s\n", filter);
+ return -1;
+ }
+
+ if (chipset != card.chipset) {
+ igt_warn("Filtered device doesn't match chipset (%d != %d)\n",
+ chipset, card.chipset);
+ return -1;
+ }
+ if (!strlen(card.card))
+ return -1;
+
+ devname = open_render ? card.render : card.card;
+ if (!strlen(devname)) {
+ igt_warn("No %s node matching filter: %s\n",
+ open_render ? "render" : "card", filter);
+ return -1;
+ }
+ return __open_driver_exact(devname, card.chipset);
+}
+
+int __drm_open_card_with_nth_filter(int num, int chipset)
+{
+ return __drm_open_with_nth_filter(num, chipset, false);
+}
+
+int __drm_open_render_with_nth_filter(int num, int chipset)
+{
+ return __drm_open_with_nth_filter(num, chipset, true);
+}
+
+int __drm_open_card(struct igt_device_card *card)
+{
+ if (!card || !strlen(card->card))
+ return -1;
+
+ return __open_driver_exact(card->card, card->chipset);
+}
+
+int __drm_open_render(struct igt_device_card *card)
+{
+ if (!card || !strlen(card->render))
+ return -1;
+
+ return __open_driver_exact(card->render, card->chipset);
+}
+
+
static int at_exit_drm_fd = -1;
static int at_exit_drm_render_fd = -1;
diff --git a/lib/drmtest.h b/lib/drmtest.h
index 614f57e6..4adb9908 100644
--- a/lib/drmtest.h
+++ b/lib/drmtest.h
@@ -50,6 +50,7 @@
#define DRIVER_AMDGPU (1 << 3)
#define DRIVER_V3D (1 << 4)
#define DRIVER_PANFROST (1 << 5)
+
/*
* Exclude DRVER_VGEM from DRIVER_ANY since if you run on a system
* with vgem as well as a supported driver, you can end up with a
@@ -81,6 +82,14 @@ int drm_open_driver(int chipset);
int drm_open_driver_master(int chipset);
int drm_open_driver_render(int chipset);
int __drm_open_driver(int chipset);
+int __drm_open_driver_render(int chipset);
+
+/* Multi device API */
+int __drm_open_card_with_nth_filter(int num, int chipset);
+int __drm_open_render_with_nth_filter(int num, int chipset);
+struct igt_device_card;
+int __drm_open_card(struct igt_device_card *card);
+int __drm_open_render(struct igt_device_card *card);
void gem_quiescent_gpu(int fd);
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 1cbb09f9..9b851175 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -71,6 +71,7 @@
#include "igt_sysrq.h"
#include "igt_rc.h"
#include "igt_list.h"
+#include "igt_device_scan.h"
#define UNW_LOCAL_ONLY
#include <libunwind.h>
@@ -304,6 +305,7 @@ enum {
OPT_DEBUG,
OPT_INTERACTIVE_DEBUG,
OPT_SKIP_CRC,
+ OPT_DEVICE,
OPT_HELP = 'h'
};
@@ -624,6 +626,7 @@ static void print_usage(const char *help_str, bool output_on_stderr)
" --skip-crc-compare\n"
" --help-description\n"
" --describe\n"
+ " --device filter\n"
" --help|-h\n");
if (help_str)
fprintf(f, "%s\n", help_str);
@@ -725,6 +728,11 @@ static void common_init_env(void)
if (env) {
__set_forced_driver(env);
}
+
+ env = getenv("IGT_DEVICE");
+ if (env) {
+ igt_device_filter_add(env);
+ }
}
static int common_init(int *argc, char **argv,
@@ -743,6 +751,7 @@ static int common_init(int *argc, char **argv,
{"debug", optional_argument, NULL, OPT_DEBUG},
{"interactive-debug", optional_argument, NULL, OPT_INTERACTIVE_DEBUG},
{"skip-crc-compare", no_argument, NULL, OPT_SKIP_CRC},
+ {"device", required_argument, NULL, OPT_DEVICE},
{"help", no_argument, NULL, OPT_HELP},
{0, 0, 0, 0}
};
@@ -865,6 +874,10 @@ static int common_init(int *argc, char **argv,
case OPT_SKIP_CRC:
igt_skip_crc_compare = true;
goto out;
+ case OPT_DEVICE:
+ assert(optarg);
+ igt_device_filter_add(optarg);
+ break;
case OPT_HELP:
print_usage(help_str, false);
ret = -1;
diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
new file mode 100644
index 00000000..5e31469a
--- /dev/null
+++ b/lib/igt_device_scan.c
@@ -0,0 +1,1084 @@
+/*
+ * 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.h"
+#include "igt_sysfs.h"
+#include "igt_device.h"
+#include "igt_device_scan.h"
+#include <glib.h>
+#include <libudev.h>
+#include <linux/limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+/**
+ * SECTION:igt_device_scan
+ * @short_description: PCI and platform devices scan
+ * @title: Device scan
+ * @include: igt.h
+ *
+ * Device discovery uses udev functionality for scanning different subsystems.
+ * This code uses scanning 'pci' and 'platform' subsystems instead of direct
+ * iterating over 'drm' subsystem.
+*/
+
+//#define DEBUG_DEVICE_SCAN
+#ifdef DEBUG_DEVICE_SCAN
+#define DBG(...) \
+{ \
+ struct timeval tm; \
+ gettimeofday(&tm, NULL); \
+ printf("%10ld.%03ld: ", tm.tv_sec, tm.tv_usec); \
+ printf(__VA_ARGS__); \
+ }
+
+#else
+#define DBG(...) {}
+#endif
+
+#define IGT_DRM_PATH "/dev/dri"
+
+/* There're two possibilities to get drm devices.
+ * First is to scan 'drm' subsystem directly. It's easy but no additional
+ * metadata is easy to get (like vendor etc.).
+ * Second is to scan 'pci' and 'platform' subsystem with apropriate filters
+ * for devices we're interested of. For PCI devices it is PCI_CLASS attribute,
+ * for platform devices this is a little bit chaotic and depends on device
+ * vendor.
+*/
+
+enum igt_devices_scan_type {
+ IGT_SCAN_PCI = 1,
+ IGT_SCAN_PLATFORM = 2,
+};
+
+static GHashTable *sysattrs_blacklist_ht; //sysattrs we don't want to read
+static GHashTable *gpu_vendor_ht; //search id -> vendor_spec mapping
+static GHashTable *filter_definition_ht; //supported filters (pci=..., etc.)
+
+/* Generic name->value struct */
+struct name_value {
+ const char *name;
+ gpointer *value;
+};
+
+/* Vendor specific data */
+struct vendor_spec {
+ enum igt_device_type dev_type;
+ const char *vendor;
+ const char *match;
+ int chipset;
+};
+
+/* Single igt_device found in PCI / platform subsystems */
+struct igt_device {
+ char *pretty_name;
+ struct vendor_spec *vs;
+ GHashTable *props_ht;
+ GHashTable *attrs_ht;
+ char *syspath;
+ char *drvpath;
+ char *drm_card_path;
+ char *drm_render_path;
+ char *vendor;
+ char *device;
+ enum igt_device_type dev_type;
+};
+
+/* Scanned devices struct */
+struct igt_devices {
+ GPtrArray *devs; //all gpu devices array
+ GPtrArray *view; //filtered view
+ bool devs_scanned;
+};
+
+/* Scanned devices holder */
+static struct igt_devices igt_devs;
+
+/* List of attribute key->value applied as udev filter
+ * for enumeration for PCI devices */
+struct name_value pci_udev_filters_attr_list[] = {
+ { "PCI_CLASS", (gpointer) "30000" },
+ { "PCI_CLASS", (gpointer) "30100" },
+ { "PCI_CLASS", (gpointer) "30200" },
+ { "PCI_CLASS", (gpointer) "38000" },
+ { NULL, },
+};
+
+/* List of attribute key->value applied as udev filter
+ * for enumeration for platform devices */
+struct name_value platform_udev_filters_attr_list[] = {
+ { "MODALIAS", (gpointer) "platform:vgem" },
+ { "MODALIAS", (gpointer) "platform:vkms" },
+ { NULL, },
+};
+
+static struct vendor_spec v_intel = { .dev_type = DEV_PCI,
+ .vendor = "Intel",
+ .chipset = DRIVER_INTEL
+ };
+static struct vendor_spec v_amd = { .dev_type = DEV_PCI,
+ .vendor = "AMD",
+ .chipset = DRIVER_AMDGPU
+ };
+static struct vendor_spec v_vgem = { .dev_type = DEV_PLATFORM,
+ .vendor = "Virtual-GEM",
+ .chipset = DRIVER_VGEM
+ };
+static struct vendor_spec v_vc4 = { .dev_type = DEV_PLATFORM,
+ .vendor = "Broadcom",
+ .chipset = DRIVER_VC4
+ };
+
+/* Mapping vendor id => vendor_spec should be unique (vendor string matching
+ * is written around this).
+ *
+ * Keys must be defined as follows:
+ * PCI devices: PCI_SLOT_ID -> vendor_spec.
+*/
+struct name_value gpu_vendor_list[] = {
+ { "8086", (gpointer) &v_intel },
+ { "1002", (gpointer) &v_amd },
+ { NULL, },
+};
+
+/* Generic hash table fill function, requires name / value ptrs array */
+static void fill_ht(GHashTable **ht, struct name_value *data)
+{
+ if (*ht)
+ return;
+
+ *ht = g_hash_table_new(g_str_hash, g_str_equal);
+ igt_assert(*ht);
+
+ while (data->name) {
+ g_hash_table_insert(*ht,
+ (gpointer) data->name,
+ data->value);
+ data++;
+ }
+}
+
+#define get_vendor_spec(prop) \
+ g_hash_table_lookup(gpu_vendor_ht, prop)
+
+/* Go through whole vendor hash table and compare against vendor field.
+ * Used mostly with vendor=... filter parameter when PCI id is not matched.
+*/
+static bool is_pci_vendor_name(const char *name)
+{
+ bool ret = false;
+ GList *keys = g_hash_table_get_keys(gpu_vendor_ht);
+
+ if (!name)
+ return false;
+
+ while (keys) {
+ char *k = (char *) keys->data;
+ struct vendor_spec *vs = g_hash_table_lookup(gpu_vendor_ht, k);
+ keys = g_list_next(keys);
+
+ if (vs->dev_type != DEV_PCI)
+ continue;
+
+ if (!strcasecmp(name, vs->vendor)) {
+ ret = true;
+ break;
+ }
+ }
+ g_list_free(keys);
+
+ return ret;
+}
+
+/* Reading sysattr values can take time (even seconds),
+ * we want to avoid reading such keys.
+*/
+static void populate_blacklist_keys(void)
+{
+ const char *keys[] = { "config", "modalias",
+ "resource",
+ "resource0", "resource1", "resource2",
+ "resource3", "resource4", "resource5",
+ "resource0_wc", "resource1_wc", "resource2_wc",
+ "resource3_wc", "resource4_wc", "resource5_wc",
+ "driver",
+ "uevent", NULL};
+ const char *key;
+ int i = 0;
+
+ if (sysattrs_blacklist_ht)
+ return;
+
+ sysattrs_blacklist_ht = g_hash_table_new(g_str_hash, g_str_equal);
+ igt_assert(sysattrs_blacklist_ht);
+
+ while ((key = keys[i++]))
+ g_hash_table_add(sysattrs_blacklist_ht, (gpointer) key);
+}
+
+#define is_on_blacklist(key) \
+ g_hash_table_contains(sysattrs_blacklist_ht, key)
+
+static struct igt_device *igt_device_new(void)
+{
+ struct igt_device *dev;
+ dev = calloc(1, sizeof(struct igt_device));
+ if (!dev)
+ return NULL;
+
+ dev->attrs_ht = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, free);
+ dev->props_ht = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, free);
+
+ if (dev->attrs_ht && dev->props_ht)
+ return dev;
+
+ return NULL;
+}
+
+static void igt_device_add_prop(struct igt_device *dev,
+ const char *key, const char *value)
+{
+ if (!key || !value)
+ return;
+
+ g_hash_table_insert(dev->props_ht, strdup(key), strdup(value));
+}
+
+static void igt_device_add_attr(struct igt_device *dev,
+ const char *key, const char *value)
+{
+ const char *v = value;
+
+ if (!key)
+ return;
+
+ /* It's possible we have symlink at key filename, but udev
+ * library resolves only few of them */
+ if (!v) {
+ struct stat st;
+ char path[PATH_MAX];
+ char linkto[PATH_MAX];
+ int len;
+
+ snprintf(path, sizeof(path), "%s/%s", dev->syspath, key);
+ if (lstat(path, &st) != 0)
+ return;
+
+ len = readlink(path, linkto, sizeof(linkto));
+ if (len <= 0 || len == (ssize_t) sizeof(linkto))
+ return;
+ linkto[len] = '\0';
+ v = strrchr(linkto, '/');
+ if (v == NULL)
+ return;
+ v++;
+ }
+
+ g_hash_table_insert(dev->attrs_ht, strdup(key), strdup(v));
+}
+
+/* Iterate over udev properties list and rewrite it to igt_device properties
+ * hash table for instant access.
+ */
+static void get_props(struct udev_device *dev, struct igt_device *idev)
+{
+ struct udev_list_entry *entry;
+
+ entry = udev_device_get_properties_list_entry(dev);
+ while (entry) {
+ const char *name = udev_list_entry_get_name(entry);
+ const char *value = udev_list_entry_get_value(entry);
+ igt_device_add_prop(idev, name, value);
+ entry = udev_list_entry_get_next(entry);
+ DBG("prop: %s, val: %s\n", name, value);
+ }
+}
+
+/* Same as get_props(), but rewrites sysattrs. Resolved symbolic links
+ * not handled by udev get_sysattr_value().
+ * Function skips sysattrs from blacklist ht (acquiring some values can take
+ * seconds).
+ */
+static void get_attrs(struct udev_device *dev, struct igt_device *idev)
+{
+ struct udev_list_entry *entry;
+
+ entry = udev_device_get_sysattr_list_entry(dev);
+ while (entry) {
+ const char *key = udev_list_entry_get_name(entry);
+ const char *value;
+
+ if (is_on_blacklist(key)) {
+ entry = udev_list_entry_get_next(entry);
+ continue;
+ }
+
+ value = udev_device_get_sysattr_value(dev, key);
+ igt_device_add_attr(idev, key, value);
+ entry = udev_list_entry_get_next(entry);
+ DBG("attr: %s, val: %s\n", key, value);
+ }
+}
+
+#define get_prop(dev, prop) (char *) g_hash_table_lookup(dev->props_ht, prop)
+#define get_attr(dev, attr) (char *) g_hash_table_lookup(dev->attrs_ht, attr)
+#define get_prop_pci_id(dev) get_prop(dev, "PCI_ID")
+#define get_prop_pci_slot(dev) get_prop(dev, "PCI_SLOT_NAME")
+#define get_prop_devpath(dev) get_prop(dev, "DEVPATH")
+#define get_prop_driver(dev) get_prop(dev, "DRIVER")
+#define get_prop_modalias(dev) get_prop(dev, "MODALIAS")
+#define get_prop_of_compatible_0(dev) get_prop(dev, "OF_COMPATIBLE_0")
+
+/* Gets PCI_ID property, splits to xxxx:yyyy and stores
+ * xxxx to dev->vendor and yyyy to dev->device for
+ * faster access.
+ */
+static void set_vendor_device(struct igt_device *dev)
+{
+ const char *pci_id = get_prop_pci_id(dev);
+ if (!pci_id || strlen(pci_id) != 9)
+ return;
+ dev->vendor = strndup(pci_id, 4);
+ dev->device = strndup(pci_id + 5, 4);
+}
+
+/* Find appropriate /dev/dri/cardX and /dev/dri/renderDX nodes
+ * for igt_device.
+ */
+static void find_drm_paths(struct igt_device *dev)
+{
+ char dirname[PATH_MAX];
+ DIR *dir;
+ struct dirent *e;
+
+ snprintf(dirname, PATH_MAX, "%s/drm", dev->syspath);
+ dir = opendir(dirname);
+ if (!dir)
+ return;
+
+ while((e = readdir(dir))) {
+ int n;
+ if (sscanf(e->d_name, "card%d", &n) == 1)
+ dev->drm_card_path = g_strdup_printf("%s/%s",
+ IGT_DRM_PATH,
+ e->d_name);
+ else if (sscanf(e->d_name, "renderD%d", &n) == 1)
+ dev->drm_render_path = g_strdup_printf("%s/%s",
+ IGT_DRM_PATH,
+ e->d_name);
+ }
+ closedir(dir);
+
+ if (dev->drm_card_path)
+ DBG("card: %s\n", dev->drm_card_path);
+ if (dev->drm_render_path)
+ DBG("rend: %s\n", dev->drm_render_path);
+}
+
+static bool prepare_scan(void)
+{
+ if (!igt_devs.devs)
+ igt_devs.devs = g_ptr_array_sized_new(4);
+ if (!igt_devs.view)
+ igt_devs.view = g_ptr_array_sized_new(4);
+
+ if (!igt_devs.devs || !igt_devs.view)
+ return false;
+
+ return true;
+}
+
+static void set_udev_filter(struct udev_enumerate *enumerate,
+ struct name_value *nv)
+{
+ /* Bypass filtering, we want to see all devices.
+ * Likely used only in lsgpu.
+ */
+ if (getenv("IGT_SCAN_GET_ALL_DEVICES"))
+ return;
+
+ while (nv->name) {
+ udev_enumerate_add_match_property(enumerate, nv->name,
+ (const char *) nv->value);
+ nv++;
+ }
+}
+
+static void set_pci_udev_filter(struct udev_enumerate *enumerate)
+{
+ set_udev_filter(enumerate, &pci_udev_filters_attr_list[0]);
+}
+
+static void set_platform_udev_filter(struct udev_enumerate *enumerate)
+{
+ set_udev_filter(enumerate, &platform_udev_filters_attr_list[0]);
+}
+
+/* Subsystem scanning */
+struct {
+ unsigned int dev_type;
+
+ /* udev related */
+ const char *subsys;
+ void (*udev_filter)(struct udev_enumerate *enumerate);
+} cls[] = {
+ [IGT_SCAN_PCI] = { .dev_type = DEV_PCI,
+ .subsys = "pci",
+ .udev_filter = set_pci_udev_filter,
+ },
+ [IGT_SCAN_PLATFORM] = { .dev_type = DEV_PLATFORM,
+ .subsys = "platform",
+ .udev_filter = set_platform_udev_filter,
+ },
+};
+
+static void scan_devices(enum igt_devices_scan_type scantype)
+{
+ struct udev *udev;
+ struct udev_device *dev;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *dev_list_entry;
+ int ret;
+
+ udev = udev_new();
+ igt_assert(udev);
+
+ enumerate = udev_enumerate_new(udev);
+ igt_assert(enumerate);
+
+ DBG("Scanning subsystem %s\n", cls[scantype].subsys);
+ ret = udev_enumerate_add_match_subsystem(enumerate, cls[scantype].subsys);
+ igt_assert(!ret);
+ cls[scantype].udev_filter(enumerate);
+
+ ret = udev_enumerate_scan_devices(enumerate);
+ igt_assert(!ret);
+
+ devices = udev_enumerate_get_list_entry(enumerate);
+ if (!devices)
+ return;
+
+ udev_list_entry_foreach(dev_list_entry, devices) {
+ struct igt_device *idev;
+ const char *path;
+
+ path = udev_list_entry_get_name(dev_list_entry);
+ dev = udev_device_new_from_syspath(udev, path);
+
+ idev = igt_device_new();
+ igt_assert(idev);
+
+ idev->dev_type = cls[scantype].dev_type;
+ idev->syspath = strdup(udev_device_get_syspath(dev));
+ get_props(dev, idev);
+ get_attrs(dev, idev);
+ find_drm_paths(idev);
+
+ switch (idev->dev_type) {
+ const char *tmp;
+ case DEV_PCI:
+ tmp = get_prop_pci_slot(idev);
+ set_vendor_device(idev);
+ idev->pretty_name = strdup(tmp ?: " ? ");
+ idev->vs = get_vendor_spec(idev->vendor);
+ break;
+ default:
+ tmp = get_prop_modalias(idev);
+ idev->pretty_name = strdup(tmp ?: " ? ");
+ }
+
+ g_ptr_array_add(igt_devs.devs, idev);
+ g_ptr_array_add(igt_devs.view, idev);
+
+ udev_device_unref(dev);
+ }
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+}
+
+struct name_value filter_definition_list[];
+static void populate_gpu_data(void)
+{
+ fill_ht(&gpu_vendor_ht, &gpu_vendor_list[0]);
+ fill_ht(&filter_definition_ht, &filter_definition_list[0]);
+}
+
+static void igt_device_free(struct igt_device *dev)
+{
+ free(dev->pretty_name);
+ free(dev->device);
+ free(dev->drm_card_path);
+ free(dev->drm_render_path);
+ free(dev->drvpath);
+ free(dev->syspath);
+ free(dev->vendor);
+ g_hash_table_destroy(dev->attrs_ht);
+ g_hash_table_destroy(dev->props_ht);
+}
+
+void igt_devices_scan(bool force)
+{
+ if (force && igt_devs.devs_scanned) {
+ for (int i = 0; i < igt_devs.devs->len; i++) {
+ struct igt_device *dev = g_ptr_array_index(igt_devs.devs, i);
+ igt_device_free(dev);
+ free(dev);
+ }
+ igt_devs.devs_scanned = false;
+ g_ptr_array_free(igt_devs.view, true);
+ g_ptr_array_free(igt_devs.devs, true);
+ igt_devs.view = NULL;
+ igt_devs.devs = NULL;
+ }
+
+ if (igt_devs.devs_scanned)
+ return;
+
+ populate_blacklist_keys(); //keys from sysattr we skip
+ populate_gpu_data();
+
+ prepare_scan();
+ scan_devices(IGT_SCAN_PCI);
+ scan_devices(IGT_SCAN_PLATFORM);
+ igt_devs.devs_scanned = true;
+}
+
+#define pr_simple(k, v) printf(" %-16s: %s\n", k, v)
+#define pr_simple_prop(dev, key) pr_simple(key, get_prop(dev, key))
+#define pr_simple_attr(dev, key) pr_simple(key, get_attr(dev, key))
+
+static void igt_devs_print_simple(GPtrArray *view)
+{
+ struct igt_device *dev;
+ int i;
+
+ if (!view)
+ return;
+
+ for (i = 0; i < view->len; i++) {
+ dev = g_ptr_array_index(view, i);
+ printf("%s\n", dev->pretty_name);
+ pr_simple("syspath", dev->syspath);
+ pr_simple("drm card", dev->drm_card_path);
+ pr_simple("drm render", dev->drm_render_path);
+
+ if (get_prop_pci_id(dev))
+ pr_simple_prop(dev, "PCI_ID");
+ if (get_prop_driver(dev))
+ pr_simple_prop(dev, "DRIVER");
+ }
+}
+
+#define pr_detail(k, v) printf("%-32s: %s\n", k, v)
+
+static void print_ht(GHashTable *ht)
+{
+ GList *keys = g_hash_table_get_keys(ht);
+ keys = g_list_sort(keys, (GCompareFunc) strcmp);
+ while (keys) {
+ char *k = (char *) keys->data;
+ char *v = g_hash_table_lookup(ht, k);
+ pr_detail(k, v);
+ keys = g_list_next(keys);
+ }
+ g_list_free(keys);
+}
+
+static void igt_devs_print_detail(GPtrArray *view)
+{
+ struct igt_device *dev;
+ int i;
+
+ if (!view)
+ return;
+
+ for (i = 0; i < view->len; i++) {
+ dev = g_ptr_array_index(view, i);
+ printf("========== %s ==========\n", dev->pretty_name);
+ printf("[drm]\n");
+ pr_detail("card device", dev->drm_card_path);
+ pr_detail("render device", dev->drm_render_path);
+ pr_detail("syspath", dev->syspath);
+
+ printf("\n[properties]\n");
+ print_ht(dev->props_ht);
+ printf("\n[attributes]\n");
+ print_ht(dev->attrs_ht);
+ }
+}
+
+static struct print_func {
+ void (*prn)(GPtrArray *);
+} print_functions[] = {
+ [IGT_PRINT_SIMPLE] = { .prn = igt_devs_print_simple },
+ [IGT_PRINT_DETAIL] = { .prn = igt_devs_print_detail },
+};
+
+void igt_devices_print(enum igt_devices_print_type printtype)
+{
+ print_functions[printtype].prn(igt_devs.view);
+}
+
+void igt_devices_print_vendors(void)
+{
+ struct name_value *list = &gpu_vendor_list[0];
+ printf("Recognized vendors:\n");
+
+ printf("%-8s %-16s\n", "PCI ID", "vendor");
+ while (list->name) {
+ struct vendor_spec *vs = (struct vendor_spec *) list->value;
+ if (vs)
+ printf("%-8s %-16s\n", list->name, vs->vendor);
+ list++;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+#define FILTER_SPEC_NAME_LEN 32
+#define FILTER_SPEC_DATA_LEN 256
+struct filter_spec {
+ char name[FILTER_SPEC_NAME_LEN];
+ char data[FILTER_SPEC_DATA_LEN];
+};
+
+struct filter_func {
+ GPtrArray *(*filter_function)(struct filter_spec *fspec,
+ struct filter_func *ffunc);
+ const char *help;
+ const char *detail;
+
+ const char *property;
+ const char *value;
+};
+
+struct filter_data {
+ char *vendor;
+ char *device;
+ char *card;
+};
+
+static GHashTable *split_filter_data(const char *data)
+{
+ GHashTable *ht = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, free);
+ gchar **s;
+ gchar **strv = g_strsplit(data, ",", -1);
+
+ s = strv;
+ while (*s) {
+ char *k, *v;
+ v = strchr(*s, '=');
+ if (!v) {
+ s++;
+ continue;
+ }
+ k = strndup(*s, v - (*s));
+ v = strdup(v + 1);
+ g_hash_table_insert(ht, k, v);
+ s++;
+ }
+ g_strfreev(strv);
+
+ return ht;
+}
+
+static bool get_filter_spec(const char *filter, struct filter_spec *spec)
+{
+ if (!filter)
+ return false;
+
+ if (sscanf(filter, "%31[^:]:%255s", spec->name, spec->data) >= 1)
+ return true;
+
+ return false;
+}
+
+static GPtrArray *filter_drm(struct filter_spec *fspec,
+ struct filter_func *ffunc)
+{
+ GHashTable *ht;
+ GPtrArray *devs, *view;
+ struct filter_data fdata;
+ int card = -1;
+ char cardstr[NAME_MAX];
+
+ (void) ffunc;
+ DBG("filter drm\n");
+
+ ht = split_filter_data(fspec->data);
+ fdata.card = g_hash_table_lookup(ht, "card");
+
+ view = igt_devs.view;
+ devs = igt_devs.devs;
+
+ if (fdata.card) {
+ sscanf(fdata.card, "%d", &card);
+ if (card < 0) {
+ g_hash_table_destroy(ht);
+ return view;
+ }
+ } else {
+ card = 0;
+ }
+
+ snprintf(cardstr, NAME_MAX, "%s/card%d", IGT_DRM_PATH, card);
+ for (int i = 0; i < devs->len; i++) {
+ struct igt_device *dev = g_ptr_array_index(devs, i);
+ if (dev->drm_card_path && !strcmp(cardstr, dev->drm_card_path)) {
+ g_ptr_array_add(view, dev);
+ break;
+ }
+ }
+
+ DBG("Filter drm view size: %d\n", view->len);
+
+ g_hash_table_destroy(ht);
+
+ return view;
+}
+
+static GPtrArray *filter_pci(struct filter_spec *fspec,
+ struct filter_func *ffunc)
+{
+ GHashTable *ht;
+ GPtrArray *devs, *view;
+ struct filter_data fdata;
+ int card = -1;
+
+ DBG("filter pci\n");
+
+ (void) ffunc;
+ ht = split_filter_data(fspec->data);
+ fdata.vendor = g_hash_table_lookup(ht, "vendor");
+ fdata.device = g_hash_table_lookup(ht, "device");
+ fdata.card = g_hash_table_lookup(ht, "card");
+
+ view = igt_devs.view;
+ devs = igt_devs.devs;
+
+ if (fdata.card) {
+ sscanf(fdata.card, "%d", &card);
+ if (card < 0) {
+ g_hash_table_destroy(ht);
+ return view;
+ }
+ } else {
+ card = 0;
+ }
+
+ for (int i = 0; i < devs->len; i++) {
+ struct igt_device *dev = g_ptr_array_index(devs, i);
+
+ if (dev->dev_type != DEV_PCI)
+ continue;
+
+ /* Skip if 'vendor' doesn't match (hex or name) */
+ if (fdata.vendor &&
+ strcasecmp(fdata.vendor, dev->vendor) &&
+ !is_pci_vendor_name(fdata.vendor))
+ continue;
+
+ /* Skip if 'device' doesn't match */
+ if (fdata.device &&
+ strcasecmp(fdata.device, dev->device))
+ continue;
+
+ if (!card) {
+ g_ptr_array_add(view, dev);
+ break;
+ }
+ card--;
+ }
+
+ DBG("Filter pci view size: %d\n", view->len);
+
+ g_hash_table_destroy(ht);
+
+ return view;
+}
+
+/* Helper for finding first device matching property:value. */
+static GPtrArray *filter_property(struct filter_spec *fspec,
+ struct filter_func *ffunc)
+{
+ GHashTable *ht;
+ GPtrArray *devs, *view;
+ struct filter_data fdata;
+ int card = -1;
+ const char *property = ffunc->property;
+ const char *value = ffunc->value;
+
+ if (!property || !value)
+ return igt_devs.view;
+
+ DBG("filter property/value [%s/%s]\n", property, value);
+
+ ht = split_filter_data(fspec->data);
+ fdata.card = g_hash_table_lookup(ht, "card");
+
+ view = igt_devs.view;
+ devs = igt_devs.devs;
+
+ if (fdata.card) {
+ sscanf(fdata.card, "%d", &card);
+ if (card < 0) {
+ g_hash_table_destroy(ht);
+ return view;
+ }
+ } else {
+ card = 0;
+ }
+
+ for (int i = 0; i < devs->len; i++) {
+ const char *prop_value;
+ struct igt_device *dev = g_ptr_array_index(devs, i);
+
+ prop_value = get_prop(dev, property);
+ if (prop_value && !strcmp(prop_value, value)) {
+ if (!card) {
+ g_ptr_array_add(view, dev);
+ break;
+ }
+ card--;
+ }
+ }
+
+ DBG("Filter view size: %d\n", view->len);
+
+ g_hash_table_destroy(ht);
+
+ return view;
+}
+
+static GPtrArray *filter_vgem(struct filter_spec *fspec,
+ struct filter_func *ffunc)
+{
+ GPtrArray *view = filter_property(fspec, ffunc);
+ if (view) {
+ struct igt_device *dev = g_ptr_array_index(view, 0);
+ dev->vs = &v_vgem;
+ }
+ return view;
+}
+
+static GPtrArray *filter_vkms(struct filter_spec *fspec,
+ struct filter_func *ffunc)
+{
+ return filter_property(fspec, ffunc);
+}
+
+static GPtrArray *filter_vc4(struct filter_spec *fspec,
+ struct filter_func *ffunc)
+{
+ GPtrArray *view = filter_property(fspec, ffunc);
+ if (view) {
+ struct igt_device *dev = g_ptr_array_index(view, 0);
+ dev->vs = &v_vc4;
+ }
+ return filter_property(fspec, ffunc);
+}
+
+static struct filter_func f_drm = { .filter_function = filter_drm,
+ .help = "drm:[card=%d]",
+ .detail = "card is N-card number (from /dev/dri/cardN)\n",
+ };
+
+static struct filter_func f_pci = { .filter_function = filter_pci,
+ .help = "pci:[vendor=%04x/name][,device=%04x][,card=%d]\n",
+ .detail = "vendor is hex number or name",
+ };
+
+static struct filter_func f_vgem = { .filter_function = filter_vgem,
+ .help = "vgem:[card=%d]",
+ .detail = "card is n-th vgem card number\n",
+ .property = "MODALIAS",
+ .value = "platform:vgem",
+ };
+
+static struct filter_func f_vkms = { .filter_function = filter_vkms,
+ .help = "vkms:[card=%d]",
+ .detail = "card is n-th vkms card number\n",
+ .property = "MODALIAS",
+ .value = "platform:vkms",
+ };
+
+static struct filter_func f_vc4 = { .filter_function = filter_vc4,
+ .help = "vc4:[card=%d]",
+ .detail = "card is n-th vc4 card number\n",
+ .property = "OF_COMPATIBLE_0",
+ .value = "brcm,bcm2835-vc4",
+ };
+
+struct name_value filter_definition_list[] = {
+ { "drm", (gpointer) &f_drm },
+ { "pci", (gpointer) &f_pci },
+ { "vgem", (gpointer) &f_vgem },
+ { "vkms", (gpointer) &f_vkms },
+ { "vc4", (gpointer) &f_vc4 },
+ { NULL, },
+};
+
+void igt_device_print_filter_types(void)
+{
+ struct name_value *list = &filter_definition_list[0];
+
+ printf("Filter types:\n---\n");
+ printf("%-8s %s\n---\n", "filter", "syntax");
+ while (list->name) {
+ struct filter_func *v = (struct filter_func *) list->value;
+ printf("%-8s %s\n", list->name, v->help);
+ printf("%-8s %s\n", "", v->detail);
+ list++;
+ }
+}
+
+static GPtrArray *device_filters = NULL;
+
+#define DEVICE_FILTER_CHECK_ALLOC() \
+ do { \
+ if (!device_filters) \
+ device_filters = g_ptr_array_new_full(2, free); \
+ igt_assert(device_filters); \
+ } while(0)
+
+int igt_device_filter_count(void)
+{
+ DEVICE_FILTER_CHECK_ALLOC();
+
+ return device_filters->len;
+}
+
+int igt_device_filter_add(const char *filter)
+{
+ gchar **strv, **s;
+ int c = 0;
+
+ DEVICE_FILTER_CHECK_ALLOC();
+
+ strv = g_strsplit(filter, ";", -1);
+
+ s = strv;
+ while (*s) {
+ g_ptr_array_add(device_filters, strdup(*s));
+ s++;
+ }
+ g_strfreev(strv);
+
+ return c;
+}
+
+const char *igt_device_filter_get(int num)
+{
+ DEVICE_FILTER_CHECK_ALLOC();
+
+ if (num < 0 || num >= device_filters->len)
+ return NULL;
+
+ return g_ptr_array_index(device_filters, num);
+}
+
+#define dev_is_non_discoverable(vs) \
+ ((vs)->dev_type == DEV_PLATFORM_NON_DISCOVERABLE)
+
+bool igt_device_filter_apply(const char *filter)
+{
+ struct filter_spec fspec;
+ struct filter_func *ffunc;
+ bool ret;
+
+ if (!filter)
+ return false;
+
+ ret = get_filter_spec(filter, &fspec);
+ if (!ret) {
+ igt_warn("Can't split filter [%s]\n", filter);
+ return false;
+ }
+
+ ffunc = g_hash_table_lookup(filter_definition_ht, fspec.name);
+ if (!ffunc) {
+ igt_warn("No filter with name [%s]\n", fspec.name);
+ return false;
+ }
+
+ /* Clean view */
+ g_ptr_array_remove_range(igt_devs.view, 0, igt_devs.view->len);
+
+ ffunc->filter_function(&fspec, ffunc);
+
+ return true;
+}
+
+bool igt_device_filter_apply_nth(int num)
+{
+ const char *filter = igt_device_filter_get(num);
+ if (!filter)
+ return false;
+
+ return igt_device_filter_apply(filter);
+}
+
+#define safe_strncpy(dst, src, size) \
+ if (src) strncpy((dst), (src), (size))
+/*
+ * Returns:
+ * false - no card pointer was passed or card wasn't matched,
+ * true - card matched and returned.
+ */
+bool igt_device_card_match(const char *filter, struct igt_device_card *card)
+{
+ struct igt_device *dev = NULL;
+
+ if (!card)
+ return false;
+ memset(card, 0, sizeof(*card));
+
+ igt_devices_scan(false);
+
+ if (igt_device_filter_apply(filter) == false)
+ return false;
+
+ if (!igt_devs.view->len)
+ return false;
+
+ /* We take first one if more than one card matches filter */
+ dev = g_ptr_array_index(igt_devs.view, 0);
+ card->dev_type = dev->dev_type;
+ card->chipset = DRIVER_ANY;
+ if (dev->vs)
+ card->chipset = dev->vs->chipset;
+ if (dev->dev_type == DEV_PCI) {
+ safe_strncpy(card->pci_slot, get_prop_pci_slot(dev),
+ PCI_SLOT_LENGTH);
+ }
+ safe_strncpy(card->card, dev->drm_card_path, NAME_MAX);
+ safe_strncpy(card->render, dev->drm_render_path, NAME_MAX);
+
+ return true;
+}
diff --git a/lib/igt_device_scan.h b/lib/igt_device_scan.h
new file mode 100644
index 00000000..b03b3007
--- /dev/null
+++ b/lib/igt_device_scan.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef __IGT_DEVICE_SCAN_H__
+#define __IGT_DEVICE_SCAN_H__
+
+#include <limits.h>
+#include <igt.h>
+
+enum igt_devices_print_type {
+ IGT_PRINT_SIMPLE,
+ IGT_PRINT_DETAIL,
+};
+
+enum igt_device_type {
+ DEV_PCI,
+ DEV_PLATFORM,
+};
+
+#define PCI_SLOT_LENGTH 13
+struct igt_device_card {
+ enum igt_device_type dev_type;
+ int chipset;
+ char card[NAME_MAX];
+ char render[NAME_MAX];
+ char pci_slot[PCI_SLOT_LENGTH];
+};
+
+/* Scan udev subsystems. Do it once unless force is true, what rescans
+ * devices again */
+void igt_devices_scan(bool force);
+
+void igt_devices_print(enum igt_devices_print_type printtype);
+void igt_devices_print_vendors(void);
+void igt_device_print_filter_types(void);
+
+/*
+ * Handle device filter collection array.
+ * IGT can store/retrieve filters passed by user using '--device' args.
+*/
+
+/* Return number of filters collected */
+int igt_device_filter_count(void);
+
+/* Add filter(s) to the array. Returns number of filters added (>1 if
+ * user passes more than one filter separatined by ';') */
+int igt_device_filter_add(const char *filter);
+
+/* Get n-th filter stored in the array or NULL */
+const char *igt_device_filter_get(int num);
+
+/* Create devices view according to filter passed as an argument */
+bool igt_device_filter_apply(const char *filter);
+
+/* Apply n-th filter and create the view */
+bool igt_device_filter_apply_nth(int num);
+
+/* Use filter to match the device and fill card structure */
+bool igt_device_card_match(const char *filter, struct igt_device_card *card);
+
+#endif /* __IGT_DEVICE_SCAN_H__ */
diff --git a/lib/meson.build b/lib/meson.build
index 157624e7..826ebbe3 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -10,6 +10,7 @@ lib_sources = [
'igt_color_encoding.c',
'igt_debugfs.c',
'igt_device.c',
+ 'igt_device_scan.c',
'igt_aux.c',
'igt_gpu_power.c',
'igt_gt.c',
diff --git a/tools/Makefile.sources b/tools/Makefile.sources
index 50706f41..0e67b654 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..4c221ad5
--- /dev/null
+++ b/tools/lsgpu.c
@@ -0,0 +1,221 @@
+/*
+ * 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>
+
+enum {
+ OPT_PRINT_SIMPLE = 'i',
+ OPT_PRINT_DETAIL = 'd',
+ OPT_DISPLAY_ALL = 'a',
+ OPT_LIST_VENDORS = 'v',
+ OPT_LIST_FILTERS = 'l',
+ OPT_SET_FILTER = 's',
+ OPT_DEVICE = 'D',
+ OPT_HELP = 'h'
+};
+
+bool g_display_all;
+bool g_show_vendors;
+char *g_pci_id;
+bool g_list_filters;
+char *g_filter;
+bool g_device;
+bool g_help;
+
+static const char *usage_str =
+ "usage: lsgpu [options]\n\n"
+ "Options:\n"
+ " -i, --print-simple Print devices as simple list (default)\n"
+ " -d, --print-details Print devices with details\n"
+ " -a, --display-all Don't apply udev filters and print all devices\n"
+ " -v, --list-vendors List recognized vendors\n"
+ " -l, --list-filter-types List registered device filters types\n"
+ " -s, --set-filter filter Set filter for processing devices\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 = __drm_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 = __drm_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;
+
+ switch (card->dev_type) {
+ case DEV_PCI:
+ printf("dev type : %s\n", "PCI");
+ printf("PCI slot : %s\n", card->pci_slot);
+ break;
+ case DEV_PLATFORM:
+ printf("dev type : %s\n", "PLATFORM");
+ break;
+ }
+ printf("chipset : %x\n", card->chipset);
+ printf("drm card : %s\n", card->card);
+ printf("drm render : %s\n", card->render);
+}
+
+int main(int argc, char *argv[])
+{
+ static struct option long_options[] = {
+ {"print-simple", no_argument, NULL, OPT_PRINT_SIMPLE},
+ {"print-detail", no_argument, NULL, OPT_PRINT_DETAIL},
+ {"display-all", no_argument, NULL, OPT_DISPLAY_ALL},
+ {"list-vendors", no_argument, NULL, OPT_LIST_VENDORS},
+ {"list-filter-types", no_argument, NULL, OPT_LIST_FILTERS},
+ {"set-filter", required_argument, NULL, OPT_SET_FILTER},
+ {"device", required_argument, NULL, OPT_DEVICE},
+ {"help", no_argument, NULL, OPT_HELP},
+ {0, 0, 0, 0}
+ };
+ int c, index = 0;
+ const char *env;
+ enum igt_devices_print_type printtype = IGT_PRINT_SIMPLE;
+
+ while ((c = getopt_long(argc, argv, "idavls:D:h",
+ long_options, &index)) != -1) {
+ switch(c) {
+ case OPT_PRINT_SIMPLE:
+ printtype = IGT_PRINT_SIMPLE;
+ break;
+ case OPT_PRINT_DETAIL:
+ printtype = IGT_PRINT_DETAIL;
+ break;
+ case OPT_DISPLAY_ALL:
+ g_display_all = true;
+ break;
+ case OPT_LIST_VENDORS:
+ g_show_vendors = true;
+ break;
+ case OPT_SET_FILTER:
+ g_filter = strdup(optarg);
+ break;
+ case OPT_LIST_FILTERS:
+ g_list_filters = true;
+ break;
+ case OPT_DEVICE:
+ g_device = true;
+ igt_device_filter_add(optarg);
+ break;
+ case OPT_HELP:
+ g_help = true;
+ break;
+ }
+ }
+
+ if (g_help) {
+ printf("%s\n", usage_str);
+ exit(0);
+ }
+
+ env = getenv("IGT_DEVICE");
+ if (env) {
+ igt_device_filter_add(env);
+ g_device = true;
+ }
+
+ if (g_show_vendors) {
+ igt_devices_print_vendors();
+ return 0;
+ }
+
+ if (g_list_filters) {
+ igt_device_print_filter_types();
+ return 0;
+ }
+
+ /* This variable is used only for lsgpu to display information
+ * about all devices in udev */
+ if (g_display_all)
+ setenv("IGT_SCAN_GET_ALL_DEVICES", "1", 0);
+ igt_devices_scan(false);
+
+ if (g_filter) {
+ igt_device_filter_apply(g_filter);
+ }
+
+ if (g_device) {
+ int n = igt_device_filter_count();
+ printf("=== Device filter list ===\n");
+ for (int i = 0; i < n; i++) {
+ printf("[%2d]: %s\n", i,
+ igt_device_filter_get(i));
+ igt_device_filter_apply_nth(i);
+ igt_devices_print(printtype);
+ }
+ printf("\n");
+
+ printf("=== Testing device open ===\n");
+ for (int i = 0; i < n; i++) {
+ struct igt_device_card card;
+ const char *filter = igt_device_filter_get(i);
+
+ if (!igt_device_card_match(filter, &card))
+ continue;
+ print_card(&card);
+ test_device_open(&card);
+ printf("---\n");
+ }
+
+ return 0;
+ }
+
+ igt_devices_print(printtype);
+
+ return 0;
+}
diff --git a/tools/meson.build b/tools/meson.build
index 6e72b263..9b3a2a69 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.21.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [igt-dev] ✓ Fi.CI.BAT: success for Add device selection methods (rev2)
2019-07-19 9:50 [igt-dev] [PATCH i-g-t v2 0/1] Add device selection methods Zbigniew Kempczyński
2019-07-19 9:50 ` [igt-dev] [PATCH i-g-t v2 1/1] Introduce new method of device selection Zbigniew Kempczyński
@ 2019-07-19 11:05 ` Patchwork
2019-07-19 12:09 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2 siblings, 0 replies; 4+ messages in thread
From: Patchwork @ 2019-07-19 11:05 UTC (permalink / raw)
To: Zbigniew Kempczyński; +Cc: igt-dev
== Series Details ==
Series: Add device selection methods (rev2)
URL : https://patchwork.freedesktop.org/series/63553/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_6509 -> IGTPW_3277
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://patchwork.freedesktop.org/api/1.0/series/63553/revisions/2/mbox/
Known issues
------------
Here are the changes found in IGTPW_3277 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@i915_selftest@live_blt:
- fi-icl-dsi: [PASS][1] -> [INCOMPLETE][2] ([fdo#107713])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/fi-icl-dsi/igt@i915_selftest@live_blt.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/fi-icl-dsi/igt@i915_selftest@live_blt.html
* igt@kms_frontbuffer_tracking@basic:
- fi-icl-u2: [PASS][3] -> [FAIL][4] ([fdo#103167])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/fi-icl-u2/igt@kms_frontbuffer_tracking@basic.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/fi-icl-u2/igt@kms_frontbuffer_tracking@basic.html
#### Possible fixes ####
* igt@kms_busy@basic-flip-c:
- {fi-icl-u4}: [DMESG-WARN][5] ([fdo#105602]) -> [PASS][6] +5 similar issues
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/fi-icl-u4/igt@kms_busy@basic-flip-c.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/fi-icl-u4/igt@kms_busy@basic-flip-c.html
* igt@kms_chamelium@hdmi-edid-read:
- {fi-icl-u4}: [FAIL][7] ([fdo#111045] / [fdo#111046 ]) -> [PASS][8]
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/fi-icl-u4/igt@kms_chamelium@hdmi-edid-read.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/fi-icl-u4/igt@kms_chamelium@hdmi-edid-read.html
* igt@kms_chamelium@hdmi-hpd-fast:
- {fi-icl-u4}: [FAIL][9] ([fdo#111045]) -> [PASS][10]
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/fi-icl-u4/igt@kms_chamelium@hdmi-hpd-fast.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/fi-icl-u4/igt@kms_chamelium@hdmi-hpd-fast.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#102505]: https://bugs.freedesktop.org/show_bug.cgi?id=102505
[fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
[fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
[fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
[fdo#111045]: https://bugs.freedesktop.org/show_bug.cgi?id=111045
[fdo#111046 ]: https://bugs.freedesktop.org/show_bug.cgi?id=111046
[fdo#111049]: https://bugs.freedesktop.org/show_bug.cgi?id=111049
Participating hosts (52 -> 47)
------------------------------
Missing (5): fi-byt-squawks fi-bsw-cyan fi-icl-y fi-byt-clapper fi-bdw-samus
Build changes
-------------
* IGT: IGT_5103 -> IGTPW_3277
CI_DRM_6509: 2eda05e19db04b001c2b0a9b32bfd43077d5a738 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_3277: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/
IGT_5103: 45c31e294b9d7874a9a21860f8a89c64bc853df2 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 4+ messages in thread
* [igt-dev] ✓ Fi.CI.IGT: success for Add device selection methods (rev2)
2019-07-19 9:50 [igt-dev] [PATCH i-g-t v2 0/1] Add device selection methods Zbigniew Kempczyński
2019-07-19 9:50 ` [igt-dev] [PATCH i-g-t v2 1/1] Introduce new method of device selection Zbigniew Kempczyński
2019-07-19 11:05 ` [igt-dev] ✓ Fi.CI.BAT: success for Add device selection methods (rev2) Patchwork
@ 2019-07-19 12:09 ` Patchwork
2 siblings, 0 replies; 4+ messages in thread
From: Patchwork @ 2019-07-19 12:09 UTC (permalink / raw)
To: Zbigniew Kempczyński; +Cc: igt-dev
== Series Details ==
Series: Add device selection methods (rev2)
URL : https://patchwork.freedesktop.org/series/63553/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_6509_full -> IGTPW_3277_full
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://patchwork.freedesktop.org/api/1.0/series/63553/revisions/2/mbox/
Known issues
------------
Here are the changes found in IGTPW_3277_full that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@gem_exec_balancer@smoke:
- shard-iclb: [PASS][1] -> [SKIP][2] ([fdo#110854])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb2/igt@gem_exec_balancer@smoke.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb6/igt@gem_exec_balancer@smoke.html
* igt@gem_tiled_swapping@non-threaded:
- shard-apl: [PASS][3] -> [DMESG-WARN][4] ([fdo#108686])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-apl5/igt@gem_tiled_swapping@non-threaded.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-apl8/igt@gem_tiled_swapping@non-threaded.html
* igt@gem_workarounds@suspend-resume-context:
- shard-apl: [PASS][5] -> [DMESG-WARN][6] ([fdo#108566]) +2 similar issues
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-apl2/igt@gem_workarounds@suspend-resume-context.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-apl7/igt@gem_workarounds@suspend-resume-context.html
* igt@i915_pm_rc6_residency@rc6-accuracy:
- shard-kbl: [PASS][7] -> [SKIP][8] ([fdo#109271])
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-kbl4/igt@i915_pm_rc6_residency@rc6-accuracy.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-kbl2/igt@i915_pm_rc6_residency@rc6-accuracy.html
* igt@i915_pm_rpm@i2c:
- shard-hsw: [PASS][9] -> [FAIL][10] ([fdo#104097])
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-hsw8/igt@i915_pm_rpm@i2c.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-hsw7/igt@i915_pm_rpm@i2c.html
* igt@kms_flip@2x-flip-vs-expired-vblank:
- shard-glk: [PASS][11] -> [FAIL][12] ([fdo#105363])
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-glk9/igt@kms_flip@2x-flip-vs-expired-vblank.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-glk6/igt@kms_flip@2x-flip-vs-expired-vblank.html
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-blt:
- shard-iclb: [PASS][13] -> [FAIL][14] ([fdo#103167]) +2 similar issues
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb8/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-blt.html
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb8/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-blt.html
* igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
- shard-kbl: [PASS][15] -> [INCOMPLETE][16] ([fdo#103665])
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-kbl6/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-kbl3/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
* igt@kms_psr@psr2_cursor_render:
- shard-iclb: [PASS][17] -> [SKIP][18] ([fdo#109441]) +2 similar issues
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb2/igt@kms_psr@psr2_cursor_render.html
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb3/igt@kms_psr@psr2_cursor_render.html
* igt@kms_setmode@basic:
- shard-kbl: [PASS][19] -> [FAIL][20] ([fdo#99912])
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-kbl3/igt@kms_setmode@basic.html
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-kbl7/igt@kms_setmode@basic.html
#### Possible fixes ####
* igt@gem_ctx_isolation@rcs0-s3:
- shard-apl: [DMESG-WARN][21] ([fdo#108566]) -> [PASS][22] +3 similar issues
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-apl5/igt@gem_ctx_isolation@rcs0-s3.html
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-apl6/igt@gem_ctx_isolation@rcs0-s3.html
* igt@gem_eio@unwedge-stress:
- shard-snb: [FAIL][23] ([fdo#109661]) -> [PASS][24]
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-snb5/igt@gem_eio@unwedge-stress.html
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-snb6/igt@gem_eio@unwedge-stress.html
* igt@gem_mmap_gtt@big-copy:
- shard-iclb: [INCOMPLETE][25] ([fdo#107713] / [fdo#109100]) -> [PASS][26]
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb7/igt@gem_mmap_gtt@big-copy.html
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb8/igt@gem_mmap_gtt@big-copy.html
* igt@i915_pm_rc6_residency@rc6-accuracy:
- shard-iclb: [SKIP][27] ([fdo#110933]) -> [PASS][28]
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb5/igt@i915_pm_rc6_residency@rc6-accuracy.html
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb6/igt@i915_pm_rc6_residency@rc6-accuracy.html
* igt@kms_atomic_transition@plane-toggle-modeset-transition:
- shard-snb: [SKIP][29] ([fdo#109271]) -> [PASS][30] +1 similar issue
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-snb1/igt@kms_atomic_transition@plane-toggle-modeset-transition.html
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-snb2/igt@kms_atomic_transition@plane-toggle-modeset-transition.html
* igt@kms_flip@dpms-vs-vblank-race:
- shard-kbl: [FAIL][31] ([fdo#103060]) -> [PASS][32]
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-kbl1/igt@kms_flip@dpms-vs-vblank-race.html
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-kbl7/igt@kms_flip@dpms-vs-vblank-race.html
* igt@kms_flip@modeset-vs-vblank-race-interruptible:
- shard-glk: [FAIL][33] ([fdo#103060]) -> [PASS][34]
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-glk5/igt@kms_flip@modeset-vs-vblank-race-interruptible.html
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-glk6/igt@kms_flip@modeset-vs-vblank-race-interruptible.html
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-mmap-gtt:
- shard-kbl: [FAIL][35] ([fdo#103167]) -> [PASS][36]
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-kbl4/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-mmap-gtt.html
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-kbl6/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-mmap-gtt.html
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-render:
- shard-iclb: [FAIL][37] ([fdo#103167]) -> [PASS][38]
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb2/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-render.html
[38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-render.html
* igt@kms_psr@psr2_primary_mmap_gtt:
- shard-iclb: [SKIP][39] ([fdo#109441]) -> [PASS][40]
[39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb6/igt@kms_psr@psr2_primary_mmap_gtt.html
[40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb2/igt@kms_psr@psr2_primary_mmap_gtt.html
* igt@perf_pmu@rc6:
- shard-iclb: [SKIP][41] ([fdo#110877]) -> [PASS][42]
[41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb4/igt@perf_pmu@rc6.html
[42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb3/igt@perf_pmu@rc6.html
#### Warnings ####
* igt@i915_pm_rc6_residency@media-rc6-accuracy:
- shard-iclb: [SKIP][43] ([fdo#110933]) -> [SKIP][44] ([fdo#109289])
[43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6509/shard-iclb4/igt@i915_pm_rc6_residency@media-rc6-accuracy.html
[44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/shard-iclb2/igt@i915_pm_rc6_residency@media-rc6-accuracy.html
[fdo#103060]: https://bugs.freedesktop.org/show_bug.cgi?id=103060
[fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
[fdo#103665]: https://bugs.freedesktop.org/show_bug.cgi?id=103665
[fdo#104097]: https://bugs.freedesktop.org/show_bug.cgi?id=104097
[fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
[fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
[fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
[fdo#108686]: https://bugs.freedesktop.org/show_bug.cgi?id=108686
[fdo#109100]: https://bugs.freedesktop.org/show_bug.cgi?id=109100
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
[fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
[fdo#109661]: https://bugs.freedesktop.org/show_bug.cgi?id=109661
[fdo#110854]: https://bugs.freedesktop.org/show_bug.cgi?id=110854
[fdo#110877]: https://bugs.freedesktop.org/show_bug.cgi?id=110877
[fdo#110933]: https://bugs.freedesktop.org/show_bug.cgi?id=110933
[fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912
Participating hosts (10 -> 6)
------------------------------
Missing (4): pig-skl-6260u shard-skl pig-hsw-4770r pig-glk-j5005
Build changes
-------------
* IGT: IGT_5103 -> IGTPW_3277
* Piglit: piglit_4509 -> None
CI_DRM_6509: 2eda05e19db04b001c2b0a9b32bfd43077d5a738 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_3277: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/
IGT_5103: 45c31e294b9d7874a9a21860f8a89c64bc853df2 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3277/
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-07-19 12:09 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-07-19 9:50 [igt-dev] [PATCH i-g-t v2 0/1] Add device selection methods Zbigniew Kempczyński
2019-07-19 9:50 ` [igt-dev] [PATCH i-g-t v2 1/1] Introduce new method of device selection Zbigniew Kempczyński
2019-07-19 11:05 ` [igt-dev] ✓ Fi.CI.BAT: success for Add device selection methods (rev2) Patchwork
2019-07-19 12:09 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox