[PATCH 3/4] drm/xe/pf: Add max_vfs configfs attribute to control PF mode

Michal Wajdeczko michal.wajdeczko at intel.com
Tue Jul 15 18:14:17 UTC 2025


In addition to max_vfs modparam, add max_vfs configfs attribute
to allow SR-IOV PF mode configuration on the per-device level.
Default config value is still based on the modparam value.

Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
Cc: Lucas De Marchi <lucas.demarchi at intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi at intel.com>
---
 drivers/gpu/drm/xe/xe_configfs.c | 89 +++++++++++++++++++++++++++++++-
 drivers/gpu/drm/xe/xe_configfs.h | 11 ++++
 drivers/gpu/drm/xe/xe_sriov_pf.c |  4 +-
 3 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_configfs.c b/drivers/gpu/drm/xe/xe_configfs.c
index 8ec1ff1e4e80..6c40efd1aa2a 100644
--- a/drivers/gpu/drm/xe/xe_configfs.c
+++ b/drivers/gpu/drm/xe/xe_configfs.c
@@ -77,6 +77,24 @@
  * available for migrations, but it's disabled. This is intended for debugging
  * purposes only.
  *
+ * Max Virtual Functions:
+ * ----------------------
+ *
+ * Configure SR-IOV PF mode on supported cards. This setting only takes effect
+ * when probing the device. Allows to limit number of Virtual Functions that
+ * can be managed by the PF driver, value 0 (no VFs) disables the PF mode.
+ * Default max_vfs config value is taken from the max_vfs modparam.
+ *
+ * Example to enable PF mode (will support up to 7 VFs)::
+ *
+ *	# echo 7 > /sys/kernel/config/xe/0000:00:02.0/max_vfs
+ *	# echo 0000:00:02.0 > /sys/bus/pci/drivers/xe/bind
+ *
+ * Example to disable PF mode (will always run as native)::
+ *
+ *	# echo 0 > /sys/kernel/config/xe/0000:00:02.0/max_vfs
+ *	# echo 0000:00:02.0 > /sys/bus/pci/drivers/xe/bind
+ *
  * Remove devices
  * ==============
  *
@@ -90,7 +108,9 @@ struct xe_config_device {
 
 	bool survivability_mode;
 	u64 engines_allowed;
-
+#ifdef CONFIG_PCI_IOV
+	unsigned int max_vfs;
+#endif
 	/* protects attributes */
 	struct mutex lock;
 };
@@ -226,12 +246,50 @@ static ssize_t engines_allowed_store(struct config_item *item, const char *page,
 	return len;
 }
 
+#ifdef CONFIG_PCI_IOV
+static ssize_t max_vfs_show(struct config_item *item, char *page)
+{
+	struct xe_config_device *dev = to_xe_config_device(item);
+
+	if (dev->max_vfs == UINT_MAX)
+		return sprintf(page, "%s\n", "unlimited");
+	else
+		return sprintf(page, "%u\n", dev->max_vfs);
+}
+
+static ssize_t max_vfs_store(struct config_item *item, const char *page, size_t len)
+{
+	struct xe_config_device *dev = to_xe_config_device(item);
+	unsigned int max_vfs;
+	int ret;
+
+	ret = kstrtouint(page, 0, &max_vfs);
+	if (ret) {
+		if (!sysfs_streq(page, "unlimited"))
+			return ret;
+		max_vfs = ~0;
+	}
+
+	mutex_lock(&dev->lock);
+	dev->max_vfs = max_vfs;
+	mutex_unlock(&dev->lock);
+
+	return len;
+}
+#endif
+
 CONFIGFS_ATTR(, survivability_mode);
 CONFIGFS_ATTR(, engines_allowed);
+#ifdef CONFIG_PCI_IOV
+CONFIGFS_ATTR(, max_vfs);
+#endif
 
 static struct configfs_attribute *xe_config_device_attrs[] = {
 	&attr_survivability_mode,
 	&attr_engines_allowed,
+#ifdef CONFIG_PCI_IOV
+	&attr_max_vfs,
+#endif
 	NULL,
 };
 
