Commit f474911f authored by Daniele Ceraolo Spurio's avatar Daniele Ceraolo Spurio
Browse files

drm/xe/pf: Add debugfs to set EQ and PT for scheduler groups



Debugfs files are added to allow a user to provide a comma-separated list
of values to assign to each group for each VF.

Signed-off-by: default avatarDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: default avatarMichal Wajdeczko <michal.wajdeczko@intel.com>
Link: https://patch.msgid.link/20251218223846.1146344-26-daniele.ceraolospurio@intel.com
parent be451812
Loading
Loading
Loading
Loading
+111 −1
Original line number Diff line number Diff line
@@ -163,10 +163,18 @@ static void pf_add_policy_attrs(struct xe_gt *gt, struct dentry *parent)
 *          :   ├── tile0
 *              :   ├── gt0
 *                  :   ├── sched_groups_mode
 *                      ├── sched_groups_exec_quantums_ms
 *                      ├── sched_groups_preempt_timeout_us
 *                      ├── sched_groups
 *                      :   ├── group0
 *                          :
 *                          └── groupN
 *          :               └── groupN
 *          ├── vf1
 *          :   ├── tile0
 *              :   ├── gt0
 *                  :   ├── sched_groups_exec_quantums_ms
 *                      ├── sched_groups_preempt_timeout_us
 *                      :
 */

static const char *sched_group_mode_to_string(enum xe_sriov_sched_group_modes mode)
@@ -261,6 +269,102 @@ static const struct file_operations sched_groups_fops = {
	.release = single_release,
};

static int sched_groups_config_show(struct seq_file *m, void *data,
				    void (*get)(struct xe_gt *, unsigned int, u32 *, u32))
{
	struct drm_printer p = drm_seq_file_printer(m);
	unsigned int vfid = extract_vfid(m->private);
	struct xe_gt *gt = extract_gt(m->private);
	u32 values[GUC_MAX_SCHED_GROUPS];
	bool first = true;
	u8 group;

	get(gt, vfid, values, ARRAY_SIZE(values));

	for (group = 0; group < ARRAY_SIZE(values); group++) {
		drm_printf(&p, "%s%u", first ? "" : ",", values[group]);

		first = false;
	}

	drm_puts(&p, "\n");

	return 0;
}

static ssize_t sched_groups_config_write(struct file *file, const char __user *ubuf,
					 size_t size, loff_t *pos,
					 int (*set)(struct xe_gt *, unsigned int, u32 *, u32))
{
	struct dentry *parent = file_inode(file)->i_private;
	unsigned int vfid = extract_vfid(parent);
	struct xe_gt *gt = extract_gt(parent);
	u32 values[GUC_MAX_SCHED_GROUPS];
	int *input __free(kfree) = NULL;
	u32 count;
	int ret;
	int i;

	if (*pos)
		return -ESPIPE;

	if (!size)
		return -ENODATA;

	ret = parse_int_array_user(ubuf, min(size, GUC_MAX_SCHED_GROUPS * sizeof(u32)), &input);
	if (ret)
		return ret;

	count = input[0];
	if (count > GUC_MAX_SCHED_GROUPS)
		return -E2BIG;

	for (i = 0; i < count; i++) {
		if (input[i + 1] < 0 || input[i + 1] > S32_MAX)
			return -EINVAL;

		values[i] = input[i + 1];
	}

	guard(xe_pm_runtime)(gt_to_xe(gt));
	ret = set(gt, vfid, values, count);

	return ret < 0 ? ret : size;
}

#define DEFINE_SRIOV_GT_GRP_CFG_DEBUGFS_ATTRIBUTE(CONFIG)			\
static int sched_groups_##CONFIG##_show(struct seq_file *m, void *data)		\
{										\
	return sched_groups_config_show(m, data,				\
					xe_gt_sriov_pf_config_get_groups_##CONFIG); \
}										\
										\
static int sched_groups_##CONFIG##_open(struct inode *inode, struct file *file)	\
{										\
	return single_open(file, sched_groups_##CONFIG##_show,			\
			   inode->i_private);					\
}										\
										\
static ssize_t sched_groups_##CONFIG##_write(struct file *file,			\
					      const char __user *ubuf,		\
					      size_t size, loff_t *pos)		\
{										\
	return sched_groups_config_write(file, ubuf, size, pos,			\
					 xe_gt_sriov_pf_config_set_groups_##CONFIG); \
}										\
										\
static const struct file_operations sched_groups_##CONFIG##_fops = {		\
	.owner = THIS_MODULE,							\
	.open = sched_groups_##CONFIG##_open,					\
	.read = seq_read,							\
	.llseek = seq_lseek,							\
	.write = sched_groups_##CONFIG##_write,					\
	.release = single_release,						\
}

DEFINE_SRIOV_GT_GRP_CFG_DEBUGFS_ATTRIBUTE(exec_quantums);
DEFINE_SRIOV_GT_GRP_CFG_DEBUGFS_ATTRIBUTE(preempt_timeouts);

static ssize_t sched_group_engines_read(struct file *file, char __user *buf,
					size_t count, loff_t *ppos)
{
@@ -322,6 +426,11 @@ static void pf_add_sched_groups(struct xe_gt *gt, struct dentry *parent, unsigne
	if (!xe_sriov_gt_pf_policy_has_sched_groups_support(gt))
		return;

	debugfs_create_file("sched_groups_exec_quantums_ms", 0644, parent, parent,
			    &sched_groups_exec_quantums_fops);
	debugfs_create_file("sched_groups_preempt_timeouts_us", 0644, parent, parent,
			    &sched_groups_preempt_timeouts_fops);

	if (vfid != PFID)
		return;

@@ -702,6 +811,7 @@ static void pf_populate_gt(struct xe_gt *gt, struct dentry *dent, unsigned int v

	if (vfid) {
		pf_add_config_attrs(gt, dent, vfid);
		pf_add_sched_groups(gt, dent, vfid);

		debugfs_create_file("control", 0600, dent, NULL, &control_ops);