Commit f71d2899 authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] Fix context switch accounting

Noted by Nick Piggin, fix based on a patch by Linus.

I've done some additional cleanups: fixed a compilation warning on UP
and cleaned up the goto pick_next_task code.  Moved the 'unlikely' to
the test as a whole.

I've tested this patch and the context-switch stats look OK.
parent 5326c535
...@@ -1470,6 +1470,7 @@ void scheduling_functions_start_here(void) { } ...@@ -1470,6 +1470,7 @@ void scheduling_functions_start_here(void) { }
*/ */
asmlinkage void schedule(void) asmlinkage void schedule(void)
{ {
long *switch_count;
task_t *prev, *next; task_t *prev, *next;
runqueue_t *rq; runqueue_t *rq;
prio_array_t *array; prio_array_t *array;
...@@ -1516,32 +1517,25 @@ asmlinkage void schedule(void) ...@@ -1516,32 +1517,25 @@ asmlinkage void schedule(void)
* if entering off of a kernel preemption go straight * if entering off of a kernel preemption go straight
* to picking the next task. * to picking the next task.
*/ */
if (unlikely(preempt_count() & PREEMPT_ACTIVE)) switch_count = &prev->nivcsw;
goto pick_next_task; if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
switch_count = &prev->nvcsw;
switch (prev->state) { if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
case TASK_INTERRUPTIBLE: unlikely(signal_pending(prev))))
if (unlikely(signal_pending(prev))) {
prev->state = TASK_RUNNING; prev->state = TASK_RUNNING;
break; else
} deactivate_task(prev, rq);
default:
deactivate_task(prev, rq);
prev->nvcsw++;
break;
case TASK_RUNNING:
prev->nivcsw++;
} }
pick_next_task:
if (unlikely(!rq->nr_running)) { if (unlikely(!rq->nr_running)) {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
load_balance(rq, 1, cpu_to_node_mask(smp_processor_id())); load_balance(rq, 1, cpu_to_node_mask(smp_processor_id()));
if (rq->nr_running)
goto pick_next_task;
#endif #endif
next = rq->idle; if (!rq->nr_running) {
rq->expired_timestamp = 0; next = rq->idle;
goto switch_tasks; rq->expired_timestamp = 0;
goto switch_tasks;
}
} }
array = rq->active; array = rq->active;
...@@ -1588,6 +1582,7 @@ asmlinkage void schedule(void) ...@@ -1588,6 +1582,7 @@ asmlinkage void schedule(void)
next->timestamp = now; next->timestamp = now;
rq->nr_switches++; rq->nr_switches++;
rq->curr = next; rq->curr = next;
++*switch_count;
prepare_arch_switch(rq, next); prepare_arch_switch(rq, next);
prev = context_switch(rq, prev, next); prev = context_switch(rq, prev, next);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment