Commit a7c8a1d3 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] sched: in_sched_functions() cleanup

From: Rusty Russell <rusty@rustcorp.com.au>

1) Create an in_sched_functions() function in sched.c and make the
   archs use it.  (Two archs have wchan #if 0'd out: left them alone).

2) Move __sched from linux/init.h to linux/sched.h and add comment.

3) Rename __scheduling_functions_start_here/end_here to __sched_text_start/end.

Thanks to wli and Sam Ravnborg for clue donation.
parent e736428d
......@@ -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];
}
......
......@@ -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, &regs, 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);
......
......@@ -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);
......
......@@ -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)
{
......
......@@ -261,12 +261,6 @@ asmlinkage int sys_execve(char *name, char **argv, char **envp,int dummy,...)
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);
......
......@@ -633,11 +633,6 @@ asmlinkage int sys_execve(struct pt_regs regs)
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.
......
......@@ -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
......
......@@ -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 @@ asmlinkage int sys_execve(char *name, char **argv, char **envp)
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);
......
......@@ -404,12 +404,6 @@ asmlinkage int sys_execve(char *name, char **argv, char **envp)
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;
......
......@@ -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 @@ unsigned long get_wchan(struct task_struct *p)
*/
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];
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......@@ -461,12 +461,6 @@ asmlinkage int sys_execve(char *ufilename, char **uargv,
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];
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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)
{
......
......@@ -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)
{
......
......@@ -53,6 +53,6 @@
}
#define SCHED_TEXT \
__scheduling_functions_start_here = .; \
__sched_text_start = .; \
*(.sched.text) \
__scheduling_functions_end_here = .;
__sched_text_end = .;
......@@ -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
......
......@@ -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));
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment