summaryrefslogtreecommitdiff
path: root/kernel/sched/debug.c
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2026-02-03 11:05:12 +0100
committerPeter Zijlstra <peterz@infradead.org>2026-02-03 12:04:18 +0100
commit5a40a9bb56d455e7548ba4b6d7787918323cbaf0 (patch)
treecb6aaa9edb0fbbe06272a5f2ad19fbfbfba44cd2 /kernel/sched/debug.c
parent76d12132ba459ab929cb66eb2030c666aacdb69a (diff)
downloadlwn-5a40a9bb56d455e7548ba4b6d7787918323cbaf0.tar.gz
lwn-5a40a9bb56d455e7548ba4b6d7787918323cbaf0.zip
sched/debug: Fix dl_server (re)start conditions
There are two problems with sched_server_write_common() that can cause the dl_server to malfunction upon attempting to change the parameters: 1) when, after having disabled the dl_server by setting runtime=0, it is enabled again while tasks are already enqueued. In this case is_active would still be 0 and dl_server_start() would not be called. 2) when dl_server_apply_params() would fail, runtime is not applied and does not reflect the new state. Instead have dl_server_start() check its actual dl_runtime, and have sched_server_write_common() unconditionally (re)start the dl_server. It will automatically stop if there isn't anything to do, so spurious activation is harmless -- while failing to start it is a problem. While there, move the printk out of the locked region and make it symmetric, also printing on enable. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://patch.msgid.link/20260203103407.GK1282955@noisy.programming.kicks-ass.net
Diffstat (limited to 'kernel/sched/debug.c')
-rw-r--r--kernel/sched/debug.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 59e650f9d436..b24f40f05019 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -338,9 +338,9 @@ static ssize_t sched_server_write_common(struct file *filp, const char __user *u
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;
+ u64 old_runtime, runtime, period;
+ struct rq *rq = cpu_rq(cpu);
int retval = 0;
size_t err;
u64 value;
@@ -350,9 +350,7 @@ static ssize_t sched_server_write_common(struct file *filp, const char __user *u
return err;
scoped_guard (rq_lock_irqsave, rq) {
- bool is_active;
-
- runtime = dl_se->dl_runtime;
+ old_runtime = runtime = dl_se->dl_runtime;
period = dl_se->dl_period;
switch (param) {
@@ -374,25 +372,23 @@ static ssize_t sched_server_write_common(struct file *filp, const char __user *u
return -EINVAL;
}
- is_active = dl_server_active(dl_se);
- if (is_active) {
- update_rq_clock(rq);
- dl_server_stop(dl_se);
- }
-
+ update_rq_clock(rq);
+ dl_server_stop(dl_se);
retval = dl_server_apply_params(dl_se, runtime, period, 0);
-
- if (!runtime)
- 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(dl_se);
+ dl_server_start(dl_se);
if (retval < 0)
return retval;
}
+ if (!!old_runtime ^ !!runtime) {
+ pr_info("%s server %sabled on CPU %d%s.\n",
+ server == &rq->fair_server ? "Fair" : "Ext",
+ runtime ? "en" : "dis",
+ cpu_of(rq),
+ runtime ? "" : ", system may malfunction due to starvation");
+ }
+
*ppos += cnt;
return cnt;
}