aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/kernel/process.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-05-11 15:46:59 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-05-11 15:46:59 -0700
commitd649dafd0713f2f3dfe29baa783868db33aa2c11 (patch)
tree219379815f3d658a499f6a1a2971c9e7b14377b7 /arch/arm/kernel/process.c
parent2bf9d6d0f2dadc2a6c13684719c67dc043b9ce67 (diff)
parent41b11afb048d67cc0e221191191ba0b2012dce47 (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.c37
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);
}
/*