diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 0f69a3e5281e..d2b9d7c31eaf 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -205,19 +205,17 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node) | |||
| 205 | void *stack; | 205 | void *stack; |
| 206 | int i; | 206 | int i; |
| 207 | 207 | ||
| 208 | local_irq_disable(); | ||
| 209 | for (i = 0; i < NR_CACHED_STACKS; i++) { | 208 | for (i = 0; i < NR_CACHED_STACKS; i++) { |
| 210 | struct vm_struct *s = this_cpu_read(cached_stacks[i]); | 209 | struct vm_struct *s; |
| 210 | |||
| 211 | s = this_cpu_xchg(cached_stacks[i], NULL); | ||
| 211 | 212 | ||
| 212 | if (!s) | 213 | if (!s) |
| 213 | continue; | 214 | continue; |
| 214 | this_cpu_write(cached_stacks[i], NULL); | ||
| 215 | 215 | ||
| 216 | tsk->stack_vm_area = s; | 216 | tsk->stack_vm_area = s; |
| 217 | local_irq_enable(); | ||
| 218 | return s->addr; | 217 | return s->addr; |
| 219 | } | 218 | } |
| 220 | local_irq_enable(); | ||
| 221 | 219 | ||
| 222 | stack = __vmalloc_node_range(THREAD_SIZE, THREAD_SIZE, | 220 | stack = __vmalloc_node_range(THREAD_SIZE, THREAD_SIZE, |
| 223 | VMALLOC_START, VMALLOC_END, | 221 | VMALLOC_START, VMALLOC_END, |
| @@ -245,19 +243,15 @@ static inline void free_thread_stack(struct task_struct *tsk) | |||
| 245 | { | 243 | { |
| 246 | #ifdef CONFIG_VMAP_STACK | 244 | #ifdef CONFIG_VMAP_STACK |
| 247 | if (task_stack_vm_area(tsk)) { | 245 | if (task_stack_vm_area(tsk)) { |
| 248 | unsigned long flags; | ||
| 249 | int i; | 246 | int i; |
| 250 | 247 | ||
| 251 | local_irq_save(flags); | ||
| 252 | for (i = 0; i < NR_CACHED_STACKS; i++) { | 248 | for (i = 0; i < NR_CACHED_STACKS; i++) { |
| 253 | if (this_cpu_read(cached_stacks[i])) | 249 | if (this_cpu_cmpxchg(cached_stacks[i], |
| 250 | NULL, tsk->stack_vm_area) != NULL) | ||
| 254 | continue; | 251 | continue; |
| 255 | 252 | ||
| 256 | this_cpu_write(cached_stacks[i], tsk->stack_vm_area); | ||
| 257 | local_irq_restore(flags); | ||
| 258 | return; | 253 | return; |
| 259 | } | 254 | } |
| 260 | local_irq_restore(flags); | ||
| 261 | 255 | ||
| 262 | vfree_atomic(tsk->stack); | 256 | vfree_atomic(tsk->stack); |
| 263 | return; | 257 | return; |
