sched/debug: Add support to change sched_ext server params

When a sched_ext server is loaded, tasks in the fair class are
automatically moved to the sched_ext class. Add support to modify the
ext server parameters similar to how the fair server parameters are
modified.

Re-use common code between ext and fair servers as needed.

Co-developed-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juri Lelli <juri.lelli@redhat.com>
Tested-by: Christian Loehle <christian.loehle@arm.com>
Link: https://patch.msgid.link/20260126100050.3854740-6-arighi@nvidia.com
This commit is contained in:
Joel Fernandes 2026-01-26 10:59:03 +01:00 committed by Peter Zijlstra
parent cd959a3562
commit 76d12132ba

View file

@ -330,14 +330,16 @@ enum dl_param {
DL_PERIOD,
};
static unsigned long fair_server_period_max = (1UL << 22) * NSEC_PER_USEC; /* ~4 seconds */
static unsigned long fair_server_period_min = (100) * NSEC_PER_USEC; /* 100 us */
static unsigned long dl_server_period_max = (1UL << 22) * NSEC_PER_USEC; /* ~4 seconds */
static unsigned long dl_server_period_min = (100) * NSEC_PER_USEC; /* 100 us */
static ssize_t sched_fair_server_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos, enum dl_param param)
static ssize_t sched_server_write_common(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos, enum dl_param param,
void *server)
{
long cpu = (long) ((struct seq_file *) filp->private_data)->private;
struct rq *rq = cpu_rq(cpu);
struct sched_dl_entity *dl_se = (struct sched_dl_entity *)server;
u64 runtime, period;
int retval = 0;
size_t err;
@ -350,8 +352,8 @@ static ssize_t sched_fair_server_write(struct file *filp, const char __user *ubu
scoped_guard (rq_lock_irqsave, rq) {
bool is_active;
runtime = rq->fair_server.dl_runtime;
period = rq->fair_server.dl_period;
runtime = dl_se->dl_runtime;
period = dl_se->dl_period;
switch (param) {
case DL_RUNTIME:
@ -367,25 +369,25 @@ static ssize_t sched_fair_server_write(struct file *filp, const char __user *ubu
}
if (runtime > period ||
period > fair_server_period_max ||
period < fair_server_period_min) {
period > dl_server_period_max ||
period < dl_server_period_min) {
return -EINVAL;
}
is_active = dl_server_active(&rq->fair_server);
is_active = dl_server_active(dl_se);
if (is_active) {
update_rq_clock(rq);
dl_server_stop(&rq->fair_server);
dl_server_stop(dl_se);
}
retval = dl_server_apply_params(&rq->fair_server, runtime, period, 0);
retval = dl_server_apply_params(dl_se, runtime, period, 0);
if (!runtime)
printk_deferred("Fair server disabled in CPU %d, system may crash due to starvation.\n",
cpu_of(rq));
printk_deferred("%s server disabled in CPU %d, system may crash due to starvation.\n",
server == &rq->fair_server ? "Fair" : "Ext", cpu_of(rq));
if (is_active && runtime)
dl_server_start(&rq->fair_server);
dl_server_start(dl_se);
if (retval < 0)
return retval;
@ -395,36 +397,42 @@ static ssize_t sched_fair_server_write(struct file *filp, const char __user *ubu
return cnt;
}
static size_t sched_fair_server_show(struct seq_file *m, void *v, enum dl_param param)
static size_t sched_server_show_common(struct seq_file *m, void *v, enum dl_param param,
void *server)
{
unsigned long cpu = (unsigned long) m->private;
struct rq *rq = cpu_rq(cpu);
struct sched_dl_entity *dl_se = (struct sched_dl_entity *)server;
u64 value;
switch (param) {
case DL_RUNTIME:
value = rq->fair_server.dl_runtime;
value = dl_se->dl_runtime;
break;
case DL_PERIOD:
value = rq->fair_server.dl_period;
value = dl_se->dl_period;
break;
}
seq_printf(m, "%llu\n", value);
return 0;
}
static ssize_t
sched_fair_server_runtime_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
return sched_fair_server_write(filp, ubuf, cnt, ppos, DL_RUNTIME);
long cpu = (long) ((struct seq_file *) filp->private_data)->private;
struct rq *rq = cpu_rq(cpu);
return sched_server_write_common(filp, ubuf, cnt, ppos, DL_RUNTIME,
&rq->fair_server);
}
static int sched_fair_server_runtime_show(struct seq_file *m, void *v)
{
return sched_fair_server_show(m, v, DL_RUNTIME);
unsigned long cpu = (unsigned long) m->private;
struct rq *rq = cpu_rq(cpu);
return sched_server_show_common(m, v, DL_RUNTIME, &rq->fair_server);
}
static int sched_fair_server_runtime_open(struct inode *inode, struct file *filp)
@ -440,16 +448,57 @@ static const struct file_operations fair_server_runtime_fops = {
.release = single_release,
};
#ifdef CONFIG_SCHED_CLASS_EXT
static ssize_t
sched_ext_server_runtime_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
long cpu = (long) ((struct seq_file *) filp->private_data)->private;
struct rq *rq = cpu_rq(cpu);
return sched_server_write_common(filp, ubuf, cnt, ppos, DL_RUNTIME,
&rq->ext_server);
}
static int sched_ext_server_runtime_show(struct seq_file *m, void *v)
{
unsigned long cpu = (unsigned long) m->private;
struct rq *rq = cpu_rq(cpu);
return sched_server_show_common(m, v, DL_RUNTIME, &rq->ext_server);
}
static int sched_ext_server_runtime_open(struct inode *inode, struct file *filp)
{
return single_open(filp, sched_ext_server_runtime_show, inode->i_private);
}
static const struct file_operations ext_server_runtime_fops = {
.open = sched_ext_server_runtime_open,
.write = sched_ext_server_runtime_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif /* CONFIG_SCHED_CLASS_EXT */
static ssize_t
sched_fair_server_period_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
return sched_fair_server_write(filp, ubuf, cnt, ppos, DL_PERIOD);
long cpu = (long) ((struct seq_file *) filp->private_data)->private;
struct rq *rq = cpu_rq(cpu);
return sched_server_write_common(filp, ubuf, cnt, ppos, DL_PERIOD,
&rq->fair_server);
}
static int sched_fair_server_period_show(struct seq_file *m, void *v)
{
return sched_fair_server_show(m, v, DL_PERIOD);
unsigned long cpu = (unsigned long) m->private;
struct rq *rq = cpu_rq(cpu);
return sched_server_show_common(m, v, DL_PERIOD, &rq->fair_server);
}
static int sched_fair_server_period_open(struct inode *inode, struct file *filp)
@ -465,6 +514,40 @@ static const struct file_operations fair_server_period_fops = {
.release = single_release,
};
#ifdef CONFIG_SCHED_CLASS_EXT
static ssize_t
sched_ext_server_period_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
long cpu = (long) ((struct seq_file *) filp->private_data)->private;
struct rq *rq = cpu_rq(cpu);
return sched_server_write_common(filp, ubuf, cnt, ppos, DL_PERIOD,
&rq->ext_server);
}
static int sched_ext_server_period_show(struct seq_file *m, void *v)
{
unsigned long cpu = (unsigned long) m->private;
struct rq *rq = cpu_rq(cpu);
return sched_server_show_common(m, v, DL_PERIOD, &rq->ext_server);
}
static int sched_ext_server_period_open(struct inode *inode, struct file *filp)
{
return single_open(filp, sched_ext_server_period_show, inode->i_private);
}
static const struct file_operations ext_server_period_fops = {
.open = sched_ext_server_period_open,
.write = sched_ext_server_period_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif /* CONFIG_SCHED_CLASS_EXT */
static struct dentry *debugfs_sched;
static void debugfs_fair_server_init(void)
@ -488,6 +571,29 @@ static void debugfs_fair_server_init(void)
}
}
#ifdef CONFIG_SCHED_CLASS_EXT
static void debugfs_ext_server_init(void)
{
struct dentry *d_ext;
unsigned long cpu;
d_ext = debugfs_create_dir("ext_server", debugfs_sched);
if (!d_ext)
return;
for_each_possible_cpu(cpu) {
struct dentry *d_cpu;
char buf[32];
snprintf(buf, sizeof(buf), "cpu%lu", cpu);
d_cpu = debugfs_create_dir(buf, d_ext);
debugfs_create_file("runtime", 0644, d_cpu, (void *) cpu, &ext_server_runtime_fops);
debugfs_create_file("period", 0644, d_cpu, (void *) cpu, &ext_server_period_fops);
}
}
#endif /* CONFIG_SCHED_CLASS_EXT */
static __init int sched_init_debug(void)
{
struct dentry __maybe_unused *numa;
@ -526,6 +632,9 @@ static __init int sched_init_debug(void)
debugfs_create_file("debug", 0444, debugfs_sched, NULL, &sched_debug_fops);
debugfs_fair_server_init();
#ifdef CONFIG_SCHED_CLASS_EXT
debugfs_ext_server_init();
#endif
return 0;
}