aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@gmail.com>2006-11-02 10:41:18 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-11-30 10:27:03 -0500
commit122214428a7bfab2c09b417f3acdb06222e81748 (patch)
treef453fa01829db292b1108e87a416c1acdfedcd70 /arch
parent9b531ce242159bd26e09b55d8fb4be3f4bf75e24 (diff)
[ARM] 3911/2: Simplify alloc_thread_info on ARM
Remove ARM local cache of 4 struct thread_info. Can cause oops under certain circumstances. Russell indicated the original optimization was required on older kernels to avoid thread starvation on memory fragmentation, but may no longer be required. I've updated the patch to 19rc4 and ensured no <config.h> dain-bramage slipped in this time (sorry about that). Original description follows: I was given some test results which pointed to an Oops in alloc_thread_info (happened 2x), and after looking at the code, I see that ARM has its own local cache of 4 struct thread_info. There wasn't any clear (to me) synchronization between the alloc_thread_info and the free_thread_info. I looked over the other arch, and they all simply allocate them on an as needed basis, so I simplified the ARM to do the same, based on the other arch (e.g. PPC) and the folks doing the testing have indicated that this fixed the oops. Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/process.c61
1 files changed, 0 insertions, 61 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index bf35c178a877..a9e8f7e55fd6 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -281,67 +281,6 @@ void show_fpregs(struct user_fp *regs)
281} 281}
282 282
283/* 283/*
284 * Task structure and kernel stack allocation.
285 */
286struct thread_info_list {
287 unsigned long *head;
288 unsigned int nr;
289};
290
291static DEFINE_PER_CPU(struct thread_info_list, thread_info_list) = { NULL, 0 };
292
293#define EXTRA_TASK_STRUCT 4
294
295struct thread_info *alloc_thread_info(struct task_struct *task)
296{
297 struct thread_info *thread = NULL;
298
299 if (EXTRA_TASK_STRUCT) {
300 struct thread_info_list *th = &get_cpu_var(thread_info_list);
301 unsigned long *p = th->head;
302
303 if (p) {
304 th->head = (unsigned long *)p[0];
305 th->nr -= 1;
306 }
307 put_cpu_var(thread_info_list);
308
309 thread = (struct thread_info *)p;
310 }
311
312 if (!thread)
313 thread = (struct thread_info *)
314 __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
315
316#ifdef CONFIG_DEBUG_STACK_USAGE
317 /*
318 * The stack must be cleared if you want SYSRQ-T to
319 * give sensible stack usage information
320 */
321 if (thread)
322 memzero(thread, THREAD_SIZE);
323#endif
324 return thread;
325}
326
327void free_thread_info(struct thread_info *thread)
328{
329 if (EXTRA_TASK_STRUCT) {
330 struct thread_info_list *th = &get_cpu_var(thread_info_list);
331 if (th->nr < EXTRA_TASK_STRUCT) {
332 unsigned long *p = (unsigned long *)thread;
333 p[0] = (unsigned long)th->head;
334 th->head = p;
335 th->nr += 1;
336 put_cpu_var(thread_info_list);
337 return;
338 }
339 put_cpu_var(thread_info_list);
340 }
341 free_pages((unsigned long)thread, THREAD_SIZE_ORDER);
342}
343
344/*
345 * Free current thread data structures etc.. 284 * Free current thread data structures etc..
346 */ 285 */
347void exit_thread(void) 286void exit_thread(void)