[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