]> Git Repo - linux.git/commit - mm/slub.c
mm/slub: fix lockups on PREEMPT && !SMP kernels
authorMark Rutland <[email protected]>
Wed, 25 Mar 2015 22:55:23 +0000 (15:55 -0700)
committerLinus Torvalds <[email protected]>
Wed, 25 Mar 2015 23:20:30 +0000 (16:20 -0700)
commit859b7a0e89120505c304d7afbbe90325abaa0a6b
tree78e3c160a7169e3b7dbf8ef9100f618b6c9692b5
parentb0dc3a342af36f95a68fe229b8f0f73552c5ca08
mm/slub: fix lockups on PREEMPT && !SMP kernels

Commit 9aabf810a67c ("mm/slub: optimize alloc/free fastpath by removing
preemption on/off") introduced an occasional hang for kernels built with
CONFIG_PREEMPT && !CONFIG_SMP.

The problem is the following loop the patch introduced to
slab_alloc_node and slab_free:

    do {
        tid = this_cpu_read(s->cpu_slab->tid);
        c = raw_cpu_ptr(s->cpu_slab);
    } while (IS_ENABLED(CONFIG_PREEMPT) && unlikely(tid != c->tid));

GCC 4.9 has been observed to hoist the load of c and c->tid above the
loop for !SMP kernels (as in this case raw_cpu_ptr(x) is compile-time
constant and does not force a reload).  On arm64 the generated assembly
looks like:

         ldr     x4, [x0,#8]
  loop:
         ldr     x1, [x0,#8]
         cmp     x1, x4
         b.ne    loop

If the thread is preempted between the load of c->tid (into x1) and tid
(into x4), and an allocation or free occurs in another thread (bumping
the cpu_slab's tid), the thread will be stuck in the loop until
s->cpu_slab->tid wraps, which may be forever in the absence of
allocations/frees on the same CPU.

This patch changes the loop condition to access c->tid with READ_ONCE.
This ensures that the value is reloaded even when the compiler would
otherwise assume it could cache the value, and also ensures that the
load will not be torn.

Signed-off-by: Mark Rutland <[email protected]>
Cc: Catalin Marinas <[email protected]>
Acked-by: Christoph Lameter <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Jesper Dangaard Brouer <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: Steve Capper <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
mm/slub.c
This page took 0.048195 seconds and 4 git commands to generate.