[igt-dev] [PATCH i-g-t 3/3] Add device selection in IGT

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


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

New IGT command line argument --device, IGT_DEVICE enviroment and .igtrc
Common::Device were added to allow selecting device using device
selection API. See generated docs for device selection and lsgpu for
more details on filters.

NOTE: IGT_FORCE_DRIVER still works if no filter is selected. We may want
      to deprecate it later.

NOTE2: This does not work with tests that open 2 or more devices (e.g.
       kms_prime). The core is capable of doing multiple filtering
       passes but we need to figure out how we want *open*() functions
       to expose this capability.

v2 (Arek):
 * remove functions acting on igt_device_card
 * use only a single filter
v3 (Arek):
 * typos, misspellings (Petri)
 * add notes on IGT_FORCE_DRIVER and opening 2 or more devices

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>
---
 .../igt-gpu-tools/igt_test_programs.xml       |  7 ++
 lib/drmtest.c                                 | 94 +++++++++++++++++--
 lib/drmtest.h                                 |  2 +
 lib/igt_core.c                                | 47 ++++++++++
 4 files changed, 142 insertions(+), 8 deletions(-)

diff --git a/docs/reference/igt-gpu-tools/igt_test_programs.xml b/docs/reference/igt-gpu-tools/igt_test_programs.xml
index 3c1e18ee..92bc33ba 100644
--- a/docs/reference/igt-gpu-tools/igt_test_programs.xml
+++ b/docs/reference/igt-gpu-tools/igt_test_programs.xml
@@ -43,6 +43,13 @@
             </para></listitem>
           </varlistentry>
 
+          <varlistentry>
+            <term><option>--device filter</option></term>
+            <listitem><para>
+                select device using filter (see "Device selection" for details)
+            </para></listitem>
+          </varlistentry>
+
           <varlistentry>
             <term><option>--help-description</option></term>
             <listitem><para>
diff --git a/lib/drmtest.c b/lib/drmtest.c
index c379a7b7..1fc39925 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"
@@ -266,14 +267,9 @@ static int __search_and_open(const char *base, int offset, unsigned int chipset)
 	return -1;
 }
 
-static int __open_driver(const char *base, int offset, unsigned int chipset)
+static void __try_modprobe(unsigned int chipset)
 {
 	static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-	int fd;
-
-	fd = __search_and_open(base, offset, chipset);
-	if (fd != -1)
-		return fd;
 
 	pthread_mutex_lock(&mutex);
 	for (const struct module *m = modules; m->module; m++) {
@@ -285,26 +281,108 @@ static int __open_driver(const char *base, int offset, unsigned int chipset)
 		}
 	}
 	pthread_mutex_unlock(&mutex);
+}
+
+static int __open_driver(const char *base, int offset, unsigned int chipset)
+{
+	int fd;
+
+	fd = __search_and_open(base, offset, chipset);
+	if (fd != -1)
+		return fd;
+
+	__try_modprobe(chipset);
 
 	return __search_and_open(base, offset, chipset);
 }
 
