2.4-ac updated O(1) scheduler
PATCH 1/1 2.4-ac updated O(1) scheduler
Halo,
The attached patch updates Ingo Molnar's ultra-scalable O(1) scheduler in 2.4-ac to the latest code base. It contains various fixes, cleanups, and new features. All changes are from 2.5 or patches pending for 2.5.
Specifically, this patch makes the following changes to the scheduler in Alan's tree:
- remove wake_up_sync and friends, we don't need them now
- abstract away access to need_resched
- fix scheduler deadlock on some platforms
- sched_yield optimizations and cleanup
- better use MAX_RT_PRIO define instead of magic numbers
- misc. code cleanups
- misc. fixes and optimizations
and most importantly:
- backport the migration_thread and associated code to 2.4
The migration_thread code has the interrupt-off fix and William Lee Irwin's new migration_init routine, both of which are pending for 2.5.
Note I have sent this to Alan already, so it should be in a future 2.4-ac. You can get a better description as well as the patches in logical chunks from:
ftp://ftp.kernel.org/pub/linux/kernel/people/rml/sched
I will also make available fully updated base O(1)-scheduler patches for 2.4.18 and the latest prepatch shortly.
Enjoy,
Robert Love
arch/i386/kernel/i8259.c +0 -4
@@ -79,7 +79,6 @@* through the ICC by us (IPIs) */ #ifdef CONFIG_SMP -BUILD_SMP_INTERRUPT(task_migration_interrupt,TASK_MIGRATION_VECTOR) BUILD_SMP_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)BUILD_SMP_INTERRUPT (call_function_interrupt,CALL_FUNCTION_VECTOR )
@@ -474,9 +473,6 @@*/ set_intr_gate (RESCHEDULE_VECTOR , reschedule_interrupt); -/* IPI for task migration */ -set_intr_gate (TASK_MIGRATION_VECTOR , task_migration_interrupt); -/* IPI for invalidation */ set_intr_gate (INVALIDATE_TLB_VECTOR , invalidate_interrupt);
arch/i386/kernel/smp.c +0 -29
@@ -484,35 +484,6 @@do_flush_tlb_all_local (); } -static spinlock_t migration_lock =SPIN_LOCK_UNLOCKED ; -static task_t *new_task; - -/* -* This function sends a 'task migration' IPI to another CPU. -* Must be called from syscall contexts, with interrupts *enabled*. -*/ -void smp_migrate_task (int cpu,task_t *p) -{ -/* -* The target CPU will unlock the migration spinlock: -*/ -spin_lock (&migration_lock); - new_task = p; -send_IPI_mask (1 << cpu,TASK_MIGRATION_VECTOR ); -} - -/* -* Task migration callback. -*/ -asmlinkage void smp_task_migration_interrupt(void) -{ -task_t *p; - -ack_APIC_irq (); - p = new_task; -spin_unlock (&migration_lock); -sched_task_migrated (p); -}/* * this function sends a 'reschedule' IPI to another CPU. * it goes straight through and wastes no time serializing
fs/pipe.c +2 -2
@@ -115,7 +115,7 @@* writers synchronously that there is more * room. */ -wake_up_interruptible_sync (PIPE_WAIT (*inode)); +wake_up_interruptible (PIPE_WAIT (*inode));if (!PIPE_EMPTY (*inode))BUG (); goto do_more_read;
@@ -215,7 +215,7 @@* is going to give up this CPU, so it doesnt have * to do idle reschedules. */ -wake_up_interruptible_sync (PIPE_WAIT (*inode)); +wake_up_interruptible (PIPE_WAIT (*inode));PIPE_WAITING_WRITERS (*inode)++;pipe_wait (inode);PIPE_WAITING_WRITERS (*inode)--;
include/asm-i386/hw_irq.h +1 -2
@@ -41,8 +41,7 @@#define ERROR_APIC_VECTOR 0xfe#define INVALIDATE_TLB_VECTOR 0xfd#define RESCHEDULE_VECTOR 0xfc -#define TASK_MIGRATION_VECTOR 0xfb -#define CALL_FUNCTION_VECTOR 0xfa +#define CALL_FUNCTION_VECTOR 0xfb/* * Local APIC timer IRQ vector is on a different priority level,
include/linux/sched.h +31 -7
@@ -149,8 +149,7 @@extern void update_one_process (task_t *p,unsigned long user,unsigned long system,int cpu);extern void scheduler_tick (int user_tick,int system); -extern void sched_task_migrated (task_t *p); -extern void smp_migrate_task (int cpu,task_t *task); +extern void migration_init (void );extern unsigned long cache_decay_ticks;extern int set_user (uid_t new_ruid,int dumpclear);
@@ -450,7 +449,12 @@*/ #define _STK_LIM (8*1024*1024) +#if CONFIG_SMP extern void set_cpus_allowed (task_t *p,unsigned long new_mask); +#else +#define set_cpus_allowed (p, new_mask) do { } while (0) +#endif +extern void set_user_nice (task_t *p,long nice);extern int task_prio (task_t *p);extern int task_nice (task_t *p);
@@ -577,7 +581,6 @@#define CURRENT_TIME (xtime.tv_sec)extern void FASTCALL (__wake_up (wait_queue_head_t *q,unsigned int mode,int nr)); -extern void FASTCALL (__wake_up_sync (wait_queue_head_t *q,unsigned int mode,int nr));extern void FASTCALL (sleep_on (wait_queue_head_t *q));extern long FASTCALL (sleep_on_timeout (wait_queue_head_t *q,signed long timeout));
@@ -591,13 +594,9 @@#define wake_up (x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1)#define wake_up_nr (x, nr) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)#define wake_up_all (x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0) -#define wake_up_sync (x) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1) -#define wake_up_sync_nr (x, nr) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)#define wake_up_interruptible (x) __wake_up((x),TASK_INTERRUPTIBLE, 1)#define wake_up_interruptible_nr (x, nr) __wake_up((x),TASK_INTERRUPTIBLE, nr)#define wake_up_interruptible_all (x) __wake_up((x),TASK_INTERRUPTIBLE, 0) -#define wake_up_interruptible_sync (x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1) -#define wake_up_interruptible_sync_nr (x) __wake_up_sync((x),TASK_INTERRUPTIBLE, nr)asmlinkage long sys_wait4 (pid_t pid,unsigned int * stat_addr,int options,struct rusage * ru);extern int in_group_p (gid_t );
@@ -919,6 +918,31 @@return res; } +static inline void set_need_resched (void ) +{ + current->need_resched =1 ; +} + +static inline void clear_need_resched (void ) +{ + current->need_resched =0 ; +} + +static inline void set_tsk_need_resched (struct task_struct *tsk) +{ + tsk->need_resched =1 ; +} + +static inline void clear_tsk_need_resched (struct task_struct *tsk) +{ + tsk->need_resched =0 ; +} + +static inline int need_resched (void ) +{ +return unlikely (current->need_resched); +} +#endif /* __KERNEL__ */ #endif
init/main.c +4 -0
@@ -458,6 +458,10 @@*/ static void __init do_basic_setup (void ) { +/* Start the per-CPU migration threads */ +#if CONFIG_SMP +migration_init (); +#endif /* * Tell the world that we're going to be the grim
kernel/ksyms.c +3 -2
@@ -434,7 +434,6 @@/* process management */ EXPORT_SYMBOL (complete_and_exit);EXPORT_SYMBOL (__wake_up); -EXPORT_SYMBOL (__wake_up_sync);EXPORT_SYMBOL (wake_up_process);EXPORT_SYMBOL (sleep_on);EXPORT_SYMBOL (sleep_on_timeout);
@@ -444,7 +443,9 @@EXPORT_SYMBOL (schedule_timeout);EXPORT_SYMBOL (sys_sched_yield);EXPORT_SYMBOL (set_user_nice); -EXPORT_SYMBOL (set_cpus_allowed); +#ifdef CONFIG_SMP +EXPORT_SYMBOL_GPL (set_cpus_allowed); +#endif EXPORT_SYMBOL (jiffies);EXPORT_SYMBOL (xtime);EXPORT_SYMBOL (do_gettimeofday);
kernel/sched.c +326 -169
810 lines not on this page · raw message
Quoted 3 lines · Robert Love
The attached patch updates Ingo Molnar's ultra-scalable O(1) scheduler in 2.4-ac to the latest code base. It contains various fixes, cleanups, and new features. All changes are from 2.5 or patches pending for 2.5.
There is an updated patch at
http://www.kernel.org/pub/linux/kernel/people/rml/sched/ingo-O1/sched-fixes-O1-rml-2.4.19-pre7-ac2-2.patch
and your favorite mirror. With the following changes:
- include linux/interrupt.h in sched.c
- use yield() where appropriate, not the old method
which are boring and only needed for those with compile problems.
Robert Love