From patchwork Tue Feb 5 17:17:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Bader X-Patchwork-Id: 218304 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 45A1D2C02CA for ; Wed, 6 Feb 2013 04:17:47 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1U2m9K-00035Q-53; Tue, 05 Feb 2013 17:17:38 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1U2m9H-00035K-S0 for kernel-team@lists.ubuntu.com; Tue, 05 Feb 2013 17:17:35 +0000 Received: from p5b2e3c52.dip.t-dialin.net ([91.46.60.82] helo=[192.168.2.5]) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1U2m9H-0003lG-Ns for kernel-team@lists.ubuntu.com; Tue, 05 Feb 2013 17:17:35 +0000 Message-ID: <51113EAD.4040507@canonical.com> Date: Tue, 05 Feb 2013 18:17:33 +0100 From: Stefan Bader User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2 MIME-Version: 1.0 To: kernel-team@lists.ubuntu.com Subject: [Precise SRU v2] Call xen_poll_irq with interrupts disabled References: <1359995982-20657-1-git-send-email-stefan.bader@canonical.com> <20130205132556.GH10405@dm> <511114E2.9040408@canonical.com> <51111604.201@canonical.com> In-Reply-To: <51111604.201@canonical.com> X-Enigmail-Version: 1.4.6 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com Ok this version also prevents the hang. From fca51db699b6254f51b1ef4cafc0751179a2dd4c Mon Sep 17 00:00:00 2001 From: Stefan Bader Date: Tue, 5 Feb 2013 15:22:37 +0100 Subject: [PATCH] UBUNTU: SAUCE: xen/pv-spinlock: Never enable interrupts in xen_spin_lock_slow() The pv-ops spinlock code for Xen will call xen_spin_lock_slow() if a lock cannot be obtained quickly by normal spinning. The slow variant will put the VCPU onto a waiters list, then enable interrupts (which are event channel messages in this case) and calls a hypervisor function that is supposed to return when the lock is released. Using a test case which has a lot of threads running that cause a high utilization of this spinlock code, it is observed that the VCPU which is the first one on the waiters list seems to be doing other things (no trace of the hv call on the stack) while the waiters list still has it as the head. So other VCPUs which try to acquire the lock are stuck in the hv call forever. And that sooner than later end up in some circular locking. By testing I can see this gets avoided when the interrupts remain disabled for the duration of the poll_irq hypercall. Xen PVM is the only affected setup because that is the only one using the special spinlock api call which passes on the flags as they were before (which is used to decide whether interrupts get re-enabled in the Xen code). KVM maps that call to the variant which will not look at the previous state of interrupts and thus never re-enables them. BugLink: http://bugs.launchpad.net/bugs/1011792 [v2: limited changes and reworded commit message] Signed-off-by: Stefan Bader --- arch/x86/xen/spinlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index d69cc6c..6051359 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -242,7 +242,7 @@ static noinline int xen_spin_lock_slow(struct arch_spinlock *lock, bool irq_enab flags = arch_local_save_flags(); if (irq_enable) { ADD_STATS(taken_slow_irqenable, 1); - raw_local_irq_enable(); + /* raw_local_irq_enable(); */ } /* @@ -256,7 +256,7 @@ static noinline int xen_spin_lock_slow(struct arch_spinlock *lock, bool irq_enab */ xen_poll_irq(irq); - raw_local_irq_restore(flags); + /* 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 */ -- 1.7.9.5