+static int __open_driver_exact(const char *name, unsigned int chipset)
+{
+	int fd;
+
+	fd = open_device(name, chipset);
+	if (fd != -1)
+		return fd;
+
+	__try_modprobe(chipset);
+
+	return open_device(name, chipset);
+}
+
+/*
+ * A helper to get the first matching card in case a filter is set.
+ * It does all the extra logging around the filters for us.
+ *
+ * @card: pointer to the igt_device_card structure to be filled
+ * when a card is found.
+ *
+ * Returns:
+ * True if card according to the added filter was found,
+ * false othwerwise.
+ */
+static bool __get_the_first_card(struct igt_device_card *card)
+{
+	const char *filter;
+
+	if (igt_device_is_filter_set()) {
+		filter = igt_device_filter_get();
+		igt_info("Looking for devices to open using filter: %s\n", filter);
+
+		if (igt_device_card_match(filter, card)) {
+			igt_info("Filter matched %s | %s\n", card->card, card->render);
+			return true;
+		}
+
+		igt_warn("No card matches the filter!\n");
+	}
+
+	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 in the following order:
+ * 1. when --device arguments are present device scanning will be executed,
+ * then filter argument is used to find matching one.
+ * 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)
 {
+	if (igt_device_is_filter_set()) {
+		bool found;
+		struct igt_device_card card;
+
+		found = __get_the_first_card(&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)
 {
+	if (igt_device_is_filter_set()) {
+		bool found;
+		struct igt_device_card card;
+
+		found = __get_the_first_card(&card);
+
+		if (!found || !strlen(card.render))
+			return -1;
+
+		return __open_driver_exact(card.render, chipset);
+	}
+
 	return __open_driver("/dev/dri/renderD", 128, chipset);
 }
 
diff --git a/lib/drmtest.h b/lib/drmtest.h
index 05eb0860..632c616b 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
@@ -90,6 +91,7 @@ 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);
 
 void gem_quiescent_gpu(int fd);
 
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 99aa0bee..c705be1e 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>
@@ -247,6 +248,9 @@
  *	[Common]
  *	FrameDumpPath=/tmp # The path to dump frames that fail comparison checks
  *
+ *	# Device selection filter
+ *	Device=pci:vendor=8086,card=0;vgem:
+ *
  *	# The following section is used for configuring the Device Under Test.
  *	# It is not mandatory and allows overriding default values.
  *	[DUT]
@@ -312,6 +316,7 @@ enum {
 	OPT_INTERACTIVE_DEBUG,
 	OPT_SKIP_CRC,
 	OPT_TRACE_OOPS,
+	OPT_DEVICE,
 	OPT_HELP = 'h'
 };
 
@@ -328,6 +333,7 @@ static pthread_mutex_t log_buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
 GKeyFile *igt_key_file;
 
 char *igt_frame_dump_path;
+char *igt_rc_device;
 
 static bool stderr_needs_sentinel = false;
 
@@ -657,6 +663,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);
@@ -746,6 +753,31 @@ static void common_init_config(void)
 
 	if (ret != 0)
 		igt_set_autoresume_delay(ret);
+
+	/* Adding filters, order .igtrc, IGT_DEVICE, --device filter */
+	if (igt_device_is_filter_set())
+		igt_debug("Notice: using --device filters:\n");
+	else {
+		if (igt_rc_device) {
+			igt_debug("Notice: using IGT_DEVICE env:\n");
+		} else {
+			igt_rc_device =	g_key_file_get_string(igt_key_file,
+							      "Common",
+							      "Device", &error);
+			g_clear_error(&error);
+			if (igt_rc_device)
+				igt_debug("Notice: using .igtrc "
+					  "Common::Device:\n");
+		}
+		if (igt_rc_device) {
+			igt_device_filter_set(igt_rc_device);
+			free(igt_rc_device);
+			igt_rc_device = NULL;
+		}
+	}
+
+	if (igt_device_is_filter_set())
+		igt_debug("[%s]\n", igt_device_filter_get());
 }
 
 static void common_init_env(void)
@@ -780,6 +812,11 @@ static void common_init_env(void)
 	if (env) {
 		__set_forced_driver(env);
 	}
+
+	env = getenv("IGT_DEVICE");
+	if (env) {
+		igt_rc_device = strdup(env);
+	}
 }
 
 static int common_init(int *argc, char **argv,
@@ -800,6 +837,7 @@ static int common_init(int *argc, char **argv,
 		{"interactive-debug", optional_argument, NULL, OPT_INTERACTIVE_DEBUG},
 		{"skip-crc-compare",  no_argument,       NULL, OPT_SKIP_CRC},
 		{"trace-on-oops",     no_argument,       NULL, OPT_TRACE_OOPS},
+		{"device",            required_argument, NULL, OPT_DEVICE},
 		{"help",              no_argument,       NULL, OPT_HELP},
 		{0, 0, 0, 0}
 	};
@@ -930,6 +968,15 @@ static int common_init(int *argc, char **argv,
 		case OPT_TRACE_OOPS:
 			show_ftrace = true;
 			goto out;
+		case OPT_DEVICE:
+			assert(optarg);
+			/* if set by env IGT_DEVICE we need to free it */
+			if (igt_rc_device) {
+				free(igt_rc_device);
+				igt_rc_device = NULL;
+			}
+			igt_device_filter_set(optarg);
+			break;
 		case OPT_HELP:
 			print_usage(help_str, false);
 			ret = -1;
-- 
2.23.0



More information about the igt-dev mailing list