From: Waiman Long <waiman.long@hp.com> To: Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com> Cc: linux-arch@vger.kernel.org, Rik van Riel <riel@redhat.com>, Gleb Natapov <gleb@redhat.com>, kvm@vger.kernel.org, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>, Peter Zijlstra <peterz@infradead.org>, Scott J Norton <scott.norton@hp.com>, x86@kernel.org, Paolo Bonzini <paolo.bonzini@gmail.com>, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org, Ingo Molnar <mingo@redhat.com>, Chegu Vinod <chegu_vinod@hp.com>, David Vrabel <david.vrabel@citrix.com>, "H. Peter Anvin" <hpa@zytor.com>, xen-devel@lists.xenproject.org, Thomas Gleixner <tglx@linutronix.de>, "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>, Linus Torvalds <torvalds@linux-foundation.org>, Oleg Nesterov <oleg@redhat.com>, Aswin Chandramouleeswaran <aswin@hp.com> Subject: Re: [PATCH v8 00/10] qspinlock: a 4-byte queue spinlock with PV support Date: Tue, 08 Apr 2014 15:15:58 -0400 [thread overview] Message-ID: <53444AEE.9050705@hp.com> (raw) In-Reply-To: <5342E5B2.1070306@linux.vnet.ibm.com> [-- Attachment #1: Type: text/plain, Size: 1194 bytes --] On 04/07/2014 01:51 PM, Raghavendra K T wrote: > On 04/07/2014 10:08 PM, Waiman Long wrote: >> On 04/07/2014 02:14 AM, Raghavendra K T wrote: > [...] >>> But I am seeing hang in overcommit cases. Gdb showed that many vcpus >>> are halted and there was no progress. Suspecting the problem /race with >>> halting, I removed the halt() part of kvm_hibernate(). I am yet to >>> take a closer look at the code on halt() related changes. >> >> It seems like there may still be race conditions where the current code >> is not handling correctly. I will look into that to see where the >> problem is. BTW, what test do you use to produce the hang condition? > > Running ebizzy on 2 of the vms simultaneously (for sometime in > repeated loop) could reproduce it. > Yes, I am able to reproduce the hang problem with ebizzy. BTW, could you try to apply the attached patch file on top of the v8 patch series to see if it can fix the hang problem? > >> What is the baseline for the performance improvement? Is it without the >> unfair lock and PV qspinlock? > > Baseline was 3.14-rc8 without any of the qspin patch series. > Does the baseline have PV ticketlock or without any PV support? -Longman [-- Attachment #2: 0011 --] [-- Type: text/plain, Size: 4725 bytes --] diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index a35cd02..825c535 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -717,9 +717,10 @@ static __always_inline void __queue_kick_cpu(int cpu) PVOP_VCALL1(pv_lock_ops.kick_cpu, cpu); } -static __always_inline void __queue_hibernate(enum pv_lock_stats type) +static __always_inline void +__queue_hibernate(enum pv_lock_stats type, s8 *state, s8 sval) { - PVOP_VCALL1(pv_lock_ops.hibernate, type); + PVOP_VCALL3(pv_lock_ops.hibernate, type, state, sval); } static __always_inline void __queue_lockstat(enum pv_lock_stats type) diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index a8564b9..0e204dd 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -346,7 +346,7 @@ enum pv_lock_stats { struct pv_lock_ops { #ifdef CONFIG_QUEUE_SPINLOCK void (*kick_cpu)(int cpu); - void (*hibernate)(enum pv_lock_stats type); + void (*hibernate)(enum pv_lock_stats type, s8 *state, s8 sval); void (*lockstat)(enum pv_lock_stats type); #else struct paravirt_callee_save lock_spinning; diff --git a/arch/x86/include/asm/pvqspinlock.h b/arch/x86/include/asm/pvqspinlock.h index a632dcb..4b33769 100644 --- a/arch/x86/include/asm/pvqspinlock.h +++ b/arch/x86/include/asm/pvqspinlock.h @@ -134,7 +134,7 @@ static __always_inline void pv_head_spin_check(struct pv_qvars *pv, int *count, *count = 0; return; } - __queue_hibernate(PV_HALT_QHEAD); + __queue_hibernate(PV_HALT_QHEAD, &pv->cpustate, PV_CPU_HALTED); __queue_lockstat((pv->cpustate == PV_CPU_KICKED) ? PV_WAKE_KICKED : PV_WAKE_SPURIOUS); ACCESS_ONCE(pv->cpustate) = PV_CPU_ACTIVE; @@ -169,7 +169,7 @@ static __always_inline void pv_queue_spin_check(struct pv_qvars *pv, int *count) * pv_next_node_check pv_queue_spin_check * ------------------ ------------------- * [1] qhead = true [3] cpustate = PV_CPU_HALTED - * barrier() barrier() + * smp_mb() smp_mb() * [2] if (cpustate [4] if (qhead) * == PV_CPU_HALTED) * @@ -178,9 +178,10 @@ static __always_inline void pv_queue_spin_check(struct pv_qvars *pv, int *count) * _QLOCK_LOCKED_SLOWPATH may or may not be set * 3,4,1,2 - the CPU is halt and _QLOCK_LOCKED_SLOWPATH is set */ - barrier(); + smp_mb(); if (!ACCESS_ONCE(pv->qhead)) { - __queue_hibernate(PV_HALT_QNODE); + __queue_hibernate(PV_HALT_QNODE, &pv->cpustate, + PV_CPU_HALTED); __queue_lockstat((pv->cpustate == PV_CPU_KICKED) ? PV_WAKE_KICKED : PV_WAKE_SPURIOUS); } else { @@ -208,7 +209,7 @@ pv_next_node_check(struct pv_qvars *pv, struct qspinlock *lock) /* * Make sure qhead flag is visible before checking the cpustate flag */ - barrier(); + smp_mb(); if (ACCESS_ONCE(pv->cpustate) == PV_CPU_HALTED) ACCESS_ONCE(((union arch_qspinlock *)lock)->lock) = _QLOCK_LOCKED_SLOWPATH; diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 7d97e58..ce4b74b 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -880,23 +880,29 @@ static void kvm_kick_cpu_stats(int cpu) /* * Halt the current CPU & release it back to the host */ -static void kvm_hibernate(enum pv_lock_stats type) +static void kvm_hibernate(enum pv_lock_stats type, s8 *state, s8 sval) { unsigned long flags; if (in_nmi()) return; - kvm_halt_stats(type); /* * Make sure an interrupt handler can't upset things in a * partially setup state. */ local_irq_save(flags); + /* + * Don't halt if the CPU state has been changed. + */ + if (ACCESS_ONCE(*state) != sval) + goto out; + kvm_halt_stats(type); if (arch_irqs_disabled_flags(flags)) halt(); else safe_halt(); +out: local_irq_restore(flags); } #endif /* !CONFIG_QUEUE_SPINLOCK */ diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 6bbe798..c597bbd 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -271,7 +271,7 @@ static void xen_kick_cpu(int cpu) /* * Halt the current CPU & release it back to the host */ -static void xen_hibernate(enum pv_lock_stats type) +static void xen_hibernate(enum pv_lock_stats type, s8 *state, s8 sval) { int irq = __this_cpu_read(lock_kicker_irq); unsigned long flags; @@ -292,7 +292,11 @@ static void xen_hibernate(enum pv_lock_stats type) /* Allow interrupts while blocked */ local_irq_restore(flags); - + /* + * Don't halt if the CPU state has been changed. + */ + if (ACCESS_ONCE(*state) != sval) + return; /* * If an interrupt happens here, it will leave the wakeup irq * pending, which will cause xen_poll_irq() to return [-- Attachment #3: Type: text/plain, Size: 183 bytes --] _______________________________________________ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
WARNING: multiple messages have this Message-ID (diff)
From: Waiman Long <waiman.long@hp.com> To: Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com> Cc: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>, Peter Zijlstra <peterz@infradead.org>, linux-arch@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org, xen-devel@lists.xenproject.org, kvm@vger.kernel.org, Paolo Bonzini <paolo.bonzini@gmail.com>, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>, "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>, Rik van Riel <riel@redhat.com>, Linus Torvalds <torvalds@linux-foundation.org>, David Vrabel <david.vrabel@citrix.com>, Oleg Nesterov <oleg@redhat.com>, Gleb Natapov <gleb@redhat.com>, Aswin Chandramouleeswaran <aswin@hp.com>, Scott J Norton <scott.norton@hp.com>, Chegu Vinod <chegu_vinod@hp.com> Subject: Re: [PATCH v8 00/10] qspinlock: a 4-byte queue spinlock with PV support Date: Tue, 08 Apr 2014 15:15:58 -0400 [thread overview] Message-ID: <53444AEE.9050705@hp.com> (raw) Message-ID: <20140408191558.uotPHLB5Qkfwq82W1eVUjYgSmE2xG30AxlZhCN24juk@z> (raw) In-Reply-To: <5342E5B2.1070306@linux.vnet.ibm.com> [-- Attachment #1: Type: text/plain, Size: 1194 bytes --] On 04/07/2014 01:51 PM, Raghavendra K T wrote: > On 04/07/2014 10:08 PM, Waiman Long wrote: >> On 04/07/2014 02:14 AM, Raghavendra K T wrote: > [...] >>> But I am seeing hang in overcommit cases. Gdb showed that many vcpus >>> are halted and there was no progress. Suspecting the problem /race with >>> halting, I removed the halt() part of kvm_hibernate(). I am yet to >>> take a closer look at the code on halt() related changes. >> >> It seems like there may still be race conditions where the current code >> is not handling correctly. I will look into that to see where the >> problem is. BTW, what test do you use to produce the hang condition? > > Running ebizzy on 2 of the vms simultaneously (for sometime in > repeated loop) could reproduce it. > Yes, I am able to reproduce the hang problem with ebizzy. BTW, could you try to apply the attached patch file on top of the v8 patch series to see if it can fix the hang problem? > >> What is the baseline for the performance improvement? Is it without the >> unfair lock and PV qspinlock? > > Baseline was 3.14-rc8 without any of the qspin patch series. > Does the baseline have PV ticketlock or without any PV support? -Longman [-- Attachment #2: 0011 --] [-- Type: text/plain, Size: 4725 bytes --] diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index a35cd02..825c535 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -717,9 +717,10 @@ static __always_inline void __queue_kick_cpu(int cpu) PVOP_VCALL1(pv_lock_ops.kick_cpu, cpu); } -static __always_inline void __queue_hibernate(enum pv_lock_stats type) +static __always_inline void +__queue_hibernate(enum pv_lock_stats type, s8 *state, s8 sval) { - PVOP_VCALL1(pv_lock_ops.hibernate, type); + PVOP_VCALL3(pv_lock_ops.hibernate, type, state, sval); } static __always_inline void __queue_lockstat(enum pv_lock_stats type) diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index a8564b9..0e204dd 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -346,7 +346,7 @@ enum pv_lock_stats { struct pv_lock_ops { #ifdef CONFIG_QUEUE_SPINLOCK void (*kick_cpu)(int cpu); - void (*hibernate)(enum pv_lock_stats type); + void (*hibernate)(enum pv_lock_stats type, s8 *state, s8 sval); void (*lockstat)(enum pv_lock_stats type); #else struct paravirt_callee_save lock_spinning; diff --git a/arch/x86/include/asm/pvqspinlock.h b/arch/x86/include/asm/pvqspinlock.h index a632dcb..4b33769 100644 --- a/arch/x86/include/asm/pvqspinlock.h +++ b/arch/x86/include/asm/pvqspinlock.h @@ -134,7 +134,7 @@ static __always_inline void pv_head_spin_check(struct pv_qvars *pv, int *count, *count = 0; return; } - __queue_hibernate(PV_HALT_QHEAD); + __queue_hibernate(PV_HALT_QHEAD, &pv->cpustate, PV_CPU_HALTED); __queue_lockstat((pv->cpustate == PV_CPU_KICKED) ? PV_WAKE_KICKED : PV_WAKE_SPURIOUS); ACCESS_ONCE(pv->cpustate) = PV_CPU_ACTIVE; @@ -169,7 +169,7 @@ static __always_inline void pv_queue_spin_check(struct pv_qvars *pv, int *count) * pv_next_node_check pv_queue_spin_check * ------------------ ------------------- * [1] qhead = true [3] cpustate = PV_CPU_HALTED - * barrier() barrier() + * smp_mb() smp_mb() * [2] if (cpustate [4] if (qhead) * == PV_CPU_HALTED) * @@ -178,9 +178,10 @@ static __always_inline void pv_queue_spin_check(struct pv_qvars *pv, int *count) * _QLOCK_LOCKED_SLOWPATH may or may not be set * 3,4,1,2 - the CPU is halt and _QLOCK_LOCKED_SLOWPATH is set */ - barrier(); + smp_mb(); if (!ACCESS_ONCE(pv->qhead)) { - __queue_hibernate(PV_HALT_QNODE); + __queue_hibernate(PV_HALT_QNODE, &pv->cpustate, + PV_CPU_HALTED); __queue_lockstat((pv->cpustate == PV_CPU_KICKED) ? PV_WAKE_KICKED : PV_WAKE_SPURIOUS); } else { @@ -208,7 +209,7 @@ pv_next_node_check(struct pv_qvars *pv, struct qspinlock *lock) /* * Make sure qhead flag is visible before checking the cpustate flag */ - barrier(); + smp_mb(); if (ACCESS_ONCE(pv->cpustate) == PV_CPU_HALTED) ACCESS_ONCE(((union arch_qspinlock *)lock)->lock) = _QLOCK_LOCKED_SLOWPATH; diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 7d97e58..ce4b74b 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -880,23 +880,29 @@ static void kvm_kick_cpu_stats(int cpu) /* * Halt the current CPU & release it back to the host */ -static void kvm_hibernate(enum pv_lock_stats type) +static void kvm_hibernate(enum pv_lock_stats type, s8 *state, s8 sval) { unsigned long flags; if (in_nmi()) return; - kvm_halt_stats(type); /* * Make sure an interrupt handler can't upset things in a * partially setup state. */ local_irq_save(flags); + /* + * Don't halt if the CPU state has been changed. + */ + if (ACCESS_ONCE(*state) != sval) + goto out; + kvm_halt_stats(type); if (arch_irqs_disabled_flags(flags)) halt(); else safe_halt(); +out: local_irq_restore(flags); } #endif /* !CONFIG_QUEUE_SPINLOCK */ diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 6bbe798..c597bbd 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -271,7 +271,7 @@ static void xen_kick_cpu(int cpu) /* * Halt the current CPU & release it back to the host */ -static void xen_hibernate(enum pv_lock_stats type) +static void xen_hibernate(enum pv_lock_stats type, s8 *state, s8 sval) { int irq = __this_cpu_read(lock_kicker_irq); unsigned long flags; @@ -292,7 +292,11 @@ static void xen_hibernate(enum pv_lock_stats type) /* Allow interrupts while blocked */ local_irq_restore(flags); - + /* + * Don't halt if the CPU state has been changed. + */ + if (ACCESS_ONCE(*state) != sval) + return; /* * If an interrupt happens here, it will leave the wakeup irq * pending, which will cause xen_poll_irq() to return
next prev parent reply other threads:[~2014-04-08 19:15 UTC|newest] Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-04-02 13:27 [PATCH v8 00/10] qspinlock: a 4-byte queue spinlock with PV support Waiman Long 2014-04-02 13:27 ` [PATCH v8 01/10] qspinlock: A generic 4-byte queue spinlock implementation Waiman Long 2014-04-02 13:27 ` Waiman Long 2014-04-04 13:00 ` Peter Zijlstra 2014-04-04 13:00 ` Peter Zijlstra 2014-04-04 14:59 ` Waiman Long 2014-04-04 14:59 ` Waiman Long 2014-04-04 17:53 ` Ingo Molnar 2014-04-04 17:53 ` Ingo Molnar 2014-04-07 14:16 ` Peter Zijlstra 2014-04-07 14:16 ` Peter Zijlstra 2014-04-04 16:57 ` Konrad Rzeszutek Wilk 2014-04-04 16:57 ` Konrad Rzeszutek Wilk 2014-04-04 17:08 ` Waiman Long 2014-04-04 17:08 ` Waiman Long 2014-04-04 17:54 ` Ingo Molnar 2014-04-04 17:54 ` Ingo Molnar 2014-04-07 14:09 ` Peter Zijlstra 2014-04-07 14:09 ` Peter Zijlstra 2014-04-07 16:59 ` Waiman Long 2014-04-07 16:59 ` Waiman Long 2014-04-07 14:12 ` Peter Zijlstra 2014-04-07 14:12 ` Peter Zijlstra 2014-04-07 14:33 ` Konrad Rzeszutek Wilk 2014-04-07 14:33 ` Konrad Rzeszutek Wilk 2014-04-02 13:27 ` [PATCH v8 02/10] qspinlock, x86: Enable x86-64 to use queue spinlock Waiman Long 2014-04-02 13:27 ` Waiman Long 2014-04-02 13:27 ` [PATCH v8 03/10] qspinlock: More optimized code for smaller NR_CPUS Waiman Long 2014-04-02 13:27 ` Waiman Long 2014-04-02 13:27 ` [PATCH v8 04/10] qspinlock: Optimized code path for 2 contending tasks Waiman Long 2014-04-02 13:27 ` [PATCH v8 05/10] pvqspinlock, x86: Allow unfair spinlock in a PV guest Waiman Long 2014-04-02 13:27 ` Waiman Long 2014-04-02 13:27 ` [PATCH v8 06/10] pvqspinlock: Enable lock stealing in queue lock waiters Waiman Long 2014-04-02 13:27 ` [PATCH v8 07/10] pvqspinlock, x86: Rename paravirt_ticketlocks_enabled Waiman Long 2014-04-02 13:27 ` Waiman Long 2014-04-02 13:27 ` [PATCH v8 08/10] pvqspinlock, x86: Add qspinlock para-virtualization support Waiman Long 2014-04-02 13:27 ` Waiman Long 2014-04-02 13:27 ` [PATCH v8 09/10] pvqspinlock, x86: Enable qspinlock PV support for KVM Waiman Long 2014-04-02 13:27 ` [PATCH v8 10/10] pvqspinlock, x86: Enable qspinlock PV support for XEN Waiman Long 2014-04-02 13:27 ` Waiman Long 2014-04-02 14:39 ` Konrad Rzeszutek Wilk 2014-04-02 14:39 ` Konrad Rzeszutek Wilk 2014-04-02 20:38 ` Waiman Long 2014-04-02 20:38 ` Waiman Long 2014-04-02 14:32 ` [PATCH v8 00/10] qspinlock: a 4-byte queue spinlock with PV support Konrad Rzeszutek Wilk 2014-04-02 14:32 ` Konrad Rzeszutek Wilk 2014-04-02 20:35 ` Waiman Long 2014-04-03 2:10 ` Waiman Long 2014-04-03 2:10 ` Waiman Long 2014-04-03 17:23 ` Konrad Rzeszutek Wilk 2014-04-03 17:23 ` Konrad Rzeszutek Wilk 2014-04-04 2:57 ` Waiman Long 2014-04-04 2:57 ` Waiman Long 2014-04-04 16:55 ` Konrad Rzeszutek Wilk 2014-04-04 16:55 ` Konrad Rzeszutek Wilk 2014-04-04 17:13 ` Waiman Long 2014-04-04 17:13 ` Waiman Long 2014-04-04 17:58 ` Konrad Rzeszutek Wilk 2014-04-04 17:58 ` Konrad Rzeszutek Wilk 2014-04-04 18:33 ` Konrad Rzeszutek Wilk 2014-04-04 18:33 ` Konrad Rzeszutek Wilk 2014-04-04 18:14 ` Marcos E. Matsunaga 2014-04-04 15:25 ` Konrad Rzeszutek Wilk 2014-04-04 15:25 ` Konrad Rzeszutek Wilk 2014-04-07 6:14 ` Raghavendra K T 2014-04-07 16:38 ` Waiman Long 2014-04-07 16:38 ` Waiman Long 2014-04-07 17:51 ` Raghavendra K T 2014-04-07 17:51 ` Raghavendra K T 2014-04-08 19:15 ` Waiman Long [this message] 2014-04-08 19:15 ` Waiman Long 2014-04-09 12:08 ` Raghavendra K T -- strict thread matches above, loose matches on Subject: below -- 2014-04-01 20:47 Waiman Long
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=53444AEE.9050705@hp.com \ --to=waiman.long@hp.com \ --cc=aswin@hp.com \ --cc=chegu_vinod@hp.com \ --cc=david.vrabel@citrix.com \ --cc=gleb@redhat.com \ --cc=hpa@zytor.com \ --cc=konrad.wilk@oracle.com \ --cc=kvm@vger.kernel.org \ --cc=linux-arch@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mingo@redhat.com \ --cc=oleg@redhat.com \ --cc=paolo.bonzini@gmail.com \ --cc=paulmck@linux.vnet.ibm.com \ --cc=peterz@infradead.org \ --cc=raghavendra.kt@linux.vnet.ibm.com \ --cc=riel@redhat.com \ --cc=scott.norton@hp.com \ --cc=tglx@linutronix.de \ --cc=torvalds@linux-foundation.org \ --cc=virtualization@lists.linux-foundation.org \ --cc=x86@kernel.org \ --cc=xen-devel@lists.xenproject.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).