Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched: Provide update_curr callbacks for stop/idle scheduling classes

Chris bisected a NULL pointer deference in task_sched_runtime() to
commit 6e998916dfe3 'sched/cputime: Fix clock_nanosleep()/clock_gettime()
inconsistency'.

Chris observed crashes in atop or other /proc walking programs when he
started fork bombs on his machine. He assumed that this is a new exit
race, but that does not make any sense when looking at that commit.

What's interesting is that, the commit provides update_curr callbacks
for all scheduling classes except stop_task and idle_task.

While nothing can ever hit that via the clock_nanosleep() and
clock_gettime() interfaces, which have been the target of the commit in
question, the author obviously forgot that there are other code paths
which invoke task_sched_runtime()

do_task_stat(()
thread_group_cputime_adjusted()
thread_group_cputime()
task_cputime()
task_sched_runtime()
if (task_current(rq, p) && task_on_rq_queued(p)) {
update_rq_clock(rq);
up->sched_class->update_curr(rq);
}

If the stats are read for a stomp machine task, aka 'migration/N' and
that task is current on its cpu, this will happily call the NULL pointer
of stop_task->update_curr. Ooops.

Chris observation that this happens faster when he runs the fork bomb
makes sense as the fork bomb will kick migration threads more often so
the probability to hit the issue will increase.

Add the missing update_curr callbacks to the scheduler classes stop_task
and idle_task. While idle tasks cannot be monitored via /proc we have
other means to hit the idle case.

Fixes: 6e998916dfe3 'sched/cputime: Fix clock_nanosleep()/clock_gettime() inconsistency'
Reported-by: Chris Mason <clm@fb.com>
Reported-and-tested-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Thomas Gleixner and committed by
Linus Torvalds
90e362f4 00c89b2f

+10
+5
kernel/sched/idle_task.c
··· 75 75 return 0; 76 76 } 77 77 78 + static void update_curr_idle(struct rq *rq) 79 + { 80 + } 81 + 78 82 /* 79 83 * Simple, special scheduling class for the per-CPU idle tasks: 80 84 */ ··· 105 101 106 102 .prio_changed = prio_changed_idle, 107 103 .switched_to = switched_to_idle, 104 + .update_curr = update_curr_idle, 108 105 };
+5
kernel/sched/stop_task.c
··· 102 102 return 0; 103 103 } 104 104 105 + static void update_curr_stop(struct rq *rq) 106 + { 107 + } 108 + 105 109 /* 106 110 * Simple, special scheduling class for the per-CPU stop tasks: 107 111 */ ··· 132 128 133 129 .prio_changed = prio_changed_stop, 134 130 .switched_to = switched_to_stop, 131 + .update_curr = update_curr_stop, 135 132 };