[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