aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-24 18:09:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-24 18:09:37 -0400
commitb235beea9e996a4d36fed6cfef4801a3e7d7a9a5 (patch)
tree52f66350a5e07e251bb241c53520dc485b5d750a
parent63c04ee7d3b7c8d8e2726cb7c5f8a5f6fcc1e3b2 (diff)
Clarify naming of thread info/stack allocators
We've had the thread info allocated together with the thread stack for most architectures for a long time (since the thread_info was split off from the task struct), but that is about to change. But the patches that move the thread info to be off-stack (and a part of the task struct instead) made it clear how confused the allocator and freeing functions are. Because the common case was that we share an allocation with the thread stack and the thread_info, the two pointers were identical. That identity then meant that we would have things like ti = alloc_thread_info_node(tsk, node); ... tsk->stack = ti; which certainly _worked_ (since stack and thread_info have the same value), but is rather confusing: why are we assigning a thread_info to the stack? And if we move the thread_info away, the "confusing" code just gets to be entirely bogus. So remove all this confusion, and make it clear that we are doing the stack allocation by renaming and clarifying the function names to be about the stack. The fact that the thread_info then shares the allocation is an implementation detail, and not really about the allocation itself. This is a pure renaming and type fix: we pass in the same pointer, it's just that we clarify what the pointer means. The ia64 code that actually only has one single allocation (for all of task_struct, thread_info and kernel thread stack) now looks a bit odd, but since "tsk->stack" is actually not even used there, that oddity doesn't matter. It would be a separate thing to clean that up, I intentionally left the ia64 changes as a pure brute-force renaming and type change. Acked-by: Andy Lutomirski <luto@amacapital.net> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/Kconfig4
-rw-r--r--arch/ia64/Kconfig2
-rw-r--r--arch/ia64/include/asm/thread_info.h8
-rw-r--r--arch/mn10300/include/asm/thread_info.h2
-rw-r--r--arch/mn10300/kernel/kgdb.c3
-rw-r--r--arch/tile/include/asm/thread_info.h2
-rw-r--r--arch/tile/kernel/process.c3
-rw-r--r--include/linux/sched.h2
-rw-r--r--init/main.c4
-rw-r--r--kernel/fork.c50
10 files changed, 41 insertions, 39 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index e9734796531f..15996290fed4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -226,8 +226,8 @@ config ARCH_INIT_TASK
226config ARCH_TASK_STRUCT_ALLOCATOR 226config ARCH_TASK_STRUCT_ALLOCATOR
227 bool 227 bool
228 228
229# Select if arch has its private alloc_thread_info() function 229# Select if arch has its private alloc_thread_stack() function
230config ARCH_THREAD_INFO_ALLOCATOR 230config ARCH_THREAD_STACK_ALLOCATOR
231 bool 231 bool
232 232
233# Select if arch wants to size task_struct dynamically via arch_task_struct_size: 233# Select if arch wants to size task_struct dynamically via arch_task_struct_size:
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index f80758cb7157..e109ee95e919 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -45,7 +45,7 @@ config IA64
45 select GENERIC_SMP_IDLE_THREAD 45 select GENERIC_SMP_IDLE_THREAD
46 select ARCH_INIT_TASK 46 select ARCH_INIT_TASK
47 select ARCH_TASK_STRUCT_ALLOCATOR 47 select ARCH_TASK_STRUCT_ALLOCATOR
48 select ARCH_THREAD_INFO_ALLOCATOR 48 select ARCH_THREAD_STACK_ALLOCATOR
49 select ARCH_CLOCKSOURCE_DATA 49 select ARCH_CLOCKSOURCE_DATA
50 select GENERIC_TIME_VSYSCALL_OLD 50 select GENERIC_TIME_VSYSCALL_OLD
51 select SYSCTL_ARCH_UNALIGN_NO_WARN 51 select SYSCTL_ARCH_UNALIGN_NO_WARN
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
index aa995b67c3f5..d1212b84fb83 100644
--- a/arch/ia64/include/asm/thread_info.h
+++ b/arch/ia64/include/asm/thread_info.h
@@ -48,15 +48,15 @@ struct thread_info {
48#ifndef ASM_OFFSETS_C 48#ifndef ASM_OFFSETS_C
49/* how to get the thread information struct from C */ 49/* how to get the thread information struct from C */
50#define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE)) 50#define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE))
51#define alloc_thread_info_node(tsk, node) \ 51#define alloc_thread_stack_node(tsk, node) \
52 ((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE)) 52 ((unsigned long *) ((char *) (tsk) + IA64_TASK_SIZE))
53#define task_thread_info(tsk) ((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE)) 53#define task_thread_info(tsk) ((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE))
54#else 54#else
55#define current_thread_info() ((struct thread_info *) 0) 55#define current_thread_info() ((struct thread_info *) 0)
56#define alloc_thread_info_node(tsk, node) ((struct thread_info *) 0) 56#define alloc_thread_stack_node(tsk, node) ((unsigned long *) 0)
57#define task_thread_info(tsk) ((struct thread_info *) 0) 57#define task_thread_info(tsk) ((struct thread_info *) 0)
58#endif 58#endif
59#define free_thread_info(ti) /* nothing */ 59#define free_thread_stack(ti) /* nothing */
60#define task_stack_page(tsk) ((void *)(tsk)) 60#define task_stack_page(tsk) ((void *)(tsk))
61 61
62#define __HAVE_THREAD_FUNCTIONS 62#define __HAVE_THREAD_FUNCTIONS
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h
index 4861a78c7160..f5f90bbf019d 100644
--- a/arch/mn10300/include/asm/thread_info.h
+++ b/arch/mn10300/include/asm/thread_info.h
@@ -115,7 +115,7 @@ static inline unsigned long current_stack_pointer(void)
115} 115}
116 116
117#ifndef CONFIG_KGDB 117#ifndef CONFIG_KGDB
118void arch_release_thread_info(struct thread_info *ti); 118void arch_release_thread_stack(unsigned long *stack);
119#endif 119#endif
120#define get_thread_info(ti) get_task_struct((ti)->task) 120#define get_thread_info(ti) get_task_struct((ti)->task)
121#define put_thread_info(ti) put_task_struct((ti)->task) 121#define put_thread_info(ti) put_task_struct((ti)->task)
diff --git a/arch/mn10300/kernel/kgdb.c b/arch/mn10300/kernel/kgdb.c
index 99770823451a..2d7986c386fe 100644
--- a/arch/mn10300/kernel/kgdb.c
+++ b/arch/mn10300/kernel/kgdb.c
@@ -397,8 +397,9 @@ static bool kgdb_arch_undo_singlestep(struct pt_regs *regs)
397 * single-step state is cleared. At this point the breakpoints should have 397 * single-step state is cleared. At this point the breakpoints should have
398 * been removed by __switch_to(). 398 * been removed by __switch_to().
399 */ 399 */
400void arch_release_thread_info(struct thread_info *ti) 400void arch_release_thread_stack(unsigned long *stack)
401{ 401{
402 struct thread_info *ti = (void *)stack;
402 if (kgdb_sstep_thread == ti) { 403 if (kgdb_sstep_thread == ti) {
403 kgdb_sstep_thread = NULL; 404 kgdb_sstep_thread = NULL;
404 405
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h
index 4b7cef9e94e0..c1467ac59ce6 100644
--- a/arch/tile/include/asm/thread_info.h
+++ b/arch/tile/include/asm/thread_info.h
@@ -78,7 +78,7 @@ struct thread_info {
78 78
79#ifndef __ASSEMBLY__ 79#ifndef __ASSEMBLY__
80 80
81void arch_release_thread_info(struct thread_info *info); 81void arch_release_thread_stack(unsigned long *stack);
82 82
83/* How to get the thread information struct from C. */ 83/* How to get the thread information struct from C. */
84register unsigned long stack_pointer __asm__("sp"); 84register unsigned long stack_pointer __asm__("sp");
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 6b705ccc9cc1..a465d8372edd 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -73,8 +73,9 @@ void arch_cpu_idle(void)
73/* 73/*
74 * Release a thread_info structure 74 * Release a thread_info structure
75 */ 75 */
76void arch_release_thread_info(struct thread_info *info) 76void arch_release_thread_stack(unsigned long *stack)
77{ 77{
78 struct thread_info *info = (void *)stack;
78 struct single_step_state *step_state = info->step_state; 79 struct single_step_state *step_state = info->step_state;
79 80
80 if (step_state) { 81 if (step_state) {
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6e42ada26345..253538f29ade 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -3007,7 +3007,7 @@ static inline int object_is_on_stack(void *obj)
3007 return (obj >= stack) && (obj < (stack + THREAD_SIZE)); 3007 return (obj >= stack) && (obj < (stack + THREAD_SIZE));
3008} 3008}
3009 3009
3010extern void thread_info_cache_init(void); 3010extern void thread_stack_cache_init(void);
3011 3011
3012#ifdef CONFIG_DEBUG_STACK_USAGE 3012#ifdef CONFIG_DEBUG_STACK_USAGE
3013static inline unsigned long stack_not_used(struct task_struct *p) 3013static inline unsigned long stack_not_used(struct task_struct *p)
diff --git a/init/main.c b/init/main.c
index 4c17fda5c2ff..826fd57fa3aa 100644
--- a/init/main.c
+++ b/init/main.c
@@ -453,7 +453,7 @@ void __init __weak smp_setup_processor_id(void)
453} 453}
454 454
455# if THREAD_SIZE >= PAGE_SIZE 455# if THREAD_SIZE >= PAGE_SIZE
456void __init __weak thread_info_cache_init(void) 456void __init __weak thread_stack_cache_init(void)
457{ 457{
458} 458}
459#endif 459#endif
@@ -627,7 +627,7 @@ asmlinkage __visible void __init start_kernel(void)
627 /* Should be run before the first non-init thread is created */ 627 /* Should be run before the first non-init thread is created */
628 init_espfix_bsp(); 628 init_espfix_bsp();
629#endif 629#endif
630 thread_info_cache_init(); 630 thread_stack_cache_init();
631 cred_init(); 631 cred_init();
632 fork_init(); 632 fork_init();
633 proc_caches_init(); 633 proc_caches_init();
diff --git a/kernel/fork.c b/kernel/fork.c
index 5c2c355aa97f..37b9439b8c07 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -148,18 +148,18 @@ static inline void free_task_struct(struct task_struct *tsk)
148} 148}
149#endif 149#endif
150 150
151void __weak arch_release_thread_info(struct thread_info *ti) 151void __weak arch_release_thread_stack(unsigned long *stack)
152{ 152{
153} 153}
154 154
155#ifndef CONFIG_ARCH_THREAD_INFO_ALLOCATOR 155#ifndef CONFIG_ARCH_THREAD_STACK_ALLOCATOR
156 156
157/* 157/*
158 * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a 158 * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a
159 * kmemcache based allocator. 159 * kmemcache based allocator.
160 */ 160 */
161# if THREAD_SIZE >= PAGE_SIZE 161# if THREAD_SIZE >= PAGE_SIZE
162static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, 162static unsigned long *alloc_thread_stack_node(struct task_struct *tsk,
163 int node) 163 int node)
164{ 164{
165 struct page *page = alloc_kmem_pages_node(node, THREADINFO_GFP, 165 struct page *page = alloc_kmem_pages_node(node, THREADINFO_GFP,
@@ -172,33 +172,33 @@ static struct thread_info *alloc_thread_info_node(struct task_struct *tsk,
172 return page ? page_address(page) : NULL; 172 return page ? page_address(page) : NULL;
173} 173}
174 174
175static inline void free_thread_info(struct thread_info *ti) 175static inline void free_thread_stack(unsigned long *stack)
176{ 176{
177 struct page *page = virt_to_page(ti); 177 struct page *page = virt_to_page(stack);
178 178
179 memcg_kmem_update_page_stat(page, MEMCG_KERNEL_STACK, 179 memcg_kmem_update_page_stat(page, MEMCG_KERNEL_STACK,
180 -(1 << THREAD_SIZE_ORDER)); 180 -(1 << THREAD_SIZE_ORDER));
181 __free_kmem_pages(page, THREAD_SIZE_ORDER); 181 __free_kmem_pages(page, THREAD_SIZE_ORDER);
182} 182}
183# else 183# else
184static struct kmem_cache *thread_info_cache; 184static struct kmem_cache *thread_stack_cache;
185 185
186static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, 186static struct thread_info *alloc_thread_stack_node(struct task_struct *tsk,
187 int node) 187 int node)
188{ 188{
189 return kmem_cache_alloc_node(thread_info_cache, THREADINFO_GFP, node); 189 return kmem_cache_alloc_node(thread_stack_cache, THREADINFO_GFP, node);
190} 190}
191 191
192static void free_thread_info(struct thread_info *ti) 192static void free_stack(unsigned long *stack)
193{ 193{
194 kmem_cache_free(thread_info_cache, ti); 194 kmem_cache_free(thread_stack_cache, stack);
195} 195}
196 196
197void thread_info_cache_init(void) 197void thread_stack_cache_init(void)
198{ 198{
199 thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, 199 thread_stack_cache = kmem_cache_create("thread_stack", THREAD_SIZE,
200 THREAD_SIZE, 0, NULL); 200 THREAD_SIZE, 0, NULL);
201 BUG_ON(thread_info_cache == NULL); 201 BUG_ON(thread_stack_cache == NULL);
202} 202}
203# endif 203# endif
204#endif 204#endif
@@ -221,9 +221,9 @@ struct kmem_cache *vm_area_cachep;
221/* SLAB cache for mm_struct structures (tsk->mm) */ 221/* SLAB cache for mm_struct structures (tsk->mm) */
222static struct kmem_cache *mm_cachep; 222static struct kmem_cache *mm_cachep;
223 223
224static void account_kernel_stack(struct thread_info *ti, int account) 224static void account_kernel_stack(unsigned long *stack, int account)
225{ 225{
226 struct zone *zone = page_zone(virt_to_page(ti)); 226 struct zone *zone = page_zone(virt_to_page(stack));
227 227
228 mod_zone_page_state(zone, NR_KERNEL_STACK, account); 228 mod_zone_page_state(zone, NR_KERNEL_STACK, account);
229} 229}
@@ -231,8 +231,8 @@ static void account_kernel_stack(struct thread_info *ti, int account)
231void free_task(struct task_struct *tsk) 231void free_task(struct task_struct *tsk)
232{ 232{
233 account_kernel_stack(tsk->stack, -1); 233 account_kernel_stack(tsk->stack, -1);
234 arch_release_thread_info(tsk->stack); 234 arch_release_thread_stack(tsk->stack);
235 free_thread_info(tsk->stack); 235 free_thread_stack(tsk->stack);
236 rt_mutex_debug_task_free(tsk); 236 rt_mutex_debug_task_free(tsk);
237 ftrace_graph_exit_task(tsk); 237 ftrace_graph_exit_task(tsk);
238 put_seccomp_filter(tsk); 238 put_seccomp_filter(tsk);
@@ -343,7 +343,7 @@ void set_task_stack_end_magic(struct task_struct *tsk)
343static struct task_struct *dup_task_struct(struct task_struct *orig, int node) 343static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
344{ 344{
345 struct task_struct *tsk; 345 struct task_struct *tsk;
346 struct thread_info *ti; 346 unsigned long *stack;
347 int err; 347 int err;
348 348
349 if (node == NUMA_NO_NODE) 349 if (node == NUMA_NO_NODE)
@@ -352,15 +352,15 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
352 if (!tsk) 352 if (!tsk)
353 return NULL; 353 return NULL;
354 354
355 ti = alloc_thread_info_node(tsk, node); 355 stack = alloc_thread_stack_node(tsk, node);
356 if (!ti) 356 if (!stack)
357 goto free_tsk; 357 goto free_tsk;
358 358
359 err = arch_dup_task_struct(tsk, orig); 359 err = arch_dup_task_struct(tsk, orig);
360 if (err) 360 if (err)
361 goto free_ti; 361 goto free_stack;
362 362
363 tsk->stack = ti; 363 tsk->stack = stack;
364#ifdef CONFIG_SECCOMP 364#ifdef CONFIG_SECCOMP
365 /* 365 /*
366 * We must handle setting up seccomp filters once we're under 366 * We must handle setting up seccomp filters once we're under
@@ -392,14 +392,14 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
392 tsk->task_frag.page = NULL; 392 tsk->task_frag.page = NULL;
393 tsk->wake_q.next = NULL; 393 tsk->wake_q.next = NULL;
394 394
395 account_kernel_stack(ti, 1); 395 account_kernel_stack(stack, 1);
396 396
397 kcov_task_init(tsk); 397 kcov_task_init(tsk);
398 398
399 return tsk; 399 return tsk;
400 400
401free_ti: 401free_stack:
402 free_thread_info(ti); 402 free_thread_stack(stack);
403free_tsk: 403free_tsk:
404 free_task_struct(tsk); 404 free_task_struct(tsk);
405 return NULL; 405 return NULL;