rpms/kernel/F-12 linux-2.6-xen-spinlock-enable-interrupts-only-when-blocking.patch, NONE, 1.1 linux-2.6-xen-spinlock-stronger-barrier.patch, NONE, 1.1 kernel.spec, 1.1834, 1.1835

Chuck Ebbert cebbert at fedoraproject.org
Fri Sep 25 21:16:39 UTC 2009


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-12
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv25329

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-xen-spinlock-enable-interrupts-only-when-blocking.patch 
	linux-2.6-xen-spinlock-stronger-barrier.patch 
Log Message:
Add Xen spinlock patches to improve scalability.

linux-2.6-xen-spinlock-enable-interrupts-only-when-blocking.patch:
 spinlock.c |   19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

--- NEW FILE linux-2.6-xen-spinlock-enable-interrupts-only-when-blocking.patch ---
From: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
Date: Wed, 9 Sep 2009 19:33:51 +0000 (-0700)
Subject: xen: only enable interrupts while actually blocking for spinlock
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=4d576b57b50a92801e6493e76e5243d6cff193d2

xen: only enable interrupts while actually blocking for spinlock

Where possible we enable interrupts while waiting for a spinlock to
become free, in order to reduce big latency spikes in interrupt handling.

However, at present if we manage to pick up the spinlock just before
blocking, we'll end up holding the lock with interrupts enabled for a
while.  This will cause a deadlock if we recieve an interrupt in that
window, and the interrupt handler tries to take the lock too.

Solve this by shrinking the interrupt-enabled region to just around the
blocking call.

[ Impact: avoid race/deadlock when using Xen PV spinlocks ]

Reported-by: "Yang, Xiaowei" <xiaowei.yang at intel.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
---

diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 5601506..2f91e56 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -187,7 +187,6 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
 	struct xen_spinlock *prev;
 	int irq = __get_cpu_var(lock_kicker_irq);
 	int ret;
-	unsigned long flags;
 	u64 start;
 
 	/* If kicker interrupts not initialized yet, just spin */
@@ -199,16 +198,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
 	/* announce we're spinning */
 	prev = spinning_lock(xl);
 
-	flags = __raw_local_save_flags();
-	if (irq_enable) {
-		ADD_STATS(taken_slow_irqenable, 1);
-		raw_local_irq_enable();
-	}
-
 	ADD_STATS(taken_slow, 1);
 	ADD_STATS(taken_slow_nested, prev != NULL);
 
 	do {
+		unsigned long flags;
+
 		/* clear pending */
 		xen_clear_irq_pending(irq);
 
@@ -228,6 +223,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
 			goto out;
 		}
 
+		flags = __raw_local_save_flags();
+		if (irq_enable) {
+			ADD_STATS(taken_slow_irqenable, 1);
+			raw_local_irq_enable();
+		}
+
 		/*
 		 * Block until irq becomes pending.  If we're
 		 * interrupted at this point (after the trylock but
@@ -238,13 +239,15 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
 		 * pending.
 		 */
 		xen_poll_irq(irq);
+
+		raw_local_irq_restore(flags);
+
 		ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq));
 	} while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */
 
 	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 
 out:
-	raw_local_irq_restore(flags);
 	unspinning_lock(xl, prev);
 	spin_time_accum_blocked(start);
 

linux-2.6-xen-spinlock-stronger-barrier.patch:
 spinlock.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-xen-spinlock-stronger-barrier.patch ---
From: Yang Xiaowei <xiaowei.yang at intel.com>
Date: Wed, 9 Sep 2009 19:44:52 +0000 (-0700)
Subject: xen: use stronger barrier after unlocking lock
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=2496afbf1e50c70f80992656bcb730c8583ddac3

xen: use stronger barrier after unlocking lock

We need to have a stronger barrier between releasing the lock and
checking for any waiting spinners.  A compiler barrier is not sufficient
because the CPU's ordering rules do not prevent the read xl->spinners
from happening before the unlock assignment, as they are different
memory locations.

We need to have an explicit barrier to enforce the write-read ordering
to different memory locations.

Because of it, I can't bring up > 4 HVM guests on one SMP machine.

[ Code and commit comments expanded -J ]

[ Impact: avoid deadlock when using Xen PV spinlocks ]

Signed-off-by: Yang Xiaowei <xiaowei.yang at intel.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
---

diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 2f91e56..36a5141 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -326,8 +326,13 @@ static void xen_spin_unlock(struct raw_spinlock *lock)
 	smp_wmb();		/* make sure no writes get moved after unlock */
 	xl->lock = 0;		/* release lock */
 
-	/* make sure unlock happens before kick */
-	barrier();
+	/*
+	 * Make sure unlock happens before checking for waiting
+	 * spinners.  We need a strong barrier to enforce the
+	 * write-read ordering to different memory locations, as the
+	 * CPU makes no implied guarantees about their ordering.
+	 */
+	mb();
 
 	if (unlikely(xl->spinners))
 		xen_spin_unlock_slow(xl);


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-12/kernel.spec,v
retrieving revision 1.1834
retrieving revision 1.1835
diff -u -p -r1.1834 -r1.1835
--- kernel.spec	25 Sep 2009 20:46:37 -0000	1.1834
+++ kernel.spec	25 Sep 2009 21:16:39 -0000	1.1835
@@ -695,6 +695,8 @@ Patch1553: linux-2.6-ksm-fix-munlock.pat
 Patch1578: linux-2.6-xen-stack-protector-fix.patch
 Patch1579: linux-2.6-virtio_blk-revert-QUEUE_FLAG_VIRT-addition.patch
 Patch1580: linux-2.6-xen-check-efer-fix.patch
+Patch1581: linux-2.6-xen-spinlock-enable-interrupts-only-when-blocking.patch
+Patch1582: linux-2.6-xen-spinlock-stronger-barrier.patch
 
 # nouveau + drm fixes
 Patch1812: drm-next-8ef8678c8.patch
@@ -1357,6 +1359,10 @@ ApplyPatch linux-2.6-xen-stack-protector
 ApplyPatch linux-2.6-virtio_blk-revert-QUEUE_FLAG_VIRT-addition.patch
 ApplyPatch linux-2.6-xen-check-efer-fix.patch
 
+# improve xen spinlock scalability
+ApplyPatch linux-2.6-xen-spinlock-enable-interrupts-only-when-blocking.patch
+ApplyPatch linux-2.6-xen-spinlock-stronger-barrier.patch
+
 # Fix block I/O errors in KVM
 ApplyPatch linux-2.6-block-silently-error-unsupported-empty-barriers-too.patch
 
@@ -2061,6 +2067,9 @@ fi
 # and build.
 
 %changelog
+* Sat Sep 26 2009 Chuck Ebbert <cebbert at redhat.com> 2.6.31.1-49
+- Add Xen spinlock patches to improve scalability.
+
 * Sat Sep 26 2009 Dave Airlie <airlied at redhat.com> 2.6.31.1-48
 - drm-next-8ef8678c8.patch: fix intel/nouveau kms
 




More information about the fedora-extras-commits mailing list