-
Ingo Molnar authored
- i've extended the scheduler context-switch mechanism with the following per-arch defines: prepare_arch_schedule(prev_task); finish_arch_schedule(prev_task); prepare_arch_switch(rq); finish_arch_switch(rq); - plus switch_to() takes 3 parameters again: switch_to(prev, next, last); - schedule_tail() has the 'prev' task parameter again, it must be passed over in switch_to() and passed in to the fork() startup path. architectures that need to unlock the runqueue before doing the switch can do the following: #define prepare_arch_schedule(prev) task_lock(prev) #define finish_arch_schedule(prev) task_unlock(prev) #define prepare_arch_switch(rq) spin_unlock(&(rq)->lock) #define finish_arch_switch(rq) __sti() this way the task-lock makes sure that a task is not scheduled on some other CPU before the switch-out finishes, but the runqueue lock is dropped. (Local interrupts are kept disabled in this variant, just to exclude things like TLB flushes - if that matters.) architectures that can hold the runqueue lock during context-switch can do the following simplification: #define prepare_arch_schedule(prev) do { } while(0) #define finish_arch_schedule(prev) do { } while(0) #define prepare_arch_switch(rq) do { } while(0) #define finish_arch_switch(rq) spin_unlock_irq(&(rq)->lock) further optimizations possible in the 'simple' variant: - an architecture does not have to handle the 'last' parameter in switch_to() if the 'prev' parameter is unused in finish_arch_schedule(). This way the inlined return value of context_switch() too gets optimized away at compile-time. - an architecture does not have to pass the 'prev' pointer to schedule_tail(), if the 'prev' parameter is unused in finish_arch_schedule(). the x86 architecture makes use of these optimizations. Via this solution we have a reasonably flexible context-switch setup which falls back to the current (faster) code on x86, but on other platforms the runqueue lock can be dropped before doing the context-switch as well. Ingo NOTE: i have coded and tested the 'complex' variant on x86 as well to make sure it works for you on Sparc64 - but since x86's switch_mm() is not too subtle it can use the simpler variant. [ The following things had to be done to make x86 arch use the complex variant: the 4 complex macros have to be used in system.h, entry.S has to 'pushl %ebx' and 'addl $4, %esp' around the call to schedule_tail(), and switch_to() had to be reverted to the 3-parameter variant present in the 2.4 kernels. NOTE2: prepare_to_switch() functionality has been moved into the prepare_arch_switch() macro. NOTE3: please use macros for prepare|finish_arch_switch() so that we can keep the scheduler data structures internal to sched.c.
873cbfcf