@@ -275,6 +333,9 @@ static struct config_group *xe_config_make_device_group(struct config_group *gro
 
 	/* Default values */
 	dev->engines_allowed = U64_MAX;
+#ifdef CONFIG_PCI_IOV
+	dev->max_vfs = xe_modparam.max_vfs;
+#endif
 
 	config_group_init_type_name(&dev->group, name, &xe_config_device_type);
 
@@ -386,6 +447,32 @@ u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev)
 	return engines_allowed;
 }
 
+#ifdef CONFIG_PCI_IOV
+/**
+ * xe_configfs_get_max_vfs() - Get number of VFs that could be managed
+ * @pdev: the &pci_dev device
+ *
+ * Find the configfs group that belongs to the PCI device and return maximum
+ * number of Virtual Functions (VFs) that could be managed by this device.
+ * If configfs group is not present, use value of max_vfs module parameter.
+ *
+ * Return: maximum number of VFs that could be managed.
+ */
+unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev)
+{
+	struct xe_config_device *dev = configfs_find_group(pdev);
+	unsigned int max_vfs;
+
+	if (!dev)
+		return xe_modparam.max_vfs;
+
+	max_vfs = dev->max_vfs;
+	config_item_put(&dev->group.cg_item);
+
+	return max_vfs;
+}
+#endif
+
 int __init xe_configfs_init(void)
 {
 	struct config_group *root = &xe_configfs.su_group;
diff --git a/drivers/gpu/drm/xe/xe_configfs.h b/drivers/gpu/drm/xe/xe_configfs.h
index fb8764008089..6d7accdc3732 100644
--- a/drivers/gpu/drm/xe/xe_configfs.h
+++ b/drivers/gpu/drm/xe/xe_configfs.h
@@ -8,6 +8,8 @@
 #include <linux/limits.h>
 #include <linux/types.h>
 
+#include "xe_module.h"
+
 struct pci_dev;
 
 #if IS_ENABLED(CONFIG_CONFIGFS_FS)
@@ -16,12 +18,21 @@ void xe_configfs_exit(void);
 bool xe_configfs_get_survivability_mode(struct pci_dev *pdev);
 void xe_configfs_clear_survivability_mode(struct pci_dev *pdev);
 u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev);
+#ifdef CONFIG_PCI_IOV
+unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev);
+#endif
 #else
 static inline int xe_configfs_init(void) { return 0; }
 static inline void xe_configfs_exit(void) { }
 static inline bool xe_configfs_get_survivability_mode(struct pci_dev *pdev) { return false; }
 static inline void xe_configfs_clear_survivability_mode(struct pci_dev *pdev) { }
 static inline u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev) { return U64_MAX; }
+#ifdef CONFIG_PCI_IOV
+static inline unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev)
+{
+	return xe_modparam.max_vfs;
+}
+#endif
 #endif
 
 #endif
diff --git a/drivers/gpu/drm/xe/xe_sriov_pf.c b/drivers/gpu/drm/xe/xe_sriov_pf.c
index afbdd894bd6e..3e8344bf772b 100644
--- a/drivers/gpu/drm/xe/xe_sriov_pf.c
+++ b/drivers/gpu/drm/xe/xe_sriov_pf.c
@@ -8,8 +8,8 @@
 #include <drm/drm_managed.h>
 
 #include "xe_assert.h"
+#include "xe_configfs.h"
 #include "xe_device.h"
-#include "xe_module.h"
 #include "xe_sriov.h"
 #include "xe_sriov_pf.h"
 #include "xe_sriov_pf_helpers.h"
@@ -18,7 +18,7 @@
 
 static unsigned int wanted_max_vfs(struct xe_device *xe)
 {
-	return xe_modparam.max_vfs;
+	return xe_configfs_get_max_vfs(to_pci_dev(xe->drm.dev));
 }
 
 static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
-- 
2.47.1



More information about the Intel-xe mailing list