diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-11 15:46:59 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-11 15:46:59 -0700 |
commit | d649dafd0713f2f3dfe29baa783868db33aa2c11 (patch) | |
tree | 219379815f3d658a499f6a1a2971c9e7b14377b7 /arch/arm/kernel/process.c | |
parent | 2bf9d6d0f2dadc2a6c13684719c67dc043b9ce67 (diff) | |
parent | 41b11afb048d67cc0e221191191ba0b2012dce47 (diff) |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm:
[ARM] 3508/1: Update collie defconfig
[ARM] Fix thread struct allocator for SMP case
[ARM] Update mach-types
[ARM] Update versatile_defconfig
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r-- | arch/arm/kernel/process.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 1ff75cee4b0..1a1539e3a94 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -264,8 +264,12 @@ void show_fpregs(struct user_fp *regs) /* * Task structure and kernel stack allocation. */ -static unsigned long *thread_info_head; -static unsigned int nr_thread_info; +struct thread_info_list { + unsigned long *head; + unsigned int nr; +}; + +static DEFINE_PER_CPU(struct thread_info_list, thread_info_list) = { NULL, 0 }; #define EXTRA_TASK_STRUCT 4 @@ -274,12 +278,15 @@ struct thread_info *alloc_thread_info(struct task_struct *task) struct thread_info *thread = NULL; if (EXTRA_TASK_STRUCT) { - unsigned long *p = thread_info_head; + struct thread_info_list *th = &get_cpu_var(thread_info_list); + unsigned long *p = th->head; if (p) { - thread_info_head = (unsigned long *)p[0]; - nr_thread_info -= 1; + th->head = (unsigned long *)p[0]; + th->nr -= 1; } + put_cpu_var(thread_info_list); + thread = (struct thread_info *)p; } @@ -300,13 +307,19 @@ struct thread_info *alloc_thread_info(struct task_struct *task) void free_thread_info(struct thread_info *thread) { - if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) { - unsigned long *p = (unsigned long *)thread; - p[0] = (unsigned long)thread_info_head; - thread_info_head = p; - nr_thread_info += 1; - } else - free_pages((unsigned long)thread, THREAD_SIZE_ORDER); + if (EXTRA_TASK_STRUCT) { + struct thread_info_list *th = &get_cpu_var(thread_info_list); + if (th->nr < EXTRA_TASK_STRUCT) { + unsigned long *p = (unsigned long *)thread; + p[0] = th->head; + th->head = p; + th->nr += 1; + put_cpu_var(thread_info_list); + return; + } + put_cpu_var(thread_info_list); + } + free_pages((unsigned long)thread, THREAD_SIZE_ORDER); } /* |