summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorMichal Wajdeczko <michal.wajdeczko@intel.com>2025-10-01 01:35:21 +0200
committerMichal Wajdeczko <michal.wajdeczko@intel.com>2025-10-02 23:58:31 +0200
commit5b7451fdd703dc582aac102bc4052b9bea501dfe (patch)
treebefca455d2d848b3429712e9ea96e5a860f596a7 /drivers/gpu
parentac43294e8ec2227eb5fa3c0576f9ec07742eabb2 (diff)
drm/xe/pf: Expose VF control operations over debugfs
To allow the user to control the activity of individual VFs, expose basic VF control operations (pause, resume, stop, reset) over the debugfs as write-only files: /sys/kernel/debug/dri/BDF/sriov/ ├── vf1 │ ├── pause │ ├── reset │ ├── resume │ ├── stop │ : ├── vf2 : : Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Michał Winiarski <michal.winiarski@intel.com> Link: https://lore.kernel.org/r/20250930233525.201263-4-michal.wajdeczko@intel.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
index 2ab0b1f4818a..97636ed86fb8 100644
--- a/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
@@ -8,13 +8,41 @@
#include "xe_device.h"
#include "xe_device_types.h"
+#include "xe_pm.h"
#include "xe_sriov_pf.h"
+#include "xe_sriov_pf_control.h"
#include "xe_sriov_pf_debugfs.h"
#include "xe_sriov_pf_helpers.h"
#include "xe_sriov_pf_service.h"
#include "xe_sriov_printk.h"
#include "xe_tile_sriov_pf_debugfs.h"
+/*
+ * /sys/kernel/debug/dri/BDF/
+ * ├── sriov # d_inode->i_private = (xe_device*)
+ * │ ├── pf # d_inode->i_private = (xe_device*)
+ * │ ├── vf1 # d_inode->i_private = VFID(1)
+ * : :
+ * │ ├── vfN # d_inode->i_private = VFID(N)
+ */
+
+static void *extract_priv(struct dentry *d)
+{
+ return d->d_inode->i_private;
+}
+
+static struct xe_device *extract_xe(struct dentry *d)
+{
+ return extract_priv(d->d_parent);
+}
+
+static unsigned int extract_vfid(struct dentry *d)
+{
+ void *p = extract_priv(d);
+
+ return p == extract_xe(d) ? PFID : (uintptr_t)p;
+}
+
static int simple_show(struct seq_file *m, void *data)
{
struct drm_printer p = drm_seq_file_printer(m);
@@ -39,6 +67,70 @@ static void pf_populate_pf(struct xe_device *xe, struct dentry *pfdent)
drm_debugfs_create_files(debugfs_list, ARRAY_SIZE(debugfs_list), pfdent, minor);
}
+/*
+ * /sys/kernel/debug/dri/BDF/
+ * ├── sriov
+ * │ ├── vf1
+ * │ │ ├── pause
+ * │ │ ├── reset
+ * │ │ ├── resume
+ * │ │ ├── stop
+ * │ │ :
+ * │ ├── vf2
+ * │ │ ├── ...
+ */
+
+static ssize_t from_file_write_to_vf_call(struct file *file, const char __user *userbuf,
+ size_t count, loff_t *ppos,
+ int (*call)(struct xe_device *, unsigned int))
+{
+ struct dentry *dent = file_dentry(file)->d_parent;
+ struct xe_device *xe = extract_xe(dent);
+ unsigned int vfid = extract_vfid(dent);
+ bool yes;
+ int ret;
+
+ if (*ppos)
+ return -EINVAL;
+ ret = kstrtobool_from_user(userbuf, count, &yes);
+ if (ret < 0)
+ return ret;
+ if (yes) {
+ xe_pm_runtime_get(xe);
+ ret = call(xe, vfid);
+ xe_pm_runtime_put(xe);
+ }
+ if (ret < 0)
+ return ret;
+ return count;
+}
+
+#define DEFINE_VF_CONTROL_ATTRIBUTE(OP) \
+static int OP##_show(struct seq_file *s, void *unused) \
+{ \
+ return 0; \
+} \
+static ssize_t OP##_write(struct file *file, const char __user *userbuf, \
+ size_t count, loff_t *ppos) \
+{ \
+ return from_file_write_to_vf_call(file, userbuf, count, ppos, \
+ xe_sriov_pf_control_##OP); \
+} \
+DEFINE_SHOW_STORE_ATTRIBUTE(OP)
+
+DEFINE_VF_CONTROL_ATTRIBUTE(pause_vf);
+DEFINE_VF_CONTROL_ATTRIBUTE(resume_vf);
+DEFINE_VF_CONTROL_ATTRIBUTE(stop_vf);
+DEFINE_VF_CONTROL_ATTRIBUTE(reset_vf);
+
+static void pf_populate_vf(struct xe_device *xe, struct dentry *vfdent)
+{
+ debugfs_create_file("pause", 0200, vfdent, xe, &pause_vf_fops);
+ debugfs_create_file("resume", 0200, vfdent, xe, &resume_vf_fops);
+ debugfs_create_file("stop", 0200, vfdent, xe, &stop_vf_fops);
+ debugfs_create_file("reset", 0200, vfdent, xe, &reset_vf_fops);
+}
+
static void pf_populate_with_tiles(struct xe_device *xe, struct dentry *dent, unsigned int vfid)
{
struct xe_tile *tile;
@@ -103,6 +195,7 @@ void xe_sriov_pf_debugfs_register(struct xe_device *xe, struct dentry *root)
return;
vfdent->d_inode->i_private = (void *)(uintptr_t)VFID(n);
+ pf_populate_vf(xe, vfdent);
pf_populate_with_tiles(xe, vfdent, VFID(n));
}
}