diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-05-16 01:19:52 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-05-16 01:19:52 +0100 |
commit | 18594822fcb01d4b35e05b9018f770a0b4156d1a (patch) | |
tree | 38d35c38086a564beaac215f8e52694cdbfab1c3 /arch/arm/kernel/process.c | |
parent | 5b5ffbc1e6d62d89747f3f59c09b2e488a7d7fce (diff) | |
parent | c4694c76ce28dd7e415b4f3014d8c6e580b5f3d2 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
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); } /* |