diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-11 18:46:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-11 18:46:59 -0400 |
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 1ff75cee4b0d..1a1539e3a946 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -264,8 +264,12 @@ void show_fpregs(struct user_fp *regs) | |||
264 | /* | 264 | /* |
265 | * Task structure and kernel stack allocation. | 265 | * Task structure and kernel stack allocation. |
266 | */ | 266 | */ |
267 | static unsigned long *thread_info_head; | 267 | struct thread_info_list { |
268 | static unsigned int nr_thread_info; | 268 | unsigned long *head; |
269 | unsigned int nr; | ||
270 | }; | ||
271 | |||
272 | static DEFINE_PER_CPU(struct thread_info_list, thread_info_list) = { NULL, 0 }; | ||
269 | 273 | ||
270 | #define EXTRA_TASK_STRUCT 4 | 274 | #define EXTRA_TASK_STRUCT 4 |
271 | 275 | ||
@@ -274,12 +278,15 @@ struct thread_info *alloc_thread_info(struct task_struct *task) | |||
274 | struct thread_info *thread = NULL; | 278 | struct thread_info *thread = NULL; |
275 | 279 | ||
276 | if (EXTRA_TASK_STRUCT) { | 280 | if (EXTRA_TASK_STRUCT) { |
277 | unsigned long *p = thread_info_head; | 281 | struct thread_info_list *th = &get_cpu_var(thread_info_list); |
282 | unsigned long *p = th->head; | ||
278 | 283 | ||
279 | if (p) { | 284 | if (p) { |
280 | thread_info_head = (unsigned long *)p[0]; | 285 | th->head = (unsigned long *)p[0]; |
281 | nr_thread_info -= 1; | 286 | th->nr -= 1; |
282 | } | 287 | } |
288 | put_cpu_var(thread_info_list); | ||
289 | |||
283 | thread = (struct thread_info *)p; | 290 | thread = (struct thread_info *)p; |
284 | } | 291 | } |
285 | 292 | ||
@@ -300,13 +307,19 @@ struct thread_info *alloc_thread_info(struct task_struct *task) | |||
300 | 307 | ||
301 | void free_thread_info(struct thread_info *thread) | 308 | void free_thread_info(struct thread_info *thread) |
302 | { | 309 | { |
303 | if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) { | 310 | if (EXTRA_TASK_STRUCT) { |
304 | unsigned long *p = (unsigned long *)thread; | 311 | struct thread_info_list *th = &get_cpu_var(thread_info_list); |
305 | p[0] = (unsigned long)thread_info_head; | 312 | if (th->nr < EXTRA_TASK_STRUCT) { |
306 | thread_info_head = p; | 313 | unsigned long *p = (unsigned long *)thread; |
307 | nr_thread_info += 1; | 314 | p[0] = th->head; |
308 | } else | 315 | th->head = p; |
309 | free_pages((unsigned long)thread, THREAD_SIZE_ORDER); | 316 | th->nr += 1; |
317 | put_cpu_var(thread_info_list); | ||
318 | return; | ||
319 | } | ||
320 | put_cpu_var(thread_info_list); | ||
321 | } | ||
322 | free_pages((unsigned long)thread, THREAD_SIZE_ORDER); | ||
310 | } | 323 | } |
311 | 324 | ||
312 | /* | 325 | /* |