summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorŁukasz Łaguna <lukasz.laguna@intel.com>2022-07-05 17:05:42 +0200
committerZbigniew Kempczyński <zbigniew.kempczynski@intel.com>2022-07-07 06:38:03 +0200
commit8aad1e6351d7932b33d4b460d863252eae1123b2 (patch)
tree5026e83000fc3bcbf93f4ebbdb89d00ccea6fe46
parent6850e9fd9287a8d39ff0c4d9dc413767022342c1 (diff)
lib/igt_device_scan: Add sriov selector
Add sriov selector to allow pf/vf selection. Signed-off-by: Łukasz Łaguna <lukasz.laguna@intel.com> Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
-rw-r--r--lib/igt_device_scan.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
index b51275e4..5d98381f 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)
{
@@ -1351,6 +1494,12 @@ static struct filter_class filter_definition_list[] = {
.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,
},
};