mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:24:45 +01:00
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:
parent
cd959a3562
commit
76d12132ba
1 changed files with 133 additions and 24 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue