17 Aug, 2017

1 commit

  • There is no agreed-upon definition of spin_unlock_wait()'s semantics,
    and it appears that all callers could do just as well with a lock/unlock
    pair. This commit therefore removes spin_unlock_wait() and related
    definitions from core code.

    Signed-off-by: Paul E. McKenney
    Cc: Arnd Bergmann
    Cc: Ingo Molnar
    Cc: Will Deacon
    Cc: Peter Zijlstra
    Cc: Alan Stern
    Cc: Andrea Parri
    Cc: Linus Torvalds

    Paul E. McKenney
     

08 Jun, 2016

2 commits

  • The existing version uses a heavy barrier while only release semantics
    is required. So use atomic_sub_return_release() instead.

    Suggested-by: Peter Zijlstra (Intel)
    Signed-off-by: Pan Xinhui
    Signed-off-by: Peter Zijlstra (Intel)
    Cc: Andrew Morton
    Cc: Linus Torvalds
    Cc: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: arnd@arndb.de
    Cc: waiman.long@hp.com
    Link: http://lkml.kernel.org/r/1464943094-3129-1-git-send-email-xinhui.pan@linux.vnet.ibm.com
    Signed-off-by: Ingo Molnar

    Pan Xinhui
     
  • While this prior commit:

    54cf809b9512 ("locking,qspinlock: Fix spin_is_locked() and spin_unlock_wait()")

    ... fixes spin_is_locked() and spin_unlock_wait() for the usage
    in ipc/sem and netfilter, it does not in fact work right for the
    usage in task_work and futex.

    So while the 2 locks crossed problem:

    spin_lock(A) spin_lock(B)
    if (!spin_is_locked(B)) spin_unlock_wait(A)
    foo() foo();

    ... works with the smp_mb() injected by both spin_is_locked() and
    spin_unlock_wait(), this is not sufficient for:

    flag = 1;
    smp_mb(); spin_lock()
    spin_unlock_wait() if (!flag)
    // add to lockless list
    // iterate lockless list

    ... because in this scenario, the store from spin_lock() can be delayed
    past the load of flag, uncrossing the variables and loosing the
    guarantee.

    This patch reworks spin_is_locked() and spin_unlock_wait() to work in
    both cases by exploiting the observation that while the lock byte
    store can be delayed, the contender must have registered itself
    visibly in other state contained in the word.

    It also allows for architectures to override both functions, as PPC
    and ARM64 have an additional issue for which we currently have no
    generic solution.

    Signed-off-by: Peter Zijlstra (Intel)
    Cc: Andrew Morton
    Cc: Boqun Feng
    Cc: Davidlohr Bueso
    Cc: Giovanni Gherdovich
    Cc: Linus Torvalds
    Cc: Pan Xinhui
    Cc: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Waiman Long
    Cc: Will Deacon
    Cc: stable@vger.kernel.org # v4.2 and later
    Fixes: 54cf809b9512 ("locking,qspinlock: Fix spin_is_locked() and spin_unlock_wait()")
    Signed-off-by: Ingo Molnar

    Peter Zijlstra
     

21 May, 2016

1 commit

  • Similar to commits:

    51d7d5205d33 ("powerpc: Add smp_mb() to arch_spin_is_locked()")
    d86b8da04dfa ("arm64: spinlock: serialise spin_unlock_wait against concurrent lockers")

    qspinlock suffers from the fact that the _Q_LOCKED_VAL store is
    unordered inside the ACQUIRE of the lock.

    And while this is not a problem for the regular mutual exclusive
    critical section usage of spinlocks, it breaks creative locking like:

    spin_lock(A) spin_lock(B)
    spin_unlock_wait(B) if (!spin_is_locked(A))
    do_something() do_something()

    In that both CPUs can end up running do_something at the same time,
    because our _Q_LOCKED_VAL store can drop past the spin_unlock_wait()
    spin_is_locked() loads (even on x86!!).

    To avoid making the normal case slower, add smp_mb()s to the less used
    spin_unlock_wait() / spin_is_locked() side of things to avoid this
    problem.

    Reported-and-tested-by: Davidlohr Bueso
    Reported-by: Giovanni Gherdovich
    Signed-off-by: Peter Zijlstra (Intel)
    Cc: stable@vger.kernel.org # v4.2 and later
    Signed-off-by: Linus Torvalds

    Peter Zijlstra
     

29 Feb, 2016

1 commit

  • Move the __ARCH_SPIN_LOCK_UNLOCKED definition from qspinlock.h into
    qspinlock_types.h.

    The definition of __ARCH_SPIN_LOCK_UNLOCKED comes from the build arch's
    include files; but on x86 when CONFIG_QUEUED_SPINLOCKS=y, it just
    it's defined in asm-generic/qspinlock.h. In most cases, this doesn't
    matter because linux/spinlock.h includes asm/spinlock.h, which for x86
    includes asm-generic/qspinlock.h. However, any code that only includes
    linux/mutex.h will break, because it only includes asm/spinlock_types.h.

    For example, this breaks systemtap, which only includes mutex.h.

    Signed-off-by: Dan Streetman
    Signed-off-by: Peter Zijlstra (Intel)
    Acked-by: Waiman Long
    Cc: Andrew Morton
    Cc: Arnd Bergmann
    Cc: Dan Streetman
    Cc: Linus Torvalds
    Cc: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Link: http://lkml.kernel.org/r/1455907767-17821-1-git-send-email-dan.streetman@canonical.com
    Signed-off-by: Ingo Molnar

    Dan Streetman
     

23 Nov, 2015

1 commit

  • This patch replaces the cmpxchg() and xchg() calls in the native
    qspinlock code with the more relaxed _acquire or _release versions of
    those calls to enable other architectures to adopt queued spinlocks
    with less memory barrier performance overhead.

    Signed-off-by: Waiman Long
    Signed-off-by: Peter Zijlstra (Intel)
    Cc: Andrew Morton
    Cc: Davidlohr Bueso
    Cc: Douglas Hatch
    Cc: H. Peter Anvin
    Cc: Linus Torvalds
    Cc: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Scott J Norton
    Cc: Thomas Gleixner
    Link: http://lkml.kernel.org/r/1447114167-47185-2-git-send-email-Waiman.Long@hpe.com
    Signed-off-by: Ingo Molnar

    Waiman Long
     

11 Sep, 2015

1 commit

  • Dave ran into horrible performance on a VM without PARAVIRT_SPINLOCKS
    set and Linus noted that the test-and-set implementation was retarded.

    One should spin on the variable with a load, not a RMW.

    While there, remove 'queued' from the name, as the lock isn't queued
    at all, but a simple test-and-set.

    Suggested-by: Linus Torvalds
    Reported-by: Dave Chinner
    Tested-by: Dave Chinner
    Signed-off-by: Peter Zijlstra (Intel)
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Waiman Long
    Cc: stable@vger.kernel.org # v4.2+
    Link: http://lkml.kernel.org/r/20150904152523.GR18673@twins.programming.kicks-ass.net
    Signed-off-by: Ingo Molnar

    Peter Zijlstra
     

08 May, 2015

2 commits

  • When we detect a hypervisor (!paravirt, see qspinlock paravirt support
    patches), revert to a simple test-and-set lock to avoid the horrors
    of queue preemption.

    Signed-off-by: Peter Zijlstra (Intel)
    Signed-off-by: Waiman Long
    Signed-off-by: Peter Zijlstra (Intel)
    Cc: Andrew Morton
    Cc: Boris Ostrovsky
    Cc: Borislav Petkov
    Cc: Daniel J Blueman
    Cc: David Vrabel
    Cc: Douglas Hatch
    Cc: H. Peter Anvin
    Cc: Konrad Rzeszutek Wilk
    Cc: Linus Torvalds
    Cc: Oleg Nesterov
    Cc: Paolo Bonzini
    Cc: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Raghavendra K T
    Cc: Rik van Riel
    Cc: Scott J Norton
    Cc: Thomas Gleixner
    Cc: virtualization@lists.linux-foundation.org
    Cc: xen-devel@lists.xenproject.org
    Link: http://lkml.kernel.org/r/1429901803-29771-8-git-send-email-Waiman.Long@hp.com
    Signed-off-by: Ingo Molnar

    Peter Zijlstra (Intel)
     
  • This patch introduces a new generic queued spinlock implementation that
    can serve as an alternative to the default ticket spinlock. Compared
    with the ticket spinlock, this queued spinlock should be almost as fair
    as the ticket spinlock. It has about the same speed in single-thread
    and it can be much faster in high contention situations especially when
    the spinlock is embedded within the data structure to be protected.

    Only in light to moderate contention where the average queue depth
    is around 1-3 will this queued spinlock be potentially a bit slower
    due to the higher slowpath overhead.

    This queued spinlock is especially suit to NUMA machines with a large
    number of cores as the chance of spinlock contention is much higher
    in those machines. The cost of contention is also higher because of
    slower inter-node memory traffic.

    Due to the fact that spinlocks are acquired with preemption disabled,
    the process will not be migrated to another CPU while it is trying
    to get a spinlock. Ignoring interrupt handling, a CPU can only be
    contending in one spinlock at any one time. Counting soft IRQ, hard
    IRQ and NMI, a CPU can only have a maximum of 4 concurrent lock waiting
    activities. By allocating a set of per-cpu queue nodes and used them
    to form a waiting queue, we can encode the queue node address into a
    much smaller 24-bit size (including CPU number and queue node index)
    leaving one byte for the lock.

    Please note that the queue node is only needed when waiting for the
    lock. Once the lock is acquired, the queue node can be released to
    be used later.

    Signed-off-by: Waiman Long
    Signed-off-by: Peter Zijlstra (Intel)
    Cc: Andrew Morton
    Cc: Boris Ostrovsky
    Cc: Borislav Petkov
    Cc: Daniel J Blueman
    Cc: David Vrabel
    Cc: Douglas Hatch
    Cc: H. Peter Anvin
    Cc: Konrad Rzeszutek Wilk
    Cc: Linus Torvalds
    Cc: Oleg Nesterov
    Cc: Paolo Bonzini
    Cc: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Raghavendra K T
    Cc: Rik van Riel
    Cc: Scott J Norton
    Cc: Thomas Gleixner
    Cc: virtualization@lists.linux-foundation.org
    Cc: xen-devel@lists.xenproject.org
    Link: http://lkml.kernel.org/r/1429901803-29771-2-git-send-email-Waiman.Long@hp.com
    Signed-off-by: Ingo Molnar

    Waiman Long