From: William Lee Irwin III This addresses the issue with get_wchan() that the various functions acting as scheduling-related primitives are not, in fact, contiguous in the text segment. It creates an ELF section for scheduling primitives to be placed in, and places currently-detected (i.e. skipped during stack decoding) scheduling primitives and others like io_schedule() and down(), which are currently missed by get_wchan() code, into this section also. The net effects are more reliability of get_wchan()'s results and the new ability, made use of by this code, to arbitrarily place scheduling primitives in the source code without disturbing get_wchan()'s accuracy. Suggestions by Arnd Bergmann and Matthew Wilcox regarding reducing the invasiveness of the patch were incorporated during prior rounds of review. I've at least tried to sweep all arches in this patch. --- 25-akpm/arch/alpha/kernel/process.c | 2 - 25-akpm/arch/alpha/kernel/semaphore.c | 9 ++--- 25-akpm/arch/alpha/kernel/vmlinux.lds.S | 1 25-akpm/arch/arm/kernel/process.c | 2 - 25-akpm/arch/arm/kernel/semaphore.c | 8 ++-- 25-akpm/arch/arm/kernel/vmlinux.lds.S | 1 25-akpm/arch/arm26/kernel/process.c | 2 - 25-akpm/arch/arm26/kernel/semaphore.c | 8 ++-- 25-akpm/arch/arm26/kernel/vmlinux-arm26-xip.lds.in | 1 25-akpm/arch/arm26/kernel/vmlinux-arm26.lds.in | 1 25-akpm/arch/cris/arch-v10/kernel/process.c | 3 - 25-akpm/arch/cris/arch-v10/vmlinux.lds.S | 1 25-akpm/arch/cris/kernel/semaphore.c | 5 +- 25-akpm/arch/h8300/kernel/process.c | 3 - 25-akpm/arch/h8300/kernel/semaphore.c | 5 +- 25-akpm/arch/h8300/kernel/vmlinux.lds.S | 1 25-akpm/arch/i386/kernel/process.c | 2 - 25-akpm/arch/i386/kernel/semaphore.c | 17 +++++---- 25-akpm/arch/i386/kernel/vmlinux.lds.S | 1 25-akpm/arch/ia64/kernel/process.c | 2 - 25-akpm/arch/ia64/kernel/semaphore.c | 7 +-- 25-akpm/arch/ia64/kernel/vmlinux.lds.S | 1 25-akpm/arch/m68k/kernel/process.c | 5 -- 25-akpm/arch/m68k/kernel/semaphore.c | 5 +- 25-akpm/arch/m68k/kernel/vmlinux-std.lds | 1 25-akpm/arch/m68k/kernel/vmlinux-sun3.lds | 1 25-akpm/arch/m68knommu/kernel/process.c | 5 -- 25-akpm/arch/m68knommu/kernel/semaphore.c | 5 +- 25-akpm/arch/m68knommu/kernel/vmlinux.lds.S | 1 25-akpm/arch/mips/kernel/process.c | 2 - 25-akpm/arch/mips/kernel/semaphore.c | 5 +- 25-akpm/arch/mips/kernel/vmlinux.lds.S | 1 25-akpm/arch/parisc/kernel/semaphore.c | 5 +- 25-akpm/arch/parisc/kernel/vmlinux.lds.S | 1 25-akpm/arch/ppc/kernel/process.c | 2 - 25-akpm/arch/ppc/kernel/semaphore.c | 5 +- 25-akpm/arch/ppc/kernel/vmlinux.lds.S | 1 25-akpm/arch/ppc64/kernel/process.c | 2 - 25-akpm/arch/ppc64/kernel/semaphore.c | 5 +- 25-akpm/arch/ppc64/kernel/vmlinux.lds.S | 1 25-akpm/arch/s390/kernel/process.c | 2 - 25-akpm/arch/s390/kernel/semaphore.c | 5 +- 25-akpm/arch/s390/kernel/vmlinux.lds.S | 1 25-akpm/arch/sh/kernel/process.c | 4 -- 25-akpm/arch/sh/kernel/semaphore.c | 5 +- 25-akpm/arch/sh/kernel/vmlinux.lds.S | 1 25-akpm/arch/sparc/kernel/process.c | 4 -- 25-akpm/arch/sparc/kernel/semaphore.c | 5 +- 25-akpm/arch/sparc/kernel/vmlinux.lds.S | 1 25-akpm/arch/sparc/lib/rwsem.S | 3 + 25-akpm/arch/sparc64/kernel/process.c | 4 -- 25-akpm/arch/sparc64/kernel/semaphore.c | 9 ++--- 25-akpm/arch/sparc64/kernel/vmlinux.lds.S | 1 25-akpm/arch/sparc64/lib/rwsem.c | 5 +- 25-akpm/arch/v850/kernel/process.c | 3 - 25-akpm/arch/v850/kernel/semaphore.c | 5 +- 25-akpm/arch/v850/kernel/vmlinux.lds.S | 1 25-akpm/arch/x86_64/kernel/process.c | 2 - 25-akpm/arch/x86_64/kernel/semaphore.c | 5 +- 25-akpm/arch/x86_64/kernel/vmlinux.lds.S | 1 25-akpm/arch/x86_64/lib/thunk.S | 3 + 25-akpm/include/asm-generic/vmlinux.lds.h | 5 ++ 25-akpm/include/linux/init.h | 2 + 25-akpm/include/linux/sched.h | 2 + 25-akpm/kernel/sched.c | 37 +++++++++++---------- 25-akpm/kernel/timer.c | 4 +- 25-akpm/lib/rwsem.c | 5 +- 67 files changed, 137 insertions(+), 124 deletions(-) diff -puN arch/alpha/kernel/process.c~wchan-use-ELF-sections arch/alpha/kernel/process.c --- 25/arch/alpha/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.186179552 -0800 +++ 25-akpm/arch/alpha/kernel/process.c 2004-04-03 02:59:47.274166176 -0800 @@ -513,8 +513,6 @@ thread_saved_pc(task_t *t) /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/alpha/kernel/semaphore.c~wchan-use-ELF-sections arch/alpha/kernel/semaphore.c --- 25/arch/alpha/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.187179400 -0800 +++ 25-akpm/arch/alpha/kernel/semaphore.c 2004-04-03 02:59:47.274166176 -0800 @@ -7,6 +7,7 @@ #include #include +#include /* * This is basically the PPC semaphore scheme ported to use @@ -60,7 +61,7 @@ static inline int __sem_update_count(str * Either form may be used in conjunction with "up()". */ -void +void __sched __down_failed(struct semaphore *sem) { struct task_struct *tsk = current; @@ -101,7 +102,7 @@ __down_failed(struct semaphore *sem) #endif } -int +int __sched __down_failed_interruptible(struct semaphore *sem) { struct task_struct *tsk = current; @@ -159,7 +160,7 @@ __up_wakeup(struct semaphore *sem) wake_up(&sem->wait); } -void +void __sched down(struct semaphore *sem) { #if WAITQUEUE_DEBUG @@ -173,7 +174,7 @@ down(struct semaphore *sem) __down(sem); } -int +int __sched down_interruptible(struct semaphore *sem) { #if WAITQUEUE_DEBUG diff -puN arch/alpha/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/alpha/kernel/vmlinux.lds.S --- 25/arch/alpha/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.188179248 -0800 +++ 25-akpm/arch/alpha/kernel/vmlinux.lds.S 2004-04-03 02:59:47.275166024 -0800 @@ -17,6 +17,7 @@ SECTIONS _text = .; /* Text and read-only data */ .text : { *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) } :kernel diff -puN arch/arm26/kernel/process.c~wchan-use-ELF-sections arch/arm26/kernel/process.c --- 25/arch/arm26/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.189179096 -0800 +++ 25-akpm/arch/arm26/kernel/process.c 2004-04-03 02:59:47.275166024 -0800 @@ -400,8 +400,6 @@ pid_t kernel_thread(int (*fn)(void *), v /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/arm26/kernel/semaphore.c~wchan-use-ELF-sections arch/arm26/kernel/semaphore.c --- 25/arch/arm26/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.191178792 -0800 +++ 25-akpm/arch/arm26/kernel/semaphore.c 2004-04-03 02:59:47.276165872 -0800 @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -56,7 +57,7 @@ void __up(struct semaphore *sem) static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -89,7 +90,7 @@ void __down(struct semaphore * sem) wake_up(&sem->wait); } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; @@ -178,7 +179,8 @@ int __down_trylock(struct semaphore * se * registers (r0 to r3 and lr), but not ip, as we use it as a return * value in some cases.. */ -asm(" .align 5 \n\ +asm(" .section .sched.text \n\ + .align 5 \n\ .globl __down_failed \n\ __down_failed: \n\ stmfd sp!, {r0 - r3, lr} \n\ diff -puN arch/arm26/kernel/vmlinux-arm26.lds.in~wchan-use-ELF-sections arch/arm26/kernel/vmlinux-arm26.lds.in --- 25/arch/arm26/kernel/vmlinux-arm26.lds.in~wchan-use-ELF-sections 2004-04-03 02:59:47.192178640 -0800 +++ 25-akpm/arch/arm26/kernel/vmlinux-arm26.lds.in 2004-04-03 02:59:47.276165872 -0800 @@ -67,6 +67,7 @@ SECTIONS .text : { /* Real text segment */ _text = .; /* Text and read-only data */ *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) *(.rodata) diff -puN arch/arm26/kernel/vmlinux-arm26-xip.lds.in~wchan-use-ELF-sections arch/arm26/kernel/vmlinux-arm26-xip.lds.in --- 25/arch/arm26/kernel/vmlinux-arm26-xip.lds.in~wchan-use-ELF-sections 2004-04-03 02:59:47.193178488 -0800 +++ 25-akpm/arch/arm26/kernel/vmlinux-arm26-xip.lds.in 2004-04-03 02:59:47.277165720 -0800 @@ -66,6 +66,7 @@ SECTIONS .text : { /* Real text segment */ _text = .; /* Text and read-only data */ *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) *(.rodata) diff -puN arch/arm/kernel/process.c~wchan-use-ELF-sections arch/arm/kernel/process.c --- 25/arch/arm/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.194178336 -0800 +++ 25-akpm/arch/arm/kernel/process.c 2004-04-03 02:59:47.277165720 -0800 @@ -414,8 +414,6 @@ pid_t kernel_thread(int (*fn)(void *), v /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/arm/kernel/semaphore.c~wchan-use-ELF-sections arch/arm/kernel/semaphore.c --- 25/arch/arm/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.196178032 -0800 +++ 25-akpm/arch/arm/kernel/semaphore.c 2004-04-03 02:59:47.278165568 -0800 @@ -13,6 +13,7 @@ */ #include #include +#include #include @@ -54,7 +55,7 @@ void __up(struct semaphore *sem) static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -87,7 +88,7 @@ void __down(struct semaphore * sem) wake_up(&sem->wait); } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; @@ -176,7 +177,8 @@ int __down_trylock(struct semaphore * se * registers (r0 to r3 and lr), but not ip, as we use it as a return * value in some cases.. */ -asm(" .align 5 \n\ +asm(" .section .sched.text \n\ + .align 5 \n\ .globl __down_failed \n\ __down_failed: \n\ stmfd sp!, {r0 - r3, lr} \n\ diff -puN arch/arm/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/arm/kernel/vmlinux.lds.S --- 25/arch/arm/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.197177880 -0800 +++ 25-akpm/arch/arm/kernel/vmlinux.lds.S 2004-04-03 02:59:47.278165568 -0800 @@ -73,6 +73,7 @@ SECTIONS .text : { /* Real text segment */ _text = .; /* Text and read-only data */ *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) *(.rodata) diff -puN arch/cris/arch-v10/kernel/process.c~wchan-use-ELF-sections arch/cris/arch-v10/kernel/process.c --- 25/arch/cris/arch-v10/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.198177728 -0800 +++ 25-akpm/arch/cris/arch-v10/kernel/process.c 2004-04-03 02:59:47.278165568 -0800 @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef CONFIG_ETRAX_GPIO void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */ @@ -216,8 +217,6 @@ asmlinkage int sys_execve(const char *fn * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/cris/arch-v10/vmlinux.lds.S~wchan-use-ELF-sections arch/cris/arch-v10/vmlinux.lds.S --- 25/arch/cris/arch-v10/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.199177576 -0800 +++ 25-akpm/arch/cris/arch-v10/vmlinux.lds.S 2004-04-03 02:59:47.279165416 -0800 @@ -25,6 +25,7 @@ SECTIONS __stext = .; .text : { *(.text) + SCHED_TEXT *(.fixup) *(.text.__*) } diff -puN arch/cris/kernel/semaphore.c~wchan-use-ELF-sections arch/cris/kernel/semaphore.c --- 25/arch/cris/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.200177424 -0800 +++ 25-akpm/arch/cris/kernel/semaphore.c 2004-04-03 02:59:47.279165416 -0800 @@ -4,6 +4,7 @@ */ #include +#include #include /* @@ -94,7 +95,7 @@ void __up(struct semaphore *sem) tsk->state = TASK_RUNNING; \ remove_wait_queue(&sem->wait, &wait); -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { DOWN_VAR DOWN_HEAD(TASK_UNINTERRUPTIBLE) @@ -104,7 +105,7 @@ void __down(struct semaphore * sem) DOWN_TAIL(TASK_UNINTERRUPTIBLE) } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int ret = 0; DOWN_VAR diff -puN arch/h8300/kernel/process.c~wchan-use-ELF-sections arch/h8300/kernel/process.c --- 25/arch/h8300/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.202177120 -0800 +++ 25-akpm/arch/h8300/kernel/process.c 2004-04-03 02:59:47.280165264 -0800 @@ -264,8 +264,6 @@ out: /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) @@ -289,7 +287,6 @@ unsigned long get_wchan(struct task_stru fp >= 8184+stack_page) return 0; pc = ((unsigned long *)fp)[1]; - /* FIXME: This depends on the order of these functions. */ if (pc < first_sched || pc >= last_sched) return pc; fp = *(unsigned long *) fp; diff -puN arch/h8300/kernel/semaphore.c~wchan-use-ELF-sections arch/h8300/kernel/semaphore.c --- 25/arch/h8300/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.203176968 -0800 +++ 25-akpm/arch/h8300/kernel/semaphore.c 2004-04-03 02:59:47.280165264 -0800 @@ -5,6 +5,7 @@ #include #include +#include #include #ifndef CONFIG_RMW_INSNS @@ -95,7 +96,7 @@ void __up(struct semaphore *sem) current->state = TASK_RUNNING; \ remove_wait_queue(&sem->wait, &wait); -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { DECLARE_WAITQUEUE(wait, current); @@ -106,7 +107,7 @@ void __down(struct semaphore * sem) DOWN_TAIL(TASK_UNINTERRUPTIBLE) } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { DECLARE_WAITQUEUE(wait, current); int ret = 0; diff -puN arch/h8300/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/h8300/kernel/vmlinux.lds.S --- 25/arch/h8300/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.204176816 -0800 +++ 25-akpm/arch/h8300/kernel/vmlinux.lds.S 2004-04-03 02:59:47.280165264 -0800 @@ -82,6 +82,7 @@ SECTIONS #endif __stext = . ; *(.text) + SCHED_TEXT . = ALIGN(0x4) ; *(.exit.text) *(.text.*) diff -puN arch/i386/kernel/process.c~wchan-use-ELF-sections arch/i386/kernel/process.c --- 25/arch/i386/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.205176664 -0800 +++ 25-akpm/arch/i386/kernel/process.c 2004-04-03 02:59:47.281165112 -0800 @@ -632,8 +632,6 @@ out: /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) #define top_esp (THREAD_SIZE - sizeof(unsigned long)) diff -puN arch/i386/kernel/semaphore.c~wchan-use-ELF-sections arch/i386/kernel/semaphore.c --- 25/arch/i386/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.206176512 -0800 +++ 25-akpm/arch/i386/kernel/semaphore.c 2004-04-03 02:59:47.282164960 -0800 @@ -15,6 +15,7 @@ #include #include #include +#include #include /* @@ -53,7 +54,7 @@ asmlinkage void __up(struct semaphore *s wake_up(&sem->wait); } -asmlinkage void __down(struct semaphore * sem) +asmlinkage void __sched __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -90,7 +91,7 @@ asmlinkage void __down(struct semaphore tsk->state = TASK_RUNNING; } -asmlinkage int __down_interruptible(struct semaphore * sem) +asmlinkage int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; @@ -187,7 +188,7 @@ asmlinkage int __down_trylock(struct sem * value.. */ asm( -".text\n" +".section .sched.text\n" ".align 4\n" ".globl __down_failed\n" "__down_failed:\n\t" @@ -210,7 +211,7 @@ asm( ); asm( -".text\n" +".section .sched.text\n" ".align 4\n" ".globl __down_failed_interruptible\n" "__down_failed_interruptible:\n\t" @@ -231,7 +232,7 @@ asm( ); asm( -".text\n" +".section .sched.text\n" ".align 4\n" ".globl __down_failed_trylock\n" "__down_failed_trylock:\n\t" @@ -252,7 +253,7 @@ asm( ); asm( -".text\n" +".section .sched.text\n" ".align 4\n" ".globl __up_wakeup\n" "__up_wakeup:\n\t" @@ -271,7 +272,7 @@ asm( */ #if defined(CONFIG_SMP) asm( -".text\n" +".section .sched.text\n" ".align 4\n" ".globl __write_lock_failed\n" "__write_lock_failed:\n\t" @@ -285,7 +286,7 @@ asm( ); asm( -".text\n" +".section .sched.text\n" ".align 4\n" ".globl __read_lock_failed\n" "__read_lock_failed:\n\t" diff -puN arch/i386/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/i386/kernel/vmlinux.lds.S --- 25/arch/i386/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.208176208 -0800 +++ 25-akpm/arch/i386/kernel/vmlinux.lds.S 2004-04-03 02:59:47.282164960 -0800 @@ -16,6 +16,7 @@ SECTIONS _text = .; /* Text and read-only data */ .text : { *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) } = 0x9090 diff -puN arch/ia64/kernel/process.c~wchan-use-ELF-sections arch/ia64/kernel/process.c --- 25/arch/ia64/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.209176056 -0800 +++ 25-akpm/arch/ia64/kernel/process.c 2004-04-03 02:59:47.283164808 -0800 @@ -660,8 +660,6 @@ get_wchan (struct task_struct *p) /* * These bracket the sleeping functions.. */ - extern void scheduling_functions_start_here(void); - extern void scheduling_functions_end_here(void); # define first_sched ((unsigned long) scheduling_functions_start_here) # define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/ia64/kernel/semaphore.c~wchan-use-ELF-sections arch/ia64/kernel/semaphore.c --- 25/arch/ia64/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.210175904 -0800 +++ 25-akpm/arch/ia64/kernel/semaphore.c 2004-04-03 02:59:47.283164808 -0800 @@ -24,6 +24,7 @@ * where we want to avoid any extra jumps and calls. */ #include +#include #include #include @@ -44,8 +45,7 @@ __up (struct semaphore *sem) wake_up(&sem->wait); } -void -__down (struct semaphore *sem) +void __sched __down (struct semaphore *sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -82,8 +82,7 @@ __down (struct semaphore *sem) tsk->state = TASK_RUNNING; } -int -__down_interruptible (struct semaphore * sem) +int __sched __down_interruptible (struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; diff -puN arch/ia64/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/ia64/kernel/vmlinux.lds.S --- 25/arch/ia64/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.211175752 -0800 +++ 25-akpm/arch/ia64/kernel/vmlinux.lds.S 2004-04-03 02:59:47.284164656 -0800 @@ -41,6 +41,7 @@ SECTIONS { *(.text.ivt) *(.text) + SCHED_TEXT *(.gnu.linkonce.t*) } .text2 : AT(ADDR(.text2) - LOAD_OFFSET) diff -puN arch/m68k/kernel/process.c~wchan-use-ELF-sections arch/m68k/kernel/process.c --- 25/arch/m68k/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.213175448 -0800 +++ 25-akpm/arch/m68k/kernel/process.c 2004-04-03 02:59:47.284164656 -0800 @@ -65,8 +65,6 @@ asmlinkage void ret_from_fork(void); */ unsigned long thread_saved_pc(struct task_struct *tsk) { - extern void scheduling_functions_start_here(void); - extern void scheduling_functions_end_here(void); struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp; /* Check whether the thread is blocked in resume() */ if (sw->retpc > (unsigned long)scheduling_functions_start_here && @@ -387,8 +385,6 @@ out: /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) @@ -407,7 +403,6 @@ unsigned long get_wchan(struct task_stru fp >= 8184+stack_page) return 0; pc = ((unsigned long *)fp)[1]; - /* FIXME: This depends on the order of these functions. */ if (pc < first_sched || pc >= last_sched) return pc; fp = *(unsigned long *) fp; diff -puN arch/m68k/kernel/semaphore.c~wchan-use-ELF-sections arch/m68k/kernel/semaphore.c --- 25/arch/m68k/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.214175296 -0800 +++ 25-akpm/arch/m68k/kernel/semaphore.c 2004-04-03 02:59:47.285164504 -0800 @@ -5,6 +5,7 @@ #include #include +#include #include #ifndef CONFIG_RMW_INSNS @@ -95,7 +96,7 @@ void __up(struct semaphore *sem) current->state = TASK_RUNNING; \ remove_wait_queue(&sem->wait, &wait); -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { DECLARE_WAITQUEUE(wait, current); @@ -106,7 +107,7 @@ void __down(struct semaphore * sem) DOWN_TAIL(TASK_UNINTERRUPTIBLE) } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { DECLARE_WAITQUEUE(wait, current); int ret = 0; diff -puN arch/m68k/kernel/vmlinux-std.lds~wchan-use-ELF-sections arch/m68k/kernel/vmlinux-std.lds --- 25/arch/m68k/kernel/vmlinux-std.lds~wchan-use-ELF-sections 2004-04-03 02:59:47.215175144 -0800 +++ 25-akpm/arch/m68k/kernel/vmlinux-std.lds 2004-04-03 02:59:47.285164504 -0800 @@ -12,6 +12,7 @@ SECTIONS _text = .; /* Text and read-only data */ .text : { *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) } = 0x4e75 diff -puN arch/m68k/kernel/vmlinux-sun3.lds~wchan-use-ELF-sections arch/m68k/kernel/vmlinux-sun3.lds --- 25/arch/m68k/kernel/vmlinux-sun3.lds~wchan-use-ELF-sections 2004-04-03 02:59:47.216174992 -0800 +++ 25-akpm/arch/m68k/kernel/vmlinux-sun3.lds 2004-04-03 02:59:47.285164504 -0800 @@ -13,6 +13,7 @@ SECTIONS .text : { *(.head) *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) } = 0x4e75 diff -puN arch/m68knommu/kernel/process.c~wchan-use-ELF-sections arch/m68knommu/kernel/process.c --- 25/arch/m68knommu/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.218174688 -0800 +++ 25-akpm/arch/m68knommu/kernel/process.c 2004-04-03 02:59:47.286164352 -0800 @@ -406,8 +406,6 @@ out: /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) @@ -426,7 +424,6 @@ unsigned long get_wchan(struct task_stru fp >= 8184+stack_page) return 0; pc = ((unsigned long *)fp)[1]; - /* FIXME: This depends on the order of these functions. */ if (pc < first_sched || pc >= last_sched) return pc; fp = *(unsigned long *) fp; @@ -439,8 +436,6 @@ unsigned long get_wchan(struct task_stru */ unsigned long thread_saved_pc(struct task_struct *tsk) { - extern void scheduling_functions_start_here(void); - extern void scheduling_functions_end_here(void); struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp; /* Check whether the thread is blocked in resume() */ diff -puN arch/m68knommu/kernel/semaphore.c~wchan-use-ELF-sections arch/m68knommu/kernel/semaphore.c --- 25/arch/m68knommu/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.219174536 -0800 +++ 25-akpm/arch/m68knommu/kernel/semaphore.c 2004-04-03 02:59:47.286164352 -0800 @@ -6,6 +6,7 @@ #include #include #include +#include #include #ifndef CONFIG_RMW_INSNS @@ -96,7 +97,7 @@ void __up(struct semaphore *sem) current->state = TASK_RUNNING; \ remove_wait_queue(&sem->wait, &wait); -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { DECLARE_WAITQUEUE(wait, current); @@ -107,7 +108,7 @@ void __down(struct semaphore * sem) DOWN_TAIL(TASK_UNINTERRUPTIBLE) } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { DECLARE_WAITQUEUE(wait, current); int ret = 0; diff -puN arch/m68knommu/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/m68knommu/kernel/vmlinux.lds.S --- 25/arch/m68knommu/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.220174384 -0800 +++ 25-akpm/arch/m68knommu/kernel/vmlinux.lds.S 2004-04-03 02:59:47.287164200 -0800 @@ -191,6 +191,7 @@ SECTIONS { .text : { _stext = . ; *(.text) + SCHED_TEXT *(.text.lock) . = ALIGN(16); /* Exception table */ diff -puN arch/mips/kernel/process.c~wchan-use-ELF-sections arch/mips/kernel/process.c --- 25/arch/mips/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.222174080 -0800 +++ 25-akpm/arch/mips/kernel/process.c 2004-04-03 02:59:47.287164200 -0800 @@ -283,8 +283,6 @@ unsigned long thread_saved_pc(struct tas /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/mips/kernel/semaphore.c~wchan-use-ELF-sections arch/mips/kernel/semaphore.c --- 25/arch/mips/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.223173928 -0800 +++ 25-akpm/arch/mips/kernel/semaphore.c 2004-04-03 02:59:47.288164048 -0800 @@ -6,6 +6,7 @@ #include #include #include +#include #include #ifdef CONFIG_CPU_HAS_LLDSCD @@ -104,7 +105,7 @@ static inline int waking_non_zero(struct * Either form may be used in conjunction with "up()". */ -void __down_failed(struct semaphore * sem) +void __sched __down_failed(struct semaphore * sem) { struct task_struct *tsk = current; wait_queue_t wait; @@ -227,7 +228,7 @@ static inline int waking_non_zero_interr #endif /* !CONFIG_CPU_HAS_LLDSCD */ -int __down_failed_interruptible(struct semaphore * sem) +int __sched __down_failed_interruptible(struct semaphore * sem) { struct task_struct *tsk = current; wait_queue_t wait; diff -puN arch/mips/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/mips/kernel/vmlinux.lds.S --- 25/arch/mips/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.224173776 -0800 +++ 25-akpm/arch/mips/kernel/vmlinux.lds.S 2004-04-03 02:59:47.288164048 -0800 @@ -28,6 +28,7 @@ SECTIONS _text = .; /* Text and read-only data */ .text : { *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) } =0 diff -puN arch/parisc/kernel/semaphore.c~wchan-use-ELF-sections arch/parisc/kernel/semaphore.c --- 25/arch/parisc/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.225173624 -0800 +++ 25-akpm/arch/parisc/kernel/semaphore.c 2004-04-03 02:59:47.289163896 -0800 @@ -5,6 +5,7 @@ #include #include #include +#include /* * Semaphores are complex as we wish to avoid using two variables. @@ -58,7 +59,7 @@ void __up(struct semaphore *sem) sem->count += (sem->count < 0) ? 1 : - 1; -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { DOWN_HEAD @@ -74,7 +75,7 @@ void __down(struct semaphore * sem) UPDATE_COUNT } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { DOWN_HEAD diff -puN arch/parisc/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/parisc/kernel/vmlinux.lds.S --- 25/arch/parisc/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.227173320 -0800 +++ 25-akpm/arch/parisc/kernel/vmlinux.lds.S 2004-04-03 02:59:47.289163896 -0800 @@ -50,6 +50,7 @@ SECTIONS _text = .; /* Text and read-only data */ .text ALIGN(16) : { *(.text*) + SCHED_TEXT *(.PARISC.unwind) *(.fixup) *(.lock.text) /* out-of-line lock text */ diff -puN arch/ppc64/kernel/process.c~wchan-use-ELF-sections arch/ppc64/kernel/process.c --- 25/arch/ppc64/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.228173168 -0800 +++ 25-akpm/arch/ppc64/kernel/process.c 2004-04-03 02:59:47.290163744 -0800 @@ -475,8 +475,6 @@ static inline int validate_sp(unsigned l /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched (*(unsigned long *)scheduling_functions_start_here) #define last_sched (*(unsigned long *)scheduling_functions_end_here) diff -puN arch/ppc64/kernel/semaphore.c~wchan-use-ELF-sections arch/ppc64/kernel/semaphore.c --- 25/arch/ppc64/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.229173016 -0800 +++ 25-akpm/arch/ppc64/kernel/semaphore.c 2004-04-03 02:59:47.290163744 -0800 @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -70,7 +71,7 @@ void __up(struct semaphore *sem) * Thus it is only when we decrement count from some value > 0 * that we have actually got the semaphore. */ -void __down(struct semaphore *sem) +void __sched __down(struct semaphore *sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -99,7 +100,7 @@ void __down(struct semaphore *sem) wake_up(&sem->wait); } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; diff -puN arch/ppc64/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/ppc64/kernel/vmlinux.lds.S --- 25/arch/ppc64/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.231172712 -0800 +++ 25-akpm/arch/ppc64/kernel/vmlinux.lds.S 2004-04-03 02:59:47.290163744 -0800 @@ -13,6 +13,7 @@ SECTIONS /* Read-only sections, merged into text segment: */ .text : { *(.text .text.*) + SCHED_TEXT *(.fixup) . = ALIGN(4096); _etext = .; diff -puN arch/ppc/kernel/process.c~wchan-use-ELF-sections arch/ppc/kernel/process.c --- 25/arch/ppc/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.232172560 -0800 +++ 25-akpm/arch/ppc/kernel/process.c 2004-04-03 02:59:47.291163592 -0800 @@ -661,8 +661,6 @@ void __init ll_puts(const char *s) /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/ppc/kernel/semaphore.c~wchan-use-ELF-sections arch/ppc/kernel/semaphore.c --- 25/arch/ppc/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.233172408 -0800 +++ 25-akpm/arch/ppc/kernel/semaphore.c 2004-04-03 02:59:47.292163440 -0800 @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -69,7 +70,7 @@ void __up(struct semaphore *sem) * Thus it is only when we decrement count from some value > 0 * that we have actually got the semaphore. */ -void __down(struct semaphore *sem) +void __sched __down(struct semaphore *sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -99,7 +100,7 @@ void __down(struct semaphore *sem) wake_up(&sem->wait); } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; diff -puN arch/ppc/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/ppc/kernel/vmlinux.lds.S --- 25/arch/ppc/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.235172104 -0800 +++ 25-akpm/arch/ppc/kernel/vmlinux.lds.S 2004-04-03 02:59:47.292163440 -0800 @@ -31,6 +31,7 @@ SECTIONS .text : { *(.text) + SCHED_TEXT *(.fixup) *(.got1) __got2_start = .; diff -puN arch/s390/kernel/process.c~wchan-use-ELF-sections arch/s390/kernel/process.c --- 25/arch/s390/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.236171952 -0800 +++ 25-akpm/arch/s390/kernel/process.c 2004-04-03 02:59:47.292163440 -0800 @@ -384,8 +384,6 @@ void dump_thread(struct pt_regs * regs, /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/s390/kernel/semaphore.c~wchan-use-ELF-sections arch/s390/kernel/semaphore.c --- 25/arch/s390/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.237171800 -0800 +++ 25-akpm/arch/s390/kernel/semaphore.c 2004-04-03 02:59:47.293163288 -0800 @@ -11,6 +11,7 @@ */ #include #include +#include #include @@ -60,7 +61,7 @@ void __up(struct semaphore *sem) * count > 0: decrement count, wake up queue and exit. * count <= 0: set count to -1, go to sleep. */ -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -82,7 +83,7 @@ void __down(struct semaphore * sem) * count > 0: wake up queue and exit. * count <= 0: set count to 0, wake up queue and exit. */ -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; diff -puN arch/s390/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/s390/kernel/vmlinux.lds.S --- 25/arch/s390/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.238171648 -0800 +++ 25-akpm/arch/s390/kernel/vmlinux.lds.S 2004-04-03 02:59:47.293163288 -0800 @@ -23,6 +23,7 @@ SECTIONS _text = .; /* Text and read-only data */ .text : { *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) } = 0x0700 diff -puN arch/sh/kernel/process.c~wchan-use-ELF-sections arch/sh/kernel/process.c --- 25/arch/sh/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.240171344 -0800 +++ 25-akpm/arch/sh/kernel/process.c 2004-04-03 02:59:47.294163136 -0800 @@ -464,8 +464,6 @@ out: /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) @@ -481,7 +479,7 @@ unsigned long get_wchan(struct task_stru * The same comment as on the Alpha applies here, too ... */ pc = thread_saved_pc(p); - if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) { + if (pc >= first_sched && pc < last_sched) { schedule_frame = ((unsigned long *)(long)p->thread.sp)[1]; return (unsigned long)((unsigned long *)schedule_frame)[1]; } diff -puN arch/sh/kernel/semaphore.c~wchan-use-ELF-sections arch/sh/kernel/semaphore.c --- 25/arch/sh/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.241171192 -0800 +++ 25-akpm/arch/sh/kernel/semaphore.c 2004-04-03 02:59:47.294163136 -0800 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -103,7 +104,7 @@ void __up(struct semaphore *sem) tsk->state = TASK_RUNNING; \ remove_wait_queue(&sem->wait, &wait); -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { DOWN_VAR DOWN_HEAD(TASK_UNINTERRUPTIBLE) @@ -113,7 +114,7 @@ void __down(struct semaphore * sem) DOWN_TAIL(TASK_UNINTERRUPTIBLE) } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int ret = 0; DOWN_VAR diff -puN arch/sh/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/sh/kernel/vmlinux.lds.S --- 25/arch/sh/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.242171040 -0800 +++ 25-akpm/arch/sh/kernel/vmlinux.lds.S 2004-04-03 02:59:47.294163136 -0800 @@ -22,6 +22,7 @@ SECTIONS } = 0 .text : { *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) } = 0x0009 diff -puN arch/sparc64/kernel/process.c~wchan-use-ELF-sections arch/sparc64/kernel/process.c --- 25/arch/sparc64/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.243170888 -0800 +++ 25-akpm/arch/sparc64/kernel/process.c 2004-04-03 02:59:47.295162984 -0800 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -823,9 +824,6 @@ out: return error; } -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); - unsigned long get_wchan(struct task_struct *task) { unsigned long pc, fp, bias = 0; diff -puN arch/sparc64/kernel/semaphore.c~wchan-use-ELF-sections arch/sparc64/kernel/semaphore.c --- 25/arch/sparc64/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.245170584 -0800 +++ 25-akpm/arch/sparc64/kernel/semaphore.c 2004-04-03 02:59:47.296162832 -0800 @@ -8,6 +8,7 @@ #include #include +#include /* * Atomically update sem->count. @@ -90,7 +91,7 @@ void up(struct semaphore *sem) : "g5", "g7", "memory", "cc"); } -static void __down(struct semaphore * sem) +static void __sched __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -108,7 +109,7 @@ static void __down(struct semaphore * se wake_up(&sem->wait); } -void down(struct semaphore *sem) +void __sched down(struct semaphore *sem) { might_sleep(); /* This atomically does: @@ -192,7 +193,7 @@ int down_trylock(struct semaphore *sem) return ret; } -static int __down_interruptible(struct semaphore * sem) +static int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; @@ -216,7 +217,7 @@ static int __down_interruptible(struct s return retval; } -int down_interruptible(struct semaphore *sem) +int __sched down_interruptible(struct semaphore *sem) { int ret = 0; diff -puN arch/sparc64/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/sparc64/kernel/vmlinux.lds.S --- 25/arch/sparc64/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.246170432 -0800 +++ 25-akpm/arch/sparc64/kernel/vmlinux.lds.S 2004-04-03 02:59:47.296162832 -0800 @@ -15,6 +15,7 @@ SECTIONS .text 0x0000000000404000 : { *(.text) + SCHED_TEXT *(.gnu.warning) } =0 _etext = .; diff -puN arch/sparc64/lib/rwsem.c~wchan-use-ELF-sections arch/sparc64/lib/rwsem.c --- 25/arch/sparc64/lib/rwsem.c~wchan-use-ELF-sections 2004-04-03 02:59:47.248170128 -0800 +++ 25-akpm/arch/sparc64/lib/rwsem.c 2004-04-03 02:59:47.297162680 -0800 @@ -6,6 +6,7 @@ #include #include +#include #include extern struct rw_semaphore *FASTCALL(rwsem_down_read_failed(struct rw_semaphore *sem)); @@ -13,7 +14,7 @@ extern struct rw_semaphore *FASTCALL(rws extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *)); extern struct rw_semaphore *FASTCALL(rwsem_downgrade_wake(struct rw_semaphore *)); -void __down_read(struct rw_semaphore *sem) +void __sched __down_read(struct rw_semaphore *sem) { __asm__ __volatile__( "! beginning __down_read\n" @@ -72,7 +73,7 @@ int __down_read_trylock(struct rw_semaph } EXPORT_SYMBOL(__down_read_trylock); -void __down_write(struct rw_semaphore *sem) +void __sched __down_write(struct rw_semaphore *sem) { __asm__ __volatile__( "! beginning __down_write\n\t" diff -puN arch/sparc/kernel/process.c~wchan-use-ELF-sections arch/sparc/kernel/process.c --- 25/arch/sparc/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.249169976 -0800 +++ 25-akpm/arch/sparc/kernel/process.c 2004-04-03 02:59:47.297162680 -0800 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -694,9 +695,6 @@ pid_t kernel_thread(int (*fn)(void *), v return retval; } -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); - unsigned long get_wchan(struct task_struct *task) { unsigned long pc, fp, bias = 0; diff -puN arch/sparc/kernel/semaphore.c~wchan-use-ELF-sections arch/sparc/kernel/semaphore.c --- 25/arch/sparc/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.250169824 -0800 +++ 25-akpm/arch/sparc/kernel/semaphore.c 2004-04-03 02:59:47.298162528 -0800 @@ -4,6 +4,7 @@ #include #include +#include #include @@ -45,7 +46,7 @@ void __up(struct semaphore *sem) static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -78,7 +79,7 @@ void __down(struct semaphore * sem) wake_up(&sem->wait); } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; diff -puN arch/sparc/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/sparc/kernel/vmlinux.lds.S --- 25/arch/sparc/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.252169520 -0800 +++ 25-akpm/arch/sparc/kernel/vmlinux.lds.S 2004-04-03 02:59:47.298162528 -0800 @@ -12,6 +12,7 @@ SECTIONS .text 0xf0004000 : { *(.text) + SCHED_TEXT *(.gnu.warning) } =0 _etext = .; diff -puN arch/sparc/lib/rwsem.S~wchan-use-ELF-sections arch/sparc/lib/rwsem.S --- 25/arch/sparc/lib/rwsem.S~wchan-use-ELF-sections 2004-04-03 02:59:47.253169368 -0800 +++ 25-akpm/arch/sparc/lib/rwsem.S 2004-04-03 02:59:47.298162528 -0800 @@ -8,7 +8,7 @@ #include #include - .text + .section .sched.text .align 4 .globl ___down_read @@ -113,6 +113,7 @@ ___down_write: ba 2b restore %l5, %g0, %g5 + .text .globl ___up_read ___up_read: rd %psr, %g3 diff -puN arch/v850/kernel/process.c~wchan-use-ELF-sections arch/v850/kernel/process.c --- 25/arch/v850/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.254169216 -0800 +++ 25-akpm/arch/v850/kernel/process.c 2004-04-03 02:59:47.299162376 -0800 @@ -203,8 +203,6 @@ int sys_execve (char *name, char **argv, /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here (void); -extern void scheduling_functions_end_here (void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) @@ -228,7 +226,6 @@ unsigned long get_wchan (struct task_str fp >= 8184+stack_page) return 0; pc = ((unsigned long *)fp)[1]; - /* FIXME: This depends on the order of these functions. */ if (pc < first_sched || pc >= last_sched) return pc; fp = *(unsigned long *) fp; diff -puN arch/v850/kernel/semaphore.c~wchan-use-ELF-sections arch/v850/kernel/semaphore.c --- 25/arch/v850/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.255169064 -0800 +++ 25-akpm/arch/v850/kernel/semaphore.c 2004-04-03 02:59:47.299162376 -0800 @@ -15,6 +15,7 @@ #include #include +#include #include @@ -56,7 +57,7 @@ void __up(struct semaphore *sem) static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -89,7 +90,7 @@ void __down(struct semaphore * sem) wake_up(&sem->wait); } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; diff -puN arch/v850/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/v850/kernel/vmlinux.lds.S --- 25/arch/v850/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.256168912 -0800 +++ 25-akpm/arch/v850/kernel/vmlinux.lds.S 2004-04-03 02:59:47.300162224 -0800 @@ -64,6 +64,7 @@ #define TEXT_CONTENTS \ __stext = . ; \ *(.text) \ + SCHED_TEXT *(.exit.text) /* 2.5 convention */ \ *(.text.exit) /* 2.4 convention */ \ *(.text.lock) \ diff -puN arch/x86_64/kernel/process.c~wchan-use-ELF-sections arch/x86_64/kernel/process.c --- 25/arch/x86_64/kernel/process.c~wchan-use-ELF-sections 2004-04-03 02:59:47.258168608 -0800 +++ 25-akpm/arch/x86_64/kernel/process.c 2004-04-03 02:59:47.301162072 -0800 @@ -576,8 +576,6 @@ asmlinkage long sys_vfork(struct pt_regs /* * These bracket the sleeping functions.. */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) diff -puN arch/x86_64/kernel/semaphore.c~wchan-use-ELF-sections arch/x86_64/kernel/semaphore.c --- 25/arch/x86_64/kernel/semaphore.c~wchan-use-ELF-sections 2004-04-03 02:59:47.259168456 -0800 +++ 25-akpm/arch/x86_64/kernel/semaphore.c 2004-04-03 02:59:47.301162072 -0800 @@ -14,6 +14,7 @@ */ #include #include +#include #include #include @@ -54,7 +55,7 @@ void __up(struct semaphore *sem) wake_up(&sem->wait); } -void __down(struct semaphore * sem) +void __sched __down(struct semaphore * sem) { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); @@ -91,7 +92,7 @@ void __down(struct semaphore * sem) tsk->state = TASK_RUNNING; } -int __down_interruptible(struct semaphore * sem) +int __sched __down_interruptible(struct semaphore * sem) { int retval = 0; struct task_struct *tsk = current; diff -puN arch/x86_64/kernel/vmlinux.lds.S~wchan-use-ELF-sections arch/x86_64/kernel/vmlinux.lds.S --- 25/arch/x86_64/kernel/vmlinux.lds.S~wchan-use-ELF-sections 2004-04-03 02:59:47.260168304 -0800 +++ 25-akpm/arch/x86_64/kernel/vmlinux.lds.S 2004-04-03 02:59:47.301162072 -0800 @@ -15,6 +15,7 @@ SECTIONS _text = .; /* Text and read-only data */ .text : { *(.text) + SCHED_TEXT *(.fixup) *(.gnu.warning) } = 0x9090 diff -puN arch/x86_64/lib/thunk.S~wchan-use-ELF-sections arch/x86_64/lib/thunk.S --- 25/arch/x86_64/lib/thunk.S~wchan-use-ELF-sections 2004-04-03 02:59:47.261168152 -0800 +++ 25-akpm/arch/x86_64/lib/thunk.S 2004-04-03 02:59:47.302161920 -0800 @@ -35,6 +35,7 @@ .endm + .section .sched.text #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM thunk rwsem_down_read_failed_thunk,rwsem_down_read_failed thunk rwsem_down_write_failed_thunk,rwsem_down_write_failed @@ -65,7 +66,7 @@ restore_norax: #ifdef CONFIG_SMP /* Support for read/write spinlocks. */ - + .text /* rax: pointer to rwlock_t */ ENTRY(__write_lock_failed) lock diff -puN include/asm-generic/vmlinux.lds.h~wchan-use-ELF-sections include/asm-generic/vmlinux.lds.h --- 25/include/asm-generic/vmlinux.lds.h~wchan-use-ELF-sections 2004-04-03 02:59:47.263167848 -0800 +++ 25-akpm/include/asm-generic/vmlinux.lds.h 2004-04-03 02:59:47.302161920 -0800 @@ -51,3 +51,8 @@ *(.security_initcall.init) \ __security_initcall_end = .; \ } + +#define SCHED_TEXT \ + __scheduling_functions_start_here = .; \ + *(.sched.text) \ + __scheduling_functions_end_here = .; diff -puN include/linux/init.h~wchan-use-ELF-sections include/linux/init.h --- 25/include/linux/init.h~wchan-use-ELF-sections 2004-04-03 02:59:47.264167696 -0800 +++ 25-akpm/include/linux/init.h 2004-04-03 02:59:47.302161920 -0800 @@ -46,6 +46,8 @@ #define __exitdata __attribute__ ((__section__(".exit.data"))) #define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) +#define __sched __attribute__((__section__(".sched.text"))) + #ifdef MODULE #define __exit __attribute__ ((__section__(".exit.text"))) #else diff -puN include/linux/sched.h~wchan-use-ELF-sections include/linux/sched.h --- 25/include/linux/sched.h~wchan-use-ELF-sections 2004-04-03 02:59:47.266167392 -0800 +++ 25-akpm/include/linux/sched.h 2004-04-03 02:59:47.303161768 -0800 @@ -170,6 +170,8 @@ extern void update_one_process(struct ta unsigned long system, int cpu); extern void scheduler_tick(int user_tick, int system); extern unsigned long cache_decay_ticks; +extern const unsigned long scheduling_functions_start_here; +extern const unsigned long scheduling_functions_end_here; #define MAX_SCHEDULE_TIMEOUT LONG_MAX diff -puN kernel/sched.c~wchan-use-ELF-sections kernel/sched.c --- 25/kernel/sched.c~wchan-use-ELF-sections 2004-04-03 02:59:47.267167240 -0800 +++ 25-akpm/kernel/sched.c 2004-04-03 02:59:47.306161312 -0800 @@ -225,6 +225,13 @@ static DEFINE_PER_CPU(struct runqueue, r #define task_rq(p) cpu_rq(task_cpu(p)) #define cpu_curr(cpu) (cpu_rq(cpu)->curr) +extern unsigned long __scheduling_functions_start_here; +extern unsigned long __scheduling_functions_end_here; +const unsigned long scheduling_functions_start_here = + (unsigned long)&__scheduling_functions_start_here; +const unsigned long scheduling_functions_end_here = + (unsigned long)&__scheduling_functions_end_here; + /* * Default context-switch locking: */ @@ -1587,12 +1594,10 @@ out: rebalance_tick(rq, 0); } -void scheduling_functions_start_here(void) { } - /* * schedule() is the main scheduler function. */ -asmlinkage void schedule(void) +asmlinkage void __sched schedule(void) { long *switch_count; task_t *prev, *next; @@ -1731,7 +1736,7 @@ EXPORT_SYMBOL(schedule); * off of preempt_enable. Kernel preemptions off return from interrupt * occur there and call schedule directly. */ -asmlinkage void preempt_schedule(void) +asmlinkage void __sched preempt_schedule(void) { struct thread_info *ti = current_thread_info(); @@ -1869,7 +1874,7 @@ void fastcall complete_all(struct comple spin_unlock_irqrestore(&x->wait.lock, flags); } -void fastcall wait_for_completion(struct completion *x) +void fastcall __sched wait_for_completion(struct completion *x) { might_sleep(); spin_lock_irq(&x->wait.lock); @@ -1907,7 +1912,7 @@ EXPORT_SYMBOL(wait_for_completion); __remove_wait_queue(q, &wait); \ spin_unlock_irqrestore(&q->lock, flags); -void fastcall interruptible_sleep_on(wait_queue_head_t *q) +void fastcall __sched interruptible_sleep_on(wait_queue_head_t *q) { SLEEP_ON_VAR @@ -1920,7 +1925,7 @@ void fastcall interruptible_sleep_on(wai EXPORT_SYMBOL(interruptible_sleep_on); -long fastcall interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) +long fastcall __sched interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) { SLEEP_ON_VAR @@ -1935,7 +1940,7 @@ long fastcall interruptible_sleep_on_tim EXPORT_SYMBOL(interruptible_sleep_on_timeout); -void fastcall sleep_on(wait_queue_head_t *q) +void fastcall __sched sleep_on(wait_queue_head_t *q) { SLEEP_ON_VAR @@ -1948,7 +1953,7 @@ void fastcall sleep_on(wait_queue_head_t EXPORT_SYMBOL(sleep_on); -long fastcall sleep_on_timeout(wait_queue_head_t *q, long timeout) +long fastcall __sched sleep_on_timeout(wait_queue_head_t *q, long timeout) { SLEEP_ON_VAR @@ -1963,8 +1968,6 @@ long fastcall sleep_on_timeout(wait_queu EXPORT_SYMBOL(sleep_on_timeout); -void scheduling_functions_end_here(void) { } - void set_user_nice(task_t *p, long nice) { unsigned long flags; @@ -2424,7 +2427,7 @@ asmlinkage long sys_sched_yield(void) return 0; } -void __cond_resched(void) +void __sched __cond_resched(void) { set_current_state(TASK_RUNNING); schedule(); @@ -2438,7 +2441,7 @@ EXPORT_SYMBOL(__cond_resched); * this is a shortcut for kernel-space yielding - it marks the * thread runnable and calls sys_sched_yield(). */ -void yield(void) +void __sched yield(void) { set_current_state(TASK_RUNNING); sys_sched_yield(); @@ -2453,7 +2456,7 @@ EXPORT_SYMBOL(yield); * But don't do that if it is a deliberate, throttling IO wait (this task * has set its backing_dev_info: the queue against which it should throttle) */ -void io_schedule(void) +void __sched io_schedule(void) { struct runqueue *rq = this_rq(); @@ -2464,7 +2467,7 @@ void io_schedule(void) EXPORT_SYMBOL(io_schedule); -long io_schedule_timeout(long timeout) +long __sched io_schedule_timeout(long timeout) { struct runqueue *rq = this_rq(); long ret; @@ -3010,7 +3013,7 @@ EXPORT_SYMBOL(__might_sleep); * * Called inside preempt_disable(). */ -void __preempt_spin_lock(spinlock_t *lock) +void __sched __preempt_spin_lock(spinlock_t *lock) { if (preempt_count() > 1) { _raw_spin_lock(lock); @@ -3026,7 +3029,7 @@ void __preempt_spin_lock(spinlock_t *loc EXPORT_SYMBOL(__preempt_spin_lock); -void __preempt_write_lock(rwlock_t *lock) +void __sched __preempt_write_lock(rwlock_t *lock) { if (preempt_count() > 1) { _raw_write_lock(lock); diff -puN kernel/timer.c~wchan-use-ELF-sections kernel/timer.c --- 25/kernel/timer.c~wchan-use-ELF-sections 2004-04-03 02:59:47.269166936 -0800 +++ 25-akpm/kernel/timer.c 2004-04-03 02:59:47.307161160 -0800 @@ -996,7 +996,7 @@ static void process_timeout(unsigned lon * * In all cases the return value is guaranteed to be non-negative. */ -fastcall signed long schedule_timeout(signed long timeout) +fastcall signed long __sched schedule_timeout(signed long timeout) { struct timer_list timer; unsigned long expire; @@ -1056,7 +1056,7 @@ asmlinkage long sys_gettid(void) return current->pid; } -static long nanosleep_restart(struct restart_block *restart) +static long __sched nanosleep_restart(struct restart_block *restart) { unsigned long expire = restart->arg0, now = jiffies; struct timespec __user *rmtp = (struct timespec __user *) restart->arg1; diff -puN lib/rwsem.c~wchan-use-ELF-sections lib/rwsem.c --- 25/lib/rwsem.c~wchan-use-ELF-sections 2004-04-03 02:59:47.270166784 -0800 +++ 25-akpm/lib/rwsem.c 2004-04-03 02:59:47.308161008 -0800 @@ -5,6 +5,7 @@ */ #include #include +#include #include struct rwsem_waiter { @@ -162,7 +163,7 @@ static inline struct rw_semaphore *rwsem /* * wait for the read lock to be granted */ -struct rw_semaphore fastcall *rwsem_down_read_failed(struct rw_semaphore *sem) +struct rw_semaphore fastcall __sched *rwsem_down_read_failed(struct rw_semaphore *sem) { struct rwsem_waiter waiter; @@ -178,7 +179,7 @@ struct rw_semaphore fastcall *rwsem_down /* * wait for the write lock to be granted */ -struct rw_semaphore fastcall *rwsem_down_write_failed(struct rw_semaphore *sem) +struct rw_semaphore fastcall __sched *rwsem_down_write_failed(struct rw_semaphore *sem) { struct rwsem_waiter waiter; _