* : ├── 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)
.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)
{
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;
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);