diff options
| -rw-r--r-- | arch/alpha/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/arm/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/arm26/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/cris/arch-v10/kernel/process.c | 4 | ||||
| -rw-r--r-- | arch/h8300/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/i386/kernel/process.c | 9 | ||||
| -rw-r--r-- | arch/ia64/kernel/process.c | 9 | ||||
| -rw-r--r-- | arch/m68k/kernel/process.c | 11 | ||||
| -rw-r--r-- | arch/m68knommu/kernel/process.c | 11 | ||||
| -rw-r--r-- | arch/mips/kernel/process.c | 10 | ||||
| -rw-r--r-- | arch/ppc/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/ppc64/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/s390/kernel/process.c | 10 | ||||
| -rw-r--r-- | arch/sh/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/sparc/kernel/process.c | 3 | ||||
| -rw-r--r-- | arch/sparc64/kernel/process.c | 3 | ||||
| -rw-r--r-- | arch/v850/kernel/process.c | 4 | ||||
| -rw-r--r-- | arch/x86_64/kernel/process.c | 10 | ||||
| -rw-r--r-- | include/asm-generic/vmlinux.lds.h | 4 | ||||
| -rw-r--r-- | include/linux/init.h | 2 | ||||
| -rw-r--r-- | include/linux/sched.h | 6 | ||||
| -rw-r--r-- | kernel/sched.c | 15 |
22 files changed, 37 insertions, 130 deletions
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 297e4b48bfe2..5bf982285994 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -510,12 +510,6 @@ thread_saved_pc(task_t *t) return 0; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { @@ -534,7 +528,7 @@ get_wchan(struct task_struct *p) */ pc = thread_saved_pc(p); - if (pc >= first_sched && pc < last_sched) { + if (in_sched_functions(pc)) { schedule_frame = ((unsigned long *)p->thread_info->pcb.ksp)[6]; return ((unsigned long *)schedule_frame)[12]; } diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 8423921e821a..1269dd26b5f6 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -411,12 +411,6 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long fp, lr; @@ -431,7 +425,7 @@ unsigned long get_wchan(struct task_struct *p) if (fp < stack_page || fp > 4092+stack_page) return 0; lr = pc_pointer (((unsigned long *)fp)[-1]); - if (lr < first_sched || lr > last_sched) + if (!in_sched_functions(lr)) return lr; fp = *(unsigned long *) (fp - 12); } while (count ++ < 16); diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c index ce23571617a1..5b4efd62029f 100644 --- a/arch/arm26/kernel/process.c +++ b/arch/arm26/kernel/process.c @@ -397,12 +397,6 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) return __ret; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long fp, lr; @@ -417,7 +411,7 @@ unsigned long get_wchan(struct task_struct *p) if (fp < stack_page || fp > 4092+stack_page) return 0; lr = pc_pointer (((unsigned long *)fp)[-1]); - if (lr < first_sched || lr > last_sched) + if (!in_sched_functions(lr)) return lr; fp = *(unsigned long *) (fp - 12); } while (count ++ < 16); diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index c785b54e6cbd..7ad7942804d0 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c @@ -217,8 +217,8 @@ asmlinkage int sys_execve(const char *fname, char **argv, char **envp, * These bracket the sleeping functions.. */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) +#define first_sched ((unsigned long)__sched_text_start) +#define last_sched ((unsigned long)__sched_text_end) unsigned long get_wchan(struct task_struct *p) { diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index afe7417c02c8..81cb7495e4a1 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -261,12 +261,6 @@ out: return error; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long thread_saved_pc(struct task_struct *tsk) { return ((struct pt_regs *)tsk->thread.esp0)->pc; @@ -287,7 +281,7 @@ unsigned long get_wchan(struct task_struct *p) fp >= 8184+stack_page) return 0; pc = ((unsigned long *)fp)[1]; - if (pc < first_sched || pc >= last_sched) + if (!in_sched_functions(pc)) return pc; fp = *(unsigned long *) fp; } while (count++ < 16); diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 2e61c5d9a959..fcd313922c95 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -633,11 +633,6 @@ out: return error; } -/* - * These bracket the sleeping functions.. - */ -#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)) #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) @@ -658,14 +653,12 @@ unsigned long get_wchan(struct task_struct *p) if (ebp < stack_page || ebp > top_ebp+stack_page) return 0; eip = *(unsigned long *) (ebp+4); - if (eip < first_sched || eip >= last_sched) + if (!in_sched_functions(eip)) return eip; ebp = *(unsigned long *) ebp; } while (count++ < 16); return 0; } -#undef last_sched -#undef first_sched /* * sys_alloc_thread_area: get a yet unused TLS descriptor index. diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 0d245cbcd1f6..a210e44b509b 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -657,11 +657,6 @@ get_wchan (struct task_struct *p) struct unw_frame_info info; unsigned long ip; int count = 0; - /* - * These bracket the sleeping functions.. - */ -# define first_sched ((unsigned long) scheduling_functions_start_here) -# define last_sched ((unsigned long) scheduling_functions_end_here) /* * Note: p may not be a blocked task (it could be current or @@ -676,12 +671,10 @@ get_wchan (struct task_struct *p) if (unw_unwind(&info) < 0) return 0; unw_get_ip(&info, &ip); - if (ip < first_sched || ip >= last_sched) + if (!in_sched_functions(ip)) return ip; } while (count++ < 16); return 0; -# undef first_sched -# undef last_sched } void diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index a270b5ff3aca..552bd2ff1436 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -67,8 +67,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) { 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 && - sw->retpc < (unsigned long)scheduling_functions_end_here) + if (in_sched_functions(sw->retpc)) return ((unsigned long *)sw->a6)[1]; else return sw->retpc; @@ -382,12 +381,6 @@ out: return error; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long fp, pc; @@ -403,7 +396,7 @@ unsigned long get_wchan(struct task_struct *p) fp >= 8184+stack_page) return 0; pc = ((unsigned long *)fp)[1]; - if (pc < first_sched || pc >= last_sched) + if (!in_sched_functions(pc)) return pc; fp = *(unsigned long *) fp; } while (count++ < 16); diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 6d9f428ef7a4..581eef2b796b 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -404,12 +404,6 @@ out: return error; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long fp, pc; @@ -425,7 +419,7 @@ unsigned long get_wchan(struct task_struct *p) fp >= 8184+stack_page) return 0; pc = ((unsigned long *)fp)[1]; - if (pc < first_sched || pc >= last_sched) + if (!in_sched_functions(pc)) return pc; fp = *(unsigned long *) fp; } while (count++ < 16); @@ -440,8 +434,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) 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 && - sw->retpc < (unsigned long)scheduling_functions_end_here) + if (in_sched_functions(sw->retpc)) return ((unsigned long *)sw->a6)[1]; else return sw->retpc; diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index f4ab9c66b27f..4bb61f32c97f 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -280,12 +280,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk) return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - /* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ unsigned long get_wchan(struct task_struct *p) { @@ -297,7 +291,7 @@ unsigned long get_wchan(struct task_struct *p) if (!mips_frame_info_initialized) return 0; pc = thread_saved_pc(p); - if (pc < first_sched || pc >= last_sched) + if (!in_sched_functions(pc)) goto out; if (pc >= (unsigned long) sleep_on_timeout) @@ -331,7 +325,7 @@ schedule_timeout_caller: */ pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset]; - if (pc >= first_sched && pc < last_sched) { + if (in_sched_functions(pc)) { /* schedule_timeout called by [interruptible_]sleep_on_timeout */ frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset]; pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset]; diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 7e47f388e1a4..19515a1f9734 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -668,12 +668,6 @@ void __init ll_puts(const char *s) } #endif -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long ip, sp; @@ -688,7 +682,7 @@ unsigned long get_wchan(struct task_struct *p) return 0; if (count > 0) { ip = *(unsigned long *)(sp + 4); - if (ip < first_sched || ip >= last_sched) + if (!in_sched_functions(ip)) return ip; } } while (count++ < 16); diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index a64973cf5862..c88ea00e88ea 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c @@ -469,12 +469,6 @@ static inline int validate_sp(unsigned long sp, struct task_struct *p) return 1; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched (*(unsigned long *)scheduling_functions_start_here) -#define last_sched (*(unsigned long *)scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long ip, sp; @@ -493,7 +487,7 @@ unsigned long get_wchan(struct task_struct *p) return 0; if (count > 0) { ip = *(unsigned long *)(sp + 16); - if (ip < first_sched || ip >= last_sched) + if (!in_sched_functions(ip)) return ip; } } while (count++ < 16); diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 252e652cd5a0..a18d5f444a51 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -385,12 +385,6 @@ void dump_thread(struct pt_regs * regs, struct user * dump) dump->regs.per_info = current->thread.per_info; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long r14, r15, bc; @@ -413,12 +407,10 @@ unsigned long get_wchan(struct task_struct *p) #else r14 = *(unsigned long *) (bc+112); #endif - if (r14 < first_sched || r14 >= last_sched) + if (!in_sched_functions(r14)) return r14; bc = (*(unsigned long *) bc) & PSW_ADDR_INSN; } while (count++ < 16); return 0; } -#undef last_sched -#undef first_sched diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 7d45ea0acd09..6b4cb096b11c 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -461,12 +461,6 @@ out: return error; } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long schedule_frame; @@ -479,7 +473,7 @@ unsigned long get_wchan(struct task_struct *p) * The same comment as on the Alpha applies here, too ... */ pc = thread_saved_pc(p); - if (pc >= first_sched && pc < last_sched) { + if (in_sched_functions(pc)) { schedule_frame = ((unsigned long *)(long)p->thread.sp)[1]; return (unsigned long)((unsigned long *)schedule_frame)[1]; } diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 13b3ac47b3c0..46d31c7f6035 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -721,8 +721,7 @@ unsigned long get_wchan(struct task_struct *task) break; rw = (struct reg_window *) fp; pc = rw->ins[7]; - if (pc < ((unsigned long) scheduling_functions_start_here) || - pc >= ((unsigned long) scheduling_functions_end_here)) { + if (!in_sched_functions(pc)) { ret = pc; goto out; } diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index f6d3364624c3..a229c05cccac 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -847,8 +847,7 @@ unsigned long get_wchan(struct task_struct *task) break; rw = (struct reg_window *) fp; pc = rw->ins[7]; - if (pc < ((unsigned long) scheduling_functions_start_here) || - pc >= ((unsigned long) scheduling_functions_end_here)) { + if (!in_sched_functions(pc)) { ret = pc; goto out; } diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c index 2fccb4cc7b82..9c708c32c1f0 100644 --- a/arch/v850/kernel/process.c +++ b/arch/v850/kernel/process.c @@ -203,8 +203,8 @@ int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs) /* * These bracket the sleeping functions.. */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) +#define first_sched ((unsigned long)__sched_text_start) +#define last_sched ((unsigned long)__sched_text_end) unsigned long get_wchan (struct task_struct *p) { diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index e80d5eb1b699..6b78619452e7 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -574,12 +574,6 @@ asmlinkage long sys_vfork(struct pt_regs regs) NULL, NULL); } -/* - * These bracket the sleeping functions.. - */ -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - unsigned long get_wchan(struct task_struct *p) { unsigned long stack; @@ -596,14 +590,12 @@ unsigned long get_wchan(struct task_struct *p) if (fp < (unsigned long)stack || fp > (unsigned long)stack+THREAD_SIZE) return 0; rip = *(u64 *)(fp+8); - if (rip < first_sched || rip >= last_sched) + if (!in_sched_functions(rip)) return rip; fp = *(u64 *)fp; } while (count++ < 16); return 0; } -#undef last_sched -#undef first_sched long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) { diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index a4b6c768cf49..4d0cff2860d1 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -53,6 +53,6 @@ } #define SCHED_TEXT \ - __scheduling_functions_start_here = .; \ + __sched_text_start = .; \ *(.sched.text) \ - __scheduling_functions_end_here = .; + __sched_text_end = .; diff --git a/include/linux/init.h b/include/linux/init.h index c6842477243c..45069e275b3d 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -46,8 +46,6 @@ #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 --git a/include/linux/sched.h b/include/linux/sched.h index 9d813de1e4b5..9de4c32a81dd 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -172,9 +172,11 @@ extern void update_one_process(struct task_struct *p, unsigned long user, 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; +/* Attach to any functions which should be ignored in wchan output. */ +#define __sched __attribute__((__section__(".sched.text"))) +/* Is this address in the __sched functions? */ +extern int in_sched_functions(unsigned long addr); #define MAX_SCHEDULE_TIMEOUT LONG_MAX extern signed long FASTCALL(schedule_timeout(signed long timeout)); diff --git a/kernel/sched.c b/kernel/sched.c index d083166dd3f0..ad9bf33f11c6 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -252,13 +252,6 @@ static DEFINE_PER_CPU(struct runqueue, runqueues); #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: */ @@ -3852,6 +3845,14 @@ void __init sched_init_smp(void) } #endif /* CONFIG_SMP */ +int in_sched_functions(unsigned long addr) +{ + /* Linker adds these: start and end of __sched functions */ + extern char __sched_text_start[], __sched_text_end[]; + return addr >= (unsigned long)__sched_text_start + && addr < (unsigned long)__sched_text_end; +} + void __init sched_init(void) { runqueue_t *rq; |
