[PATCH 1/5] 2.6.0 fix preempt ctx switch accounting

From: Nick Piggin
Date: Sat Dec 20 2003 - 10:20:57 EST


Make sure to count kernel preemption as a context switch. A short cut
has been preventing it.



Make sure to count kernel preemption as a context switch. A short cut
has been preventing it.


linux-2.6-npiggin/kernel/sched.c | 37 +++++++++++++++----------------------
1 files changed, 15 insertions(+), 22 deletions(-)

diff -puN kernel/sched.c~sched-ctx-count-preempt kernel/sched.c
--- linux-2.6/kernel/sched.c~sched-ctx-count-preempt 2003-12-04 13:01:03.000000000 +1100
+++ linux-2.6-npiggin/kernel/sched.c 2003-12-04 13:01:26.000000000 +1100
@@ -1512,33 +1512,20 @@ need_resched:

spin_lock_irq(&rq->lock);

- /*
- * if entering off of a kernel preemption go straight
- * to picking the next task.
- */
- if (unlikely(preempt_count() & PREEMPT_ACTIVE))
- goto pick_next_task;
-
- switch (prev->state) {
- case TASK_INTERRUPTIBLE:
- if (unlikely(signal_pending(prev))) {
+ if (prev->state != TASK_RUNNING &&
+ likely(!(preempt_count() & PREEMPT_ACTIVE)) ) {
+ if (unlikely(signal_pending(prev)) &&
+ prev->state == TASK_INTERRUPTIBLE)
prev->state = TASK_RUNNING;
- break;
- }
- default:
- deactivate_task(prev, rq);
- prev->nvcsw++;
- break;
- case TASK_RUNNING:
- prev->nivcsw++;
+ else
+ deactivate_task(prev, rq);
}
-pick_next_task:
- if (unlikely(!rq->nr_running)) {
+
#ifdef CONFIG_SMP
+ if (unlikely(!rq->nr_running))
load_balance(rq, 1, cpu_to_node_mask(smp_processor_id()));
- if (rq->nr_running)
- goto pick_next_task;
#endif
+ if (unlikely(!rq->nr_running)) {
next = rq->idle;
rq->expired_timestamp = 0;
goto switch_tasks;
@@ -1585,6 +1572,12 @@ switch_tasks:
prev->timestamp = now;

if (likely(prev != next)) {
+ if (prev->state == TASK_RUNNING ||
+ unlikely(preempt_count() & PREEMPT_ACTIVE))
+ prev->nivcsw++;
+ else
+ prev->nvcsw++;
+
next->timestamp = now;
rq->nr_switches++;
rq->curr = next;

_