Patch "locking/qspinlock/x86: Fix performance regression under unaccelerated VMs" has been added to the 4.2-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
locking/qspinlock/x86: Fix performance regression under unaccelerated VMs
to the 4.2-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
locking-qspinlock-x86-fix-performance-regression-under-unaccelerated-vms.patch
and it can be found in the queue-4.2 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
43b3f02899f74ae9914a39547cc5492156f0027aMon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Fri, 4 Sep 2015 17:25:23 +0200
Subject: locking/qspinlock/x86: Fix performance regression under unaccelerated VMs
From: Peter Zijlstra <[email protected]>
commit 43b3f02899f74ae9914a39547cc5492156f0027a upstream.
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.
arch/x86/include/asm/qspinlock.h +12 -4
@@ -39,15 +39,23 @@ static inline void queued_spin_unlock(struct qspinlock *lock) }#endif -#define virt_queued_spin_lock virt_queued_spin_lock +#define virt_spin_lock virt_spin_lock -static inline bool virt_queued_spin_lock (struct qspinlock *lock) +static inline bool virt_spin_lock (struct qspinlock *lock) {if (!static_cpu_has (X86_FEATURE_HYPERVISOR ))return false; -while (atomic_cmpxchg (&lock->val,0 , _Q_LOCKED_VAL) !=0 ) -cpu_relax (); +/* +* On hypervisors without PARAVIRT_SPINLOCKS support we fall +* back to a Test-and-Set spinlock, because fair locks have +* horrible lock 'holder' preemption issues. +*/ + +do { +while (atomic_read (&lock->val) !=0 ) +cpu_relax (); + }while (atomic_cmpxchg (&lock->val,0 , _Q_LOCKED_VAL) !=0 );return true; }
include/asm-generic/qspinlock.h +2 -2
@@ -111,8 +111,8 @@ static inline void queued_spin_unlock_wait(struct qspinlock *lock)cpu_relax (); } -#ifndef virt_queued_spin_lock -static __always_inline bool virt_queued_spin_lock(struct qspinlock *lock) +#ifndef virt_spin_lock +static __always_inline bool virt_spin_lock(struct qspinlock *lock) {return false; }
kernel/locking/qspinlock.c +1 -1
@@ -289,7 +289,7 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)if (pv_enabled ()) goto queue; -if (virt_queued_spin_lock (lock)) +if (virt_spin_lock (lock))return ;/*
Patches currently in stable-queue which might be from [email protected] are
queue-4.2/time-fix-timekeeping_freqadjust-s-incorrect-use-of-abs-instead-of-abs64.patch queue-4.2/perf-x86-intel-fix-constraint-access.patch queue-4.2/sched-access-local-runqueue-directly-in-single_task_running.patch queue-4.2/locking-qspinlock-x86-only-emit-the-test-and-set-fallback-when-building-guest-support.patch queue-4.2/locking-qspinlock-x86-fix-performance-regression-under-unaccelerated-vms.patch