From 6c0a9fa62feb7e9fdefa9720bcc03040c9b0b311 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 May 2012 15:05:40 +0000 Subject: fork: Remove the weak insanity We error out when compiling with gcc4.1.[01] as it miscompiles __weak. The workaround with magic defines is not longer necessary. Make it __weak again. Signed-off-by: Thomas Gleixner Link: http://lkml.kernel.org/r/20120505150141.306358267@linutronix.de --- kernel/fork.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'kernel/fork.c') diff --git a/kernel/fork.c b/kernel/fork.c index b9372a0bff18..a79b36e2e912 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -203,13 +203,7 @@ void __put_task_struct(struct task_struct *tsk) } EXPORT_SYMBOL_GPL(__put_task_struct); -/* - * macro override instead of weak attribute alias, to workaround - * gcc 4.1.0 and 4.1.1 bugs with weak attribute and empty functions. - */ -#ifndef arch_task_cache_init -#define arch_task_cache_init() -#endif +void __init __weak arch_task_cache_init(void) { } void __init fork_init(unsigned long mempages) { -- cgit v1.2.3 From 2889f60814e15dea644782597d897cdba943564f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 May 2012 15:05:41 +0000 Subject: fork: Move thread info gfp flags to header These flags can be useful for extra allocations outside of the core code. Add __GFP_NOTRACK to them, so the archs which have kmemcheck do not have to provide extra allocators just for that reason. Signed-off-by: Thomas Gleixner Link: http://lkml.kernel.org/r/20120505150141.428211694@linutronix.de --- include/linux/thread_info.h | 6 ++++++ kernel/fork.c | 8 ++------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'kernel/fork.c') diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 8d03f079688c..db78775eff3b 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -54,6 +54,12 @@ extern long do_no_restart_syscall(struct restart_block *parm); #ifdef __KERNEL__ +#ifdef CONFIG_DEBUG_STACK_USAGE +# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +#else +# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK) +#endif + /* * flag set/clear/test wrappers * - pass TIF_xxxx constants to these functions diff --git a/kernel/fork.c b/kernel/fork.c index a79b36e2e912..5d22b9b8cf7b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -123,12 +123,8 @@ static struct kmem_cache *task_struct_cachep; static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) { -#ifdef CONFIG_DEBUG_STACK_USAGE - gfp_t mask = GFP_KERNEL | __GFP_ZERO; -#else - gfp_t mask = GFP_KERNEL; -#endif - struct page *page = alloc_pages_node(node, mask, THREAD_SIZE_ORDER); + struct page *page = alloc_pages_node(node, THREADINFO_GFP, + THREAD_SIZE_ORDER); return page ? page_address(page) : NULL; } -- cgit v1.2.3 From 41101809a865dd0be1b56eff46c83fad321870b2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 May 2012 15:05:41 +0000 Subject: fork: Provide weak arch_release_[task_struct|thread_info] functions These functions allow us to move most of the duplicated thread_info allocators to the core code. Signed-off-by: Thomas Gleixner Link: http://lkml.kernel.org/r/20120505150141.366461660@linutronix.de --- kernel/fork.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'kernel/fork.c') diff --git a/kernel/fork.c b/kernel/fork.c index 5d22b9b8cf7b..2dfad0269674 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -112,14 +112,26 @@ int nr_processes(void) } #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR -# define alloc_task_struct_node(node) \ - kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node) -# define free_task_struct(tsk) \ - kmem_cache_free(task_struct_cachep, (tsk)) static struct kmem_cache *task_struct_cachep; + +static inline struct task_struct *alloc_task_struct_node(int node) +{ + return kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node); +} + +void __weak arch_release_task_struct(struct task_struct *tsk) { } + +static inline void free_task_struct(struct task_struct *tsk) +{ + arch_release_task_struct(tsk); + kmem_cache_free(task_struct_cachep, tsk); +} #endif #ifndef __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +void __weak arch_release_thread_info(struct thread_info *ti) { } + static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) { @@ -131,6 +143,7 @@ static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, static inline void free_thread_info(struct thread_info *ti) { + arch_release_thread_info(ti); free_pages((unsigned long)ti, THREAD_SIZE_ORDER); } #endif -- cgit v1.2.3 From 0d15d74a1ead10673b5b1db66d4c90552769096c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 May 2012 15:05:41 +0000 Subject: fork: Provide kmemcache based thread_info allocator Several architectures have their own kmemcache based thread allocator because THREAD_SIZE is smaller than PAGE_SIZE. Add it to the core code conditionally on THREAD_SIZE < PAGE_SIZE so the private copies can go. Signed-off-by: Thomas Gleixner Link: http://lkml.kernel.org/r/20120505150141.491002124@linutronix.de --- kernel/fork.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'kernel/fork.c') diff --git a/kernel/fork.c b/kernel/fork.c index 2dfad0269674..7590bd6e8dff 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -132,6 +132,11 @@ static inline void free_task_struct(struct task_struct *tsk) void __weak arch_release_thread_info(struct thread_info *ti) { } +/* + * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a + * kmemcache based allocator. + */ +# if THREAD_SIZE >= PAGE_SIZE static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) { @@ -146,6 +151,28 @@ static inline void free_thread_info(struct thread_info *ti) arch_release_thread_info(ti); free_pages((unsigned long)ti, THREAD_SIZE_ORDER); } +# else +static struct kmem_cache *thread_info_cache; + +static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, + int node) +{ + return kmem_cache_alloc_node(thread_info_cache, THREADINFO_GFP, node); +} + +static void free_thread_info(struct thread_info *ti) +{ + arch_release_thread_info(ti); + kmem_cache_free(thread_info_cache, ti); +} + +void thread_info_cache_init(void) +{ + thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, + THREAD_SIZE, 0, NULL); + BUG_ON(thread_info_cache == NULL); +} +# endif #endif /* SLAB cache for signal_struct structures (tsk->signal) */ -- cgit v1.2.3 From f5e10287367dcffb5504d19c83e85ca041ca2596 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 May 2012 15:05:48 +0000 Subject: task_allocator: Use config switches instead of magic defines Replace __HAVE_ARCH_TASK_ALLOCATOR and __HAVE_ARCH_THREAD_ALLOCATOR with proper config switches. Signed-off-by: Thomas Gleixner Cc: Sam Ravnborg Cc: Tony Luck Link: http://lkml.kernel.org/r/20120505150142.371309416@linutronix.de --- arch/Kconfig | 8 ++++++++ arch/ia64/Kconfig | 2 ++ arch/ia64/include/asm/thread_info.h | 3 --- arch/sparc/Kconfig | 1 + arch/sparc/include/asm/thread_info_32.h | 2 -- kernel/fork.c | 7 +++---- 6 files changed, 14 insertions(+), 9 deletions(-) (limited to 'kernel/fork.c') diff --git a/arch/Kconfig b/arch/Kconfig index 597b132b3902..bd265a217bd2 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -152,6 +152,14 @@ config GENERIC_SMP_IDLE_THREAD config ARCH_INIT_TASK bool +# Select if arch has its private alloc_task_struct() function +config ARCH_TASK_STRUCT_ALLOCATOR + bool + +# Select if arch has its private alloc_thread_info() function +config ARCH_THREAD_INFO_ALLOCATOR + bool + config HAVE_REGS_AND_STACK_ACCESS_API bool help diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 022ea3a9d1ab..ba667b60f32d 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -35,6 +35,8 @@ config IA64 select GENERIC_IOMAP select GENERIC_SMP_IDLE_THREAD select ARCH_INIT_TASK + select ARCH_TASK_STRUCT_ALLOCATOR + select ARCH_THREAD_INFO_ALLOCATOR default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index e054bcc4273c..310d9734f02d 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h @@ -54,8 +54,6 @@ struct thread_info { }, \ } -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR - #ifndef ASM_OFFSETS_C /* how to get the thread information struct from C */ #define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE)) @@ -84,7 +82,6 @@ struct thread_info { #endif #define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET) -#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR #define alloc_task_struct_node(node) \ ({ \ struct page *page = alloc_pages_node(node, GFP_KERNEL | __GFP_COMP, \ diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index e417f35d5912..ec0347aaeaa8 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -36,6 +36,7 @@ config SPARC32 def_bool !64BIT select GENERIC_ATOMIC64 select CLZ_TAB + select ARCH_THREAD_INFO_ALLOCATOR config SPARC64 def_bool 64BIT diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h index c2a1080cdd3b..b29498dea6b7 100644 --- a/arch/sparc/include/asm/thread_info_32.h +++ b/arch/sparc/include/asm/thread_info_32.h @@ -80,8 +80,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); */ #define THREAD_INFO_ORDER 1 -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR - BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info_node, int) #define alloc_thread_info_node(tsk, node) BTFIXUP_CALL(alloc_thread_info_node)(node) diff --git a/kernel/fork.c b/kernel/fork.c index 7590bd6e8dff..a1793e442b20 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -111,7 +111,7 @@ int nr_processes(void) return total; } -#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR +#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR static struct kmem_cache *task_struct_cachep; static inline struct task_struct *alloc_task_struct_node(int node) @@ -128,8 +128,7 @@ static inline void free_task_struct(struct task_struct *tsk) } #endif -#ifndef __HAVE_ARCH_THREAD_INFO_ALLOCATOR - +#ifndef CONFIG_ARCH_THREAD_INFO_ALLOCATOR void __weak arch_release_thread_info(struct thread_info *ti) { } /* @@ -243,7 +242,7 @@ void __init __weak arch_task_cache_init(void) { } void __init fork_init(unsigned long mempages) { -#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR +#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR #ifndef ARCH_MIN_TASKALIGN #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES #endif -- cgit v1.2.3