[igt-dev] [PATCH i-g-t 1/1] lib/igt_device_scan: Add sriov selector

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Mon Jun 27 20:12:23 UTC 2022


From: Łukasz Łaguna <lukasz.laguna at intel.com>

Add sriov selector to allow pf/vf selection.

Signed-off-by: Łukasz Łaguna <lukasz.laguna at intel.com>
Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Cc: Petri Latvala <petri.latvala at intel.com>
---
 lib/igt_device_scan.c | 148 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)

diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
index a1cee7a42a..67ddf56eb2 100644
--- a/lib/igt_device_scan.c
+++ b/lib/igt_device_scan.c
@@ -128,6 +128,35 @@
  *   return you same device regardless the order of enumeration.
  *
  *   Simple syntactic sugar over using the sysfs paths.
+ *
+ * - sriov: select pf or vf
+ *   |[<!-- language="plain" -->
+ *   sriov:[vendor=%04x/name][,device=%04x][,card=%d][,pf=%d][,vf=%d]
+ *   ]|
+ *
+ *   Filter extends pci selector to allow pf/vf selection:
+ *
+ *   |[<!-- language="plain" -->
+ *   sriov:vendor=Intel,device=1234,card=0,vf=2
+ *   ]|
+ *
+ *   When vf is not defined, pf will be selected:
+ *
+ *   |[<!-- language="plain" -->
+ *   sriov:vendor=Intel,device=1234,card=0
+ *   ]|
+ *
+ *   In case a device has more than one pf, you can also select a specific pf
+ *   or a vf associated with a specific pf:
+ *
+ *   |[<!-- language="plain" -->
+ *   sriov:vendor=Intel,device=1234,card=0,pf=1
+ *   ]|
+ *
+ *   |[<!-- language="plain" -->
+ *   sriov:vendor=Intel,device=1234,card=0,pf=1,vf=0
+ *   ]|
+ *
  */
 
 #ifdef DEBUG_DEVICE_SCAN
@@ -1152,6 +1181,8 @@ struct filter {
 		char *slot;
 		char *drm;
 		char *driver;
+		char *pf;
+		char *vf;
 	} data;
 };
 
@@ -1169,6 +1200,8 @@ static void fill_filter_data(struct filter *filter, const char *key, const char
 	__fill_key(slot);
 	__fill_key(drm);
 	__fill_key(driver);
+	__fill_key(pf);
+	__fill_key(vf);
 #undef __fill_key
 
 }
@@ -1315,6 +1348,115 @@ static struct igt_list_head *filter_pci(const struct filter_class *fcls,
 	return &igt_devs.filtered;
 }
 
+static bool is_pf(struct igt_device *dev)
+{
+	if (get_attr(dev, "sriov_numvfs") == NULL)
+		return false;
+
+	return true;
+}
+
+static bool is_vf(struct igt_device *dev)
+{
+	if (get_attr(dev, "physfn") == NULL)
+		return false;
+
+	return true;
+}
+
+/* Find appropriate pci device matching vendor/device/card/pf/vf filter arguments.
+ */
+static struct igt_list_head *filter_sriov(const struct filter_class *fcls,
+					const struct filter *filter)
+{
+	struct igt_device *dev, *dup;
+	int card = -1, pf = -1, vf = -1;
+	char *pf_pci_slot_name = NULL;
+	(void) fcls;
+
+	DBG("filter sriov\n");
+
+	if (filter->data.card) {
+		sscanf(filter->data.card, "%d", &card);
+		if (card < 0) {
+			return &igt_devs.filtered;
+		}
+	} else {
+		card = 0;
+	}
+
+	if (filter->data.pf) {
+		sscanf(filter->data.pf, "%d", &pf);
+		if (pf < 0) {
+			return &igt_devs.filtered;
+		}
+	} else {
+		pf = 0;
+	}
+
+	if (filter->data.vf) {
+		sscanf(filter->data.vf, "%d", &vf);
+		if (vf < 0) {
+			return &igt_devs.filtered;
+		}
+	}
+
+	igt_list_for_each_entry(dev, &igt_devs.all, link) {
+		if (!is_pci_subsystem(dev))
+			continue;
+
+		/* Skip if 'vendor' doesn't match (hex or name) */
+		if (filter->data.vendor && !is_vendor_matched(dev, filter->data.vendor))
+			continue;
+
+		/* Skip if 'device' doesn't match */
+		if (filter->data.device && strcasecmp(filter->data.device, dev->device))
+			continue;
+
+		/* We get n-th card */
+		if (!card) {
+			if (!pf) {
+				if (is_pf(dev))
+					pf_pci_slot_name = dev->pci_slot_name;
+
+				/* vf parameter was not passed, get pf */
+				if (vf < 0) {
+					if (!is_pf(dev))
+						continue;
+
+					dup = duplicate_device(dev);
+					igt_list_add_tail(&dup->link, &igt_devs.filtered);
+					break;
+				} else {
+					/* Skip if vf is not associated with defined pf */
+					if (!strequal(get_attr(dev, "physfn"), pf_pci_slot_name))
+						continue;
+
+					if (!vf) {
+						if (!is_vf(dev))
+							continue;
+
+						dup = duplicate_device(dev);
+						igt_list_add_tail(&dup->link, &igt_devs.filtered);
+						break;
+					}
+					if (is_vf(dev)) {
+						vf--;
+						continue;
+					}
+				}
+			}
+			if (is_pf(dev)) {
+				pf--;
+				continue;
+			}
+		}
+		card--;
+	}
+
+	return &igt_devs.filtered;
+}
+
 static bool sys_path_valid(const struct filter_class *fcls,
 			   const struct filter *filter)
 {
@@ -1350,6 +1492,12 @@ static struct filter_class filter_definition_list[] = {
 		.help = "pci:[vendor=%04x/name][,device=%04x][,card=%d] | [slot=%04x:%02x:%02x.%x]",
 		.detail = "vendor is hex number or vendor name\n",
 	},
+	{
+		.name = "sriov",
+		.filter_function = filter_sriov,
+		.help = "sriov:[vendor=%04x/name][,device=%04x][,card=%d][,pf=%d][,vf=%d]",
+		.detail = "find pf or vf\n",
+	},
 	{
 		.name = NULL,
 	},
-- 
2.34.1



More information about the igt-dev mailing list