summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-04-11 22:41:20 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-11 22:41:20 -0700
commitb283f09cf8f51c29bf90e42e22099f76d0f33378 (patch)
tree7aee46f073ec3c8fc678b64eb430e2958ff0de1e
parentee28db843649533f5650186251ae4a8bd49a3da9 (diff)
[PATCH] Fix get_wchan() FIXME wrt. order of functions
From: William Lee Irwin III <wli@holomorphy.com> 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.
-rw-r--r--arch/alpha/kernel/process.c2
-rw-r--r--arch/alpha/kernel/semaphore.c9
-rw-r--r--arch/alpha/kernel/vmlinux.lds.S1
-rw-r--r--arch/arm/kernel/process.c2
-rw-r--r--arch/arm/kernel/semaphore.c8
-rw-r--r--arch/arm/kernel/vmlinux.lds.S1
-rw-r--r--arch/arm26/kernel/process.c2
-rw-r--r--arch/arm26/kernel/semaphore.c8
-rw-r--r--arch/arm26/kernel/vmlinux-arm26-xip.lds.in1
-rw-r--r--arch/arm26/kernel/vmlinux-arm26.lds.in1
-rw-r--r--arch/cris/arch-v10/kernel/process.c3
-rw-r--r--arch/cris/arch-v10/vmlinux.lds.S1
-rw-r--r--arch/cris/kernel/semaphore.c5
-rw-r--r--arch/h8300/kernel/process.c3
-rw-r--r--arch/h8300/kernel/semaphore.c5
-rw-r--r--arch/h8300/kernel/vmlinux.lds.S1
-rw-r--r--arch/i386/kernel/process.c2
-rw-r--r--arch/i386/kernel/semaphore.c17
-rw-r--r--arch/i386/kernel/vmlinux.lds.S1
-rw-r--r--arch/ia64/kernel/process.c2
-rw-r--r--arch/ia64/kernel/semaphore.c7
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S1
-rw-r--r--arch/m68k/kernel/process.c5
-rw-r--r--arch/m68k/kernel/semaphore.c5
-rw-r--r--arch/m68k/kernel/vmlinux-std.lds1
-rw-r--r--arch/m68k/kernel/vmlinux-sun3.lds1
-rw-r--r--arch/m68knommu/kernel/process.c5
-rw-r--r--arch/m68knommu/kernel/semaphore.c5
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S1
-rw-r--r--arch/mips/kernel/process.c2
-rw-r--r--arch/mips/kernel/semaphore.c5
-rw-r--r--arch/mips/kernel/vmlinux.lds.S1
-rw-r--r--arch/parisc/kernel/semaphore.c5
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S1
-rw-r--r--arch/ppc/kernel/process.c2
-rw-r--r--arch/ppc/kernel/semaphore.c5
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S1
-rw-r--r--arch/ppc64/kernel/process.c2
-rw-r--r--arch/ppc64/kernel/semaphore.c5
-rw-r--r--arch/ppc64/kernel/vmlinux.lds.S1
-rw-r--r--arch/s390/kernel/process.c2
-rw-r--r--arch/s390/kernel/semaphore.c5
-rw-r--r--arch/s390/kernel/vmlinux.lds.S1
-rw-r--r--arch/sh/kernel/process.c4
-rw-r--r--arch/sh/kernel/semaphore.c5
-rw-r--r--arch/sh/kernel/vmlinux.lds.S1
-rw-r--r--arch/sparc/kernel/process.c4
-rw-r--r--arch/sparc/kernel/semaphore.c5
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S1
-rw-r--r--arch/sparc/lib/rwsem.S3
-rw-r--r--arch/sparc64/kernel/process.c4
-rw-r--r--arch/sparc64/kernel/semaphore.c9
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S1
-rw-r--r--arch/sparc64/lib/rwsem.c5
-rw-r--r--arch/v850/kernel/process.c3
-rw-r--r--arch/v850/kernel/semaphore.c5
-rw-r--r--arch/v850/kernel/vmlinux.lds.S1
-rw-r--r--arch/x86_64/kernel/process.c2
-rw-r--r--arch/x86_64/kernel/semaphore.c5
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S1
-rw-r--r--arch/x86_64/lib/thunk.S3
-rw-r--r--include/asm-generic/vmlinux.lds.h5
-rw-r--r--include/linux/init.h2
-rw-r--r--include/linux/sched.h2
-rw-r--r--kernel/sched.c37
-rw-r--r--kernel/timer.c4
-rw-r--r--lib/rwsem.c5
67 files changed, 137 insertions, 124 deletions
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index e427bae12ffe..297e4b48bfe2 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -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 --git a/arch/alpha/kernel/semaphore.c b/arch/alpha/kernel/semaphore.c
index b52a0df303fe..4d60a0ccd6f7 100644
--- a/arch/alpha/kernel/semaphore.c
+++ b/arch/alpha/kernel/semaphore.c
@@ -7,6 +7,7 @@
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/init.h>
/*
* This is basically the PPC semaphore scheme ported to use
@@ -60,7 +61,7 @@ static inline int __sem_update_count(struct semaphore *sem, int incr)
* 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 --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 7afd00d5d46b..d159b8f0d022 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -17,6 +17,7 @@ SECTIONS
_text = .; /* Text and read-only data */
.text : {
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
} :kernel
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 863c4076daad..8423921e821a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -414,8 +414,6 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
/*
* 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 --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
index a50902e8bec7..da39eb3dca31 100644
--- a/arch/arm/kernel/semaphore.c
+++ b/arch/arm/kernel/semaphore.c
@@ -13,6 +13,7 @@
*/
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <asm/semaphore.h>
@@ -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 * sem)
* 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 --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 56af3401b34d..a5db0ddca6a4 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -73,6 +73,7 @@ SECTIONS
.text : { /* Real text segment */
_text = .; /* Text and read-only data */
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
*(.rodata)
diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
index 09a2f52ad8a8..ce23571617a1 100644
--- a/arch/arm26/kernel/process.c
+++ b/arch/arm26/kernel/process.c
@@ -400,8 +400,6 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
/*
* 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 --git a/arch/arm26/kernel/semaphore.c b/arch/arm26/kernel/semaphore.c
index e7964ce1d0d9..60591a738592 100644
--- a/arch/arm26/kernel/semaphore.c
+++ b/arch/arm26/kernel/semaphore.c
@@ -15,6 +15,7 @@
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <asm/semaphore.h>
@@ -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 * sem)
* 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 --git a/arch/arm26/kernel/vmlinux-arm26-xip.lds.in b/arch/arm26/kernel/vmlinux-arm26-xip.lds.in
index 602a77c022d7..61eedf0bc42f 100644
--- a/arch/arm26/kernel/vmlinux-arm26-xip.lds.in
+++ b/arch/arm26/kernel/vmlinux-arm26-xip.lds.in
@@ -66,6 +66,7 @@ SECTIONS
.text : { /* Real text segment */
_text = .; /* Text and read-only data */
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
*(.rodata)
diff --git a/arch/arm26/kernel/vmlinux-arm26.lds.in b/arch/arm26/kernel/vmlinux-arm26.lds.in
index 8782fe36f0a8..2393f3805a49 100644
--- a/arch/arm26/kernel/vmlinux-arm26.lds.in
+++ b/arch/arm26/kernel/vmlinux-arm26.lds.in
@@ -67,6 +67,7 @@ SECTIONS
.text : { /* Real text segment */
_text = .; /* Text and read-only data */
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
*(.rodata)
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c
index 62e3a4fbf33a..c785b54e6cbd 100644
--- a/arch/cris/arch-v10/kernel/process.c
+++ b/arch/cris/arch-v10/kernel/process.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/slab.h>
+#include <linux/init.h>
#ifdef CONFIG_ETRAX_GPIO
void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */
@@ -216,8 +217,6 @@ asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
* 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 --git a/arch/cris/arch-v10/vmlinux.lds.S b/arch/cris/arch-v10/vmlinux.lds.S
index b2c27e147f29..6b73a2c0dad8 100644
--- a/arch/cris/arch-v10/vmlinux.lds.S
+++ b/arch/cris/arch-v10/vmlinux.lds.S
@@ -25,6 +25,7 @@ SECTIONS
__stext = .;
.text : {
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.text.__*)
}
diff --git a/arch/cris/kernel/semaphore.c b/arch/cris/kernel/semaphore.c
index d62b355e1706..b884263d3cd4 100644
--- a/arch/cris/kernel/semaphore.c
+++ b/arch/cris/kernel/semaphore.c
@@ -4,6 +4,7 @@
*/
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/semaphore-helper.h>
/*
@@ -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 --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index bd6ccd542399..8640ea20dba0 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -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_struct *p)
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 --git a/arch/h8300/kernel/semaphore.c b/arch/h8300/kernel/semaphore.c
index 690efce1e437..1ebb79baaa8c 100644
--- a/arch/h8300/kernel/semaphore.c
+++ b/arch/h8300/kernel/semaphore.c
@@ -5,6 +5,7 @@
#include <linux/config.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/semaphore-helper.h>
#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 --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 60787f07eb2b..3a643954a8fe 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -82,6 +82,7 @@ SECTIONS
#endif
__stext = . ;
*(.text)
+ SCHED_TEXT
. = ALIGN(0x4) ;
*(.exit.text)
*(.text.*)
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 3495f1aedf67..7fed9d3823ed 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -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 --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c
index 5acd544f0cbd..073912cfcf44 100644
--- a/arch/i386/kernel/semaphore.c
+++ b/arch/i386/kernel/semaphore.c
@@ -15,6 +15,7 @@
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/err.h>
+#include <linux/init.h>
#include <asm/semaphore.h>
/*
@@ -53,7 +54,7 @@ asmlinkage void __up(struct semaphore *sem)
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 * sem)
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 semaphore * 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 --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 3623d7e2934a..0253c586547b 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -16,6 +16,7 @@ SECTIONS
_text = .; /* Text and read-only data */
.text : {
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
} = 0x9090
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index a1d09d5c91c4..0d245cbcd1f6 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -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 --git a/arch/ia64/kernel/semaphore.c b/arch/ia64/kernel/semaphore.c
index f3926a3c4d73..2724ef3fbae2 100644
--- a/arch/ia64/kernel/semaphore.c
+++ b/arch/ia64/kernel/semaphore.c
@@ -24,6 +24,7 @@
* <asm/semaphore.h> where we want to avoid any extra jumps and calls.
*/
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/errno.h>
#include <asm/semaphore.h>
@@ -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 --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index e5589e49d9da..5c45718a9c82 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -41,6 +41,7 @@ SECTIONS
{
*(.text.ivt)
*(.text)
+ SCHED_TEXT
*(.gnu.linkonce.t*)
}
.text2 : AT(ADDR(.text2) - LOAD_OFFSET)
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 8d72a5c5b0c7..fc2c753c332b 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -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_struct *p)
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 --git a/arch/m68k/kernel/semaphore.c b/arch/m68k/kernel/semaphore.c
index 690efce1e437..1ebb79baaa8c 100644
--- a/arch/m68k/kernel/semaphore.c
+++ b/arch/m68k/kernel/semaphore.c
@@ -5,6 +5,7 @@
#include <linux/config.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/semaphore-helper.h>
#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 --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index bd41fc992169..6dc62684c7b9 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -12,6 +12,7 @@ SECTIONS
_text = .; /* Text and read-only data */
.text : {
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
} = 0x4e75
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index 2e81cde14987..f293e567192c 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -13,6 +13,7 @@ SECTIONS
.text : {
*(.head)
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
} = 0x4e75
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index c8b87371641a..896d596a1bd8 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -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_struct *p)
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_struct *p)
*/
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 --git a/arch/m68knommu/kernel/semaphore.c b/arch/m68knommu/kernel/semaphore.c
index 33d704fcf883..c083f4772add 100644
--- a/arch/m68knommu/kernel/semaphore.c
+++ b/arch/m68knommu/kernel/semaphore.c
@@ -6,6 +6,7 @@
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/err.h>
+#include <linux/init.h>
#include <asm/semaphore-helper.h>
#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 --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 1ab8a31ef964..a362870b6e4e 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -191,6 +191,7 @@ SECTIONS {
.text : {
_stext = . ;
*(.text)
+ SCHED_TEXT
*(.text.lock)
. = ALIGN(16); /* Exception table */
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index f8ba26770bf4..f4ab9c66b27f 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -283,8 +283,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
/*
* 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 --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c
index 11b937f20604..51c3e772c029 100644
--- a/arch/mips/kernel/semaphore.c
+++ b/arch/mips/kernel/semaphore.c
@@ -6,6 +6,7 @@
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/sched.h>
#ifdef CONFIG_CPU_HAS_LLDSCD
@@ -104,7 +105,7 @@ static inline int waking_non_zero(struct semaphore *sem)
* 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_interruptible(struct semaphore *sem,
#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 --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index b72639f8db65..098cfaa23c0e 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -28,6 +28,7 @@ SECTIONS
_text = .; /* Text and read-only data */
.text : {
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
} =0
diff --git a/arch/parisc/kernel/semaphore.c b/arch/parisc/kernel/semaphore.c
index ffb4851451fc..ee806bcc3726 100644
--- a/arch/parisc/kernel/semaphore.c
+++ b/arch/parisc/kernel/semaphore.c
@@ -5,6 +5,7 @@
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
+#include <linux/init.h>
/*
* 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 --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 14d0882a19d2..e5d5aeef96e5 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -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 --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index ada32baeda19..3363a030e00f 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -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 --git a/arch/ppc/kernel/semaphore.c b/arch/ppc/kernel/semaphore.c
index 7bf51fba5c14..2fe429b27c14 100644
--- a/arch/ppc/kernel/semaphore.c
+++ b/arch/ppc/kernel/semaphore.c
@@ -15,6 +15,7 @@
*/
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
#include <asm/errno.h>
@@ -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 --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 81b95d449a22..b710d55c5b08 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -31,6 +31,7 @@ SECTIONS
.text :
{
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.got1)
__got2_start = .;
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index cec7225a6ac1..f74b14d7e58e 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -475,8 +475,6 @@ static inline int validate_sp(unsigned long sp, 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 --git a/arch/ppc64/kernel/semaphore.c b/arch/ppc64/kernel/semaphore.c
index c977029e2465..d723632d59f3 100644
--- a/arch/ppc64/kernel/semaphore.c
+++ b/arch/ppc64/kernel/semaphore.c
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
#include <asm/errno.h>
@@ -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 --git a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S
index a8531b1f9ef2..1d9b61143aaa 100644
--- a/arch/ppc64/kernel/vmlinux.lds.S
+++ b/arch/ppc64/kernel/vmlinux.lds.S
@@ -13,6 +13,7 @@ SECTIONS
/* Read-only sections, merged into text segment: */
.text : {
*(.text .text.*)
+ SCHED_TEXT
*(.fixup)
. = ALIGN(4096);
_etext = .;
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 3676307d1d8a..050585ab5d2a 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -384,8 +384,6 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
/*
* 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 --git a/arch/s390/kernel/semaphore.c b/arch/s390/kernel/semaphore.c
index 8203f5e0228d..8dfb690c159f 100644
--- a/arch/s390/kernel/semaphore.c
+++ b/arch/s390/kernel/semaphore.c
@@ -11,6 +11,7 @@
*/
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <asm/semaphore.h>
@@ -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 --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index c9ca7a8e93b3..b4534b2867c3 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -23,6 +23,7 @@ SECTIONS
_text = .; /* Text and read-only data */
.text : {
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
} = 0x0700
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 773006661b50..7d45ea0acd09 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -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_struct *p)
* 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 --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c
index 0943ad666a67..a3c24dcbf01d 100644
--- a/arch/sh/kernel/semaphore.c
+++ b/arch/sh/kernel/semaphore.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/wait.h>
+#include <linux/init.h>
#include <asm/semaphore.h>
#include <asm/semaphore-helper.h>
@@ -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 --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 2cc86534c130..da0f5d728b3e 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -22,6 +22,7 @@ SECTIONS
} = 0
.text : {
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
} = 0x0009
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index beae70a970e4..70261b211997 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -28,6 +28,7 @@
#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/pm.h>
+#include <linux/init.h>
#include <asm/auxio.h>
#include <asm/oplib.h>
@@ -694,9 +695,6 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
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 --git a/arch/sparc/kernel/semaphore.c b/arch/sparc/kernel/semaphore.c
index 5a8f3d176a8f..77e63b92ca30 100644
--- a/arch/sparc/kernel/semaphore.c
+++ b/arch/sparc/kernel/semaphore.c
@@ -4,6 +4,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <asm/semaphore.h>
@@ -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 --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 0862360d865d..8d4bbfaf304c 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -12,6 +12,7 @@ SECTIONS
.text 0xf0004000 :
{
*(.text)
+ SCHED_TEXT
*(.gnu.warning)
} =0
_etext = .;
diff --git a/arch/sparc/lib/rwsem.S b/arch/sparc/lib/rwsem.S
index 98b757cb67c6..e7578dc600b8 100644
--- a/arch/sparc/lib/rwsem.S
+++ b/arch/sparc/lib/rwsem.S
@@ -8,7 +8,7 @@
#include <asm/ptrace.h>
#include <asm/psr.h>
- .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 --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 1be2b97e4672..0caf962e8155 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -28,6 +28,7 @@
#include <linux/config.h>
#include <linux/reboot.h>
#include <linux/delay.h>
+#include <linux/init.h>
#include <asm/oplib.h>
#include <asm/uaccess.h>
@@ -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 --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c
index a9e66d666ceb..9ddfcb9a1900 100644
--- a/arch/sparc64/kernel/semaphore.c
+++ b/arch/sparc64/kernel/semaphore.c
@@ -8,6 +8,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/init.h>
/*
* 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 * sem)
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 semaphore * sem)
return retval;
}
-int down_interruptible(struct semaphore *sem)
+int __sched down_interruptible(struct semaphore *sem)
{
int ret = 0;
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index ad95e88a3cbc..8faeee09fab2 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -15,6 +15,7 @@ SECTIONS
.text 0x0000000000404000 :
{
*(.text)
+ SCHED_TEXT
*(.gnu.warning)
} =0
_etext = .;
diff --git a/arch/sparc64/lib/rwsem.c b/arch/sparc64/lib/rwsem.c
index 8e1dfdda91fa..e19968dbc2d1 100644
--- a/arch/sparc64/lib/rwsem.c
+++ b/arch/sparc64/lib/rwsem.c
@@ -6,6 +6,7 @@
#include <linux/kernel.h>
#include <linux/rwsem.h>
+#include <linux/init.h>
#include <linux/module.h>
extern struct rw_semaphore *FASTCALL(rwsem_down_read_failed(struct rw_semaphore *sem));
@@ -13,7 +14,7 @@ extern struct rw_semaphore *FASTCALL(rwsem_down_write_failed(struct rw_semaphore
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_semaphore *sem)
}
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 --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
index 5c29ae51a303..977d75772d81 100644
--- a/arch/v850/kernel/process.c
+++ b/arch/v850/kernel/process.c
@@ -203,8 +203,6 @@ int sys_execve (char *name, char **argv, char **envp, 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)
@@ -228,7 +226,6 @@ unsigned long get_wchan (struct task_struct *p)
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 --git a/arch/v850/kernel/semaphore.c b/arch/v850/kernel/semaphore.c
index b78d714384db..2d20886863d8 100644
--- a/arch/v850/kernel/semaphore.c
+++ b/arch/v850/kernel/semaphore.c
@@ -15,6 +15,7 @@
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/semaphore.h>
@@ -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 --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S
index 028c224fa66a..07ab0f292d1c 100644
--- a/arch/v850/kernel/vmlinux.lds.S
+++ b/arch/v850/kernel/vmlinux.lds.S
@@ -64,6 +64,7 @@
#define TEXT_CONTENTS \
__stext = . ; \
*(.text) \
+ SCHED_TEXT
*(.exit.text) /* 2.5 convention */ \
*(.text.exit) /* 2.4 convention */ \
*(.text.lock) \
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 7b2414765ca3..d1d9471581a8 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -576,8 +576,6 @@ asmlinkage long sys_vfork(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 --git a/arch/x86_64/kernel/semaphore.c b/arch/x86_64/kernel/semaphore.c
index 5e517814dd07..2bcd4a7ec38d 100644
--- a/arch/x86_64/kernel/semaphore.c
+++ b/arch/x86_64/kernel/semaphore.c
@@ -14,6 +14,7 @@
*/
#include <linux/config.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/errno.h>
#include <asm/semaphore.h>
@@ -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 --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 7b9e1beb360e..c612e4d213a1 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -15,6 +15,7 @@ SECTIONS
_text = .; /* Text and read-only data */
.text : {
*(.text)
+ SCHED_TEXT
*(.fixup)
*(.gnu.warning)
} = 0x9090
diff --git a/arch/x86_64/lib/thunk.S b/arch/x86_64/lib/thunk.S
index 876cb937f9f1..acc1e2ca7ed7 100644
--- a/arch/x86_64/lib/thunk.S
+++ b/arch/x86_64/lib/thunk.S
@@ -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 --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 59c2b950e8b8..a4b6c768cf49 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -51,3 +51,8 @@
*(.security_initcall.init) \
__security_initcall_end = .; \
}
+
+#define SCHED_TEXT \
+ __scheduling_functions_start_here = .; \
+ *(.sched.text) \
+ __scheduling_functions_end_here = .;
diff --git a/include/linux/init.h b/include/linux/init.h
index 45069e275b3d..c6842477243c 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -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 --git a/include/linux/sched.h b/include/linux/sched.h
index f5fa0c07a7f8..054b3c0d5962 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -170,6 +170,8 @@ 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;
#define MAX_SCHEDULE_TIMEOUT LONG_MAX
diff --git a/kernel/sched.c b/kernel/sched.c
index 9e19d4c0d4a9..b42029abe679 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -225,6 +225,13 @@ 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:
*/
@@ -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 completion *x)
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(wait_queue_head_t *q)
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_timeout(wait_queue_head_t *q, long timeout)
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 *q)
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_queue_head_t *q, long timeout)
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 *lock)
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 --git a/kernel/timer.c b/kernel/timer.c
index f53e0749b0d2..cbcb5522866d 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -996,7 +996,7 @@ static void process_timeout(unsigned long __data)
*
* 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 --git a/lib/rwsem.c b/lib/rwsem.c
index 95469d7fb796..85dcae7e9337 100644
--- a/lib/rwsem.c
+++ b/lib/rwsem.c
@@ -5,6 +5,7 @@
*/
#include <linux/rwsem.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <linux/module.h>
struct rwsem_waiter {
@@ -162,7 +163,7 @@ static inline struct rw_semaphore *rwsem_down_failed_common(struct rw_semaphore
/*
* 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_read_failed(struct rw_semaphore *sem)
/*
* 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;