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

Łukasz Łaguna lukasz.laguna at intel.com
Tue Jul 5 15:05:42 UTC 2022


Add sriov selector to allow pf/vf selection.

Signed-off-by: Łukasz Łaguna <lukasz.laguna at intel.com>
---
 lib/igt_device_scan.c | 149 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)

diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
index a1cee7a4..356064d0 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,116 @@ 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 +1493,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.31.1

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.


More information about the igt-dev mailing list