diff options
| author | Christoph Lameter <cl@linux.com> | 2017-07-12 17:33:11 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-12 19:25:59 -0400 |
| commit | 112166f88cf83dd11486cf1818672d42b540865b (patch) | |
| tree | a111199c9d0cb26065fc0023879f53d904657d1f /kernel/fork.c | |
| parent | 91a90140f9987101d730b7dad8c6406321285da8 (diff) | |
kernel/fork.c: virtually mapped stacks: do not disable interrupts
The reason to disable interrupts seems to be to avoid switching to a
different processor while handling per cpu data using individual loads and
stores. If we use per cpu RMV primitives we will not have to disable
interrupts.
Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1705171055130.5898@east.gentwo.org
Signed-off-by: Christoph Lameter <cl@linux.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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; |
