[igt-dev] [PATCH i-g-t 1/2] lib: Support multiple filters

Arkadiusz Hiler arkadiusz.hiler at intel.com
Wed Apr 29 15:49:01 UTC 2020


This patch brings back support for multiple filters that was in the
original series by Zbyszek.

We can now take multiple, semicolon separated filters. Right now the
tests are using only the first filter.

Cc: Petri Latvala <petri.latvala at intel.com>
Cc: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler at intel.com>
---
 lib/drmtest.c          |  8 ++--
 lib/igt_core.c         | 16 ++++----
 lib/igt_device_scan.c  | 87 +++++++++++++++++++++++++++++++-----------
 lib/igt_device_scan.h  |  8 ++--
 tests/core_hotunplug.c |  3 +-
 5 files changed, 83 insertions(+), 39 deletions(-)

diff --git a/lib/drmtest.c b/lib/drmtest.c
index 1fc39925..7b2fd337 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -324,8 +324,8 @@ 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();
+	if (igt_device_filter_count() > 0) {
+		filter = igt_device_filter_get(0);
 		igt_info("Looking for devices to open using filter: %s\n", filter);
 
 		if (igt_device_card_match(filter, card)) {
@@ -354,7 +354,7 @@ static bool __get_the_first_card(struct igt_device_card *card)
  */
 int __drm_open_driver(int chipset)
 {
-	if (igt_device_is_filter_set()) {
+	if (igt_device_filter_count() > 0) {
 		bool found;
 		struct igt_device_card card;
 
@@ -371,7 +371,7 @@ int __drm_open_driver(int chipset)
 
 int __drm_open_driver_render(int chipset)
 {
-	if (igt_device_is_filter_set()) {
+	if (igt_device_filter_count() > 0) {
 		bool found;
 		struct igt_device_card card;
 
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 3f7b9f68..44705d10 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -249,7 +249,7 @@
  *	FrameDumpPath=/tmp # The path to dump frames that fail comparison checks
  *
  *	# Device selection filter
- *	Device=pci:vendor=8086,card=0;vgem:
+ *	Device=pci:vendor=8086,card=0;sys:/sys/devices/platform/vgem
  *
  *	# The following section is used for configuring the Device Under Test.
  *	# It is not mandatory and allows overriding default values.
@@ -685,7 +685,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"
+		   "  --device filters\n"
 		   "  --version\n"
 		   "  --help|-h\n");
 	if (help_str)
@@ -778,7 +778,7 @@ static void common_init_config(void)
 		igt_set_autoresume_delay(ret);
 
 	/* Adding filters, order .igtrc, IGT_DEVICE, --device filter */
-	if (igt_device_is_filter_set())
+	if (igt_device_filter_count() > 0)
 		igt_debug("Notice: using --device filters:\n");
 	else {
 		if (igt_rc_device) {
@@ -793,14 +793,16 @@ static void common_init_config(void)
 					  "Common::Device:\n");
 		}
 		if (igt_rc_device) {
-			igt_device_filter_set(igt_rc_device);
+			igt_device_filter_add(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());
+	if (igt_device_filter_count() > 0) {
+		for (int i = 0; i < igt_device_filter_count(); i++)
+			igt_debug("[%s]\n", igt_device_filter_get(i));
+	}
 }
 
 static void common_init_env(void)
@@ -999,7 +1001,7 @@ static int common_init(int *argc, char **argv,
 				free(igt_rc_device);
 				igt_rc_device = NULL;
 			}
-			igt_device_filter_set(optarg);
+			igt_device_filter_add(optarg);
 			break;
 		case OPT_VERSION:
 			print_version();
diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
index 30a9704a..601d6fb0 100644
--- a/lib/igt_device_scan.c
+++ b/lib/igt_device_scan.c
@@ -1014,16 +1014,21 @@ void igt_device_print_filter_types(void)
 	}
 }
 
-static char *device_filter;
+struct device_filter {
+	char filter[NAME_MAX];
+	struct igt_list_head link;
+};
+
+static IGT_LIST_HEAD(device_filters);
 
 /**
- * igt_device_is_filter_set
+ * igt_device_filter_count
  *
- * Returns whether we have a filter set.
+ * Returns number of filters collected in the filter list.
  */
-bool igt_device_is_filter_set(void)
+int igt_device_filter_count(void)
 {
-	return device_filter != NULL;
+	return igt_list_length(&device_filters);
 }
 
 /* Check does filter is valid. It checks:
@@ -1054,43 +1059,79 @@ static bool is_filter_valid(const char *fstr)
 }
 
 /**
- * igt_device_filter_set
- * @filter: filter that should be set globally
+ * igt_device_filter_add
+ * @filters: filter(s) to be stored in filter array
+ *
+ * Function allows passing single or more filters within one string. This is
+ * for CI when it can extract filter from environment variable (and it must
+ * be single string). So if @filter contains semicolon ';' it treats
+ * each part as separate filter and adds to the filter array.
+ *
+ * Returns number of filters added to filter array. Can be greater than
+ * 1 if @filters contains more than one filter separated by semicolon.
  */
-void igt_device_filter_set(const char *filter)
+int igt_device_filter_add(const char *filters)
 {
-	if (!is_filter_valid(filter)) {
-		igt_warn("Invalid filter: %s\n", filter);
-		return;
+	char *dup, *dup_orig, *filter;
+	int count = 0;
+
+	dup = strdup(filters);
+	dup_orig = dup;
+
+	while ((filter = strsep(&dup, ";"))) {
+		bool is_valid = is_filter_valid(filter);
+		igt_warn_on(!is_valid);
+		if (is_valid) {
+			struct device_filter *df = malloc(sizeof(*df));
+			strncpy(df->filter, filter, sizeof(df->filter)-1);
+			igt_list_add_tail(&df->link, &device_filters);
+			count++;
+		}
 	}
 
-	if (device_filter != NULL)
-		free(device_filter);
+	free(dup_orig);
 
-	device_filter = strdup(filter);
+	return count;
 }
 
 /**
- * igt_device_filter_free
+ * igt_device_filter_free_all
  *
- * Free the filter that we store internally, effectively unsetting it.
+ * Free all filters within array.
  */
-void igt_device_filter_free(void)
+void igt_device_filter_free_all(void)
 {
-	if (device_filter != NULL)
-		free(device_filter);
+	struct device_filter *filter, *tmp;
 
-	device_filter = NULL;
+	igt_list_for_each_entry_safe(filter, tmp, &device_filters, link) {
+		igt_list_del(&filter->link);
+		free(filter);
+	}
 }
 
 /**
  * igt_device_filter_get
+ * @num: Number of filter from filter array
  *
- * Returns filter string or NULL if not set
+ * Returns filter string or NULL if @num is out of range of filter array.
  */
-const char *igt_device_filter_get(void)
+const char *igt_device_filter_get(int num)
 {
-	return device_filter;
+	struct device_filter *filter;
+	int i = 0;
+
+	if (num < 0)
+		return NULL;
+
+
+	igt_list_for_each_entry(filter, &device_filters, link) {
+		if (i == num)
+			return filter->filter;
+		i++;
+	}
+
+
+	return NULL;
 }
 
 static bool igt_device_filter_apply(const char *fstr)
diff --git a/lib/igt_device_scan.h b/lib/igt_device_scan.h
index 44c99dec..24eafe62 100644
--- a/lib/igt_device_scan.h
+++ b/lib/igt_device_scan.h
@@ -50,10 +50,10 @@ void igt_device_print_filter_types(void);
  * IGT can store/retrieve filters passed by user using '--device' args.
  */
 
-bool igt_device_is_filter_set(void);
-void igt_device_filter_set(const char *filter);
-void igt_device_filter_free(void);
-const char *igt_device_filter_get(void);
+int igt_device_filter_count(void);
+int igt_device_filter_add(const char *filter);
+void igt_device_filter_free_all(void);
+const char *igt_device_filter_get(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);
diff --git a/tests/core_hotunplug.c b/tests/core_hotunplug.c
index f9cfc8c3..ded53fd5 100644
--- a/tests/core_hotunplug.c
+++ b/tests/core_hotunplug.c
@@ -167,7 +167,8 @@ static void set_filter_from_device(int fd)
 	strncat(path, "/device", PATH_MAX - strlen(path));
 	igt_assert(realpath(path, dst));
 
-	igt_device_filter_set(filter);
+	igt_device_filter_free_all();
+	igt_device_filter_add(filter);
 }
 
 /* Subtests */
-- 
2.25.2



More information about the igt-dev mailing list