From 95a2f6d75d878126b883e87a5fd028e971851c93 Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Mon, 18 Oct 2004 09:11:14 -0700 Subject: [PATCH] [PATCH] CPU Scheduler: fix potential error in runqueue nr_uninterruptible count Problem: In the function try_to_wake_up(), when the runqueue's nr_uninterruptible field is decremented it's possible (on SMP systems) that the pointer no longer points to the runqueue that the task being woken was on when it went to sleep. This would cause the wrong runqueue's field to be decremented and the correct one tp remain unchanged. Fix: Save a pointer to the old runqueue at the beginning of the function and use it when decrementing nr_uninterruptible. Signed-off-by: Peter Williams Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/sched.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 2e67de4b356a6..3b498fa4f3d75 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -981,14 +981,14 @@ static int try_to_wake_up(task_t * p, unsigned int state, int sync) int cpu, this_cpu, success = 0; unsigned long flags; long old_state; - runqueue_t *rq; + runqueue_t *rq, *old_rq; #ifdef CONFIG_SMP unsigned long load, this_load; struct sched_domain *sd; int new_cpu; #endif - rq = task_rq_lock(p, &flags); + old_rq = rq = task_rq_lock(p, &flags); schedstat_inc(rq, ttwu_cnt); old_state = p->state; if (!(old_state & state)) @@ -1083,7 +1083,7 @@ out_set_cpu: out_activate: #endif /* CONFIG_SMP */ if (old_state == TASK_UNINTERRUPTIBLE) { - rq->nr_uninterruptible--; + old_rq->nr_uninterruptible--; /* * Tasks on involuntary sleep don't earn * sleep_avg beyond just interactive state. -- 2.53.0