involuntary context switching

In a kernel based on 2.6.27:

In the schedule() routine they have a local variable switch_count:
/*

  • schedule() is the main scheduler function.
    */
    asmlinkage void __sched schedule(void)
    {
    struct task_struct *prev, *next;
    unsigned long *switch_count;
    struct rq *rq;
    int cpu;

They originally point this to the involuntary context switch.

    switch_count = &prev->nivcsw;

Later on a conditional can change the pointer to the voluntary context switch:

if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
if (unlikely(signal_pending_state(prev->state, prev)))
prev->state = TASK_RUNNING;
else
deactivate_task(rq, prev, 1);
switch_count = &prev->nvcsw;
}

Then later if the next proc isn't the same as the prev one it will do the context switch and increment the switch_count:

    if \(likely\(prev != next\)\) \{
            sched\_info_switch\(prev, next\);

            rq->nr_switches\+\+;
            rq->curr = next;
            \+\+*switch_count;

            context_switch\(rq, prev, next\); /* unlocks the rq */
            /*
             * the context switch might have flipped the stack from under
             * us, hence refresh the local variables.
             */
            cpu = smp\_processor_id\(\);
            rq = cpu_rq\(cpu\);

So whether nivcsw gets incremented or nvcsw depends on the condition.

There seem to be over 500 places where the kernel calls schedule(). Most of these from what I can tell call the schedule() routine when they start some I/O and are giving up the processor. I assume most of these would be voluntary context switches.

Also, when a time-slice comes in the schedule() gets called and that would be an involuntary context switch.

My question is are their other times when the schedule() would get called that would be involuntary. Like specifically, if a process got interrupted to handle a disk drive interrupt or serial port interrupt or network interrupt, does the system go back to the process that got interrupted or does it call schedule() and possibly give the processor to a different process on return from handling the interrupt ?

Every system call is a context switch, bar none.

Got it!

Thanks