All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] locking/pvqspinlock: Fix kernel panic in locking-selftest
@ 2015-07-12  1:19 Waiman Long
  2015-07-12  3:13 ` Masami Hiramatsu
  2015-07-21  9:41 ` [tip:locking/urgent] " tip-bot for Waiman Long
  0 siblings, 2 replies; 3+ messages in thread
From: Waiman Long @ 2015-07-12  1:19 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar; +Cc: linux-kernel, Masami Hiramatsu, Waiman Long

Enabling locking-selftest in a VM guest may cause the following
kernel panic:

kernel BUG at .../kernel/locking/qspinlock_paravirt.h:137!

This is due to the fact that the pvqspinlock unlock function is
expecting either a _Q_LOCKED_VAL or _Q_SLOW_VAL in the lock byte. This
patch prevents that bug report by ignoring it when debug_locks_silent
is set. Otherwise, a warning will be printed if it contains an
unexpected value.

With this patch applied, the kernel locking-selftest completed without
any noise.

Signed-off-by: Waiman Long <Waiman.Long@hp.com>
---
 kernel/locking/qspinlock_paravirt.h |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h
index 04ab181..15d3733 100644
--- a/kernel/locking/qspinlock_paravirt.h
+++ b/kernel/locking/qspinlock_paravirt.h
@@ -4,6 +4,7 @@
 
 #include <linux/hash.h>
 #include <linux/bootmem.h>
+#include <linux/debug_locks.h>
 
 /*
  * Implement paravirt qspinlocks; the general idea is to halt the vcpus instead
@@ -286,15 +287,24 @@ __visible void __pv_queued_spin_unlock(struct qspinlock *lock)
 {
 	struct __qspinlock *l = (void *)lock;
 	struct pv_node *node;
+	u8 lockval = cmpxchg(&l->locked, _Q_LOCKED_VAL, 0);
 
 	/*
 	 * We must not unlock if SLOW, because in that case we must first
 	 * unhash. Otherwise it would be possible to have multiple @lock
 	 * entries, which would be BAD.
 	 */
-	if (likely(cmpxchg(&l->locked, _Q_LOCKED_VAL, 0) == _Q_LOCKED_VAL))
+	if (likely(lockval == _Q_LOCKED_VAL))
 		return;
 
+	if (unlikely(lockval != _Q_SLOW_VAL)) {
+		if (debug_locks_silent)
+			return;
+		WARN(1, "pvqspinlock: lock 0x%lx has corrupted value 0x%x!\n",
+		    (unsigned long)lock, atomic_read(&lock->val));
+		return;
+	}
+
 	/*
 	 * Since the above failed to release, this must be the SLOW path.
 	 * Therefore start by looking up the blocked node and unhashing it.
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] locking/pvqspinlock: Fix kernel panic in locking-selftest
  2015-07-12  1:19 [PATCH] locking/pvqspinlock: Fix kernel panic in locking-selftest Waiman Long
@ 2015-07-12  3:13 ` Masami Hiramatsu
  2015-07-21  9:41 ` [tip:locking/urgent] " tip-bot for Waiman Long
  1 sibling, 0 replies; 3+ messages in thread
From: Masami Hiramatsu @ 2015-07-12  3:13 UTC (permalink / raw)
  To: Waiman Long, Peter Zijlstra, Ingo Molnar; +Cc: linux-kernel

On 2015/07/12 10:19, Waiman Long wrote:
> Enabling locking-selftest in a VM guest may cause the following
> kernel panic:
> 
> kernel BUG at .../kernel/locking/qspinlock_paravirt.h:137!
> 
> This is due to the fact that the pvqspinlock unlock function is
> expecting either a _Q_LOCKED_VAL or _Q_SLOW_VAL in the lock byte. This
> patch prevents that bug report by ignoring it when debug_locks_silent
> is set. Otherwise, a warning will be printed if it contains an
> unexpected value.
> 
> With this patch applied, the kernel locking-selftest completed without
> any noise.
> 

OK, I've tested this with make allmodconfig && make localmodconfig kernel.
(I've hit another issue to boot, but it seems not related to this issue)

Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

Thank you!



> Signed-off-by: Waiman Long <Waiman.Long@hp.com>
> ---
>  kernel/locking/qspinlock_paravirt.h |   12 +++++++++++-
>  1 files changed, 11 insertions(+), 1 deletions(-)
> 
> diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h
> index 04ab181..15d3733 100644
> --- a/kernel/locking/qspinlock_paravirt.h
> +++ b/kernel/locking/qspinlock_paravirt.h
> @@ -4,6 +4,7 @@
>  
>  #include <linux/hash.h>
>  #include <linux/bootmem.h>
> +#include <linux/debug_locks.h>
>  
>  /*
>   * Implement paravirt qspinlocks; the general idea is to halt the vcpus instead
> @@ -286,15 +287,24 @@ __visible void __pv_queued_spin_unlock(struct qspinlock *lock)
>  {
>  	struct __qspinlock *l = (void *)lock;
>  	struct pv_node *node;
> +	u8 lockval = cmpxchg(&l->locked, _Q_LOCKED_VAL, 0);
>  
>  	/*
>  	 * We must not unlock if SLOW, because in that case we must first
>  	 * unhash. Otherwise it would be possible to have multiple @lock
>  	 * entries, which would be BAD.
>  	 */
> -	if (likely(cmpxchg(&l->locked, _Q_LOCKED_VAL, 0) == _Q_LOCKED_VAL))
> +	if (likely(lockval == _Q_LOCKED_VAL))
>  		return;
>  
> +	if (unlikely(lockval != _Q_SLOW_VAL)) {
> +		if (debug_locks_silent)
> +			return;
> +		WARN(1, "pvqspinlock: lock 0x%lx has corrupted value 0x%x!\n",
> +		    (unsigned long)lock, atomic_read(&lock->val));
> +		return;
> +	}
> +
>  	/*
>  	 * Since the above failed to release, this must be the SLOW path.
>  	 * Therefore start by looking up the blocked node and unhashing it.
> 


-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [tip:locking/urgent] locking/pvqspinlock: Fix kernel panic in locking-selftest
  2015-07-12  1:19 [PATCH] locking/pvqspinlock: Fix kernel panic in locking-selftest Waiman Long
  2015-07-12  3:13 ` Masami Hiramatsu
@ 2015-07-21  9:41 ` tip-bot for Waiman Long
  1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for Waiman Long @ 2015-07-21  9:41 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, Waiman.Long, tglx, mingo, masami.hiramatsu.pt,
	linux-kernel, torvalds, hpa

Commit-ID:  cba77f03f2c7b6cc0b0a44a3c679e0abade7da62
Gitweb:     http://git.kernel.org/tip/cba77f03f2c7b6cc0b0a44a3c679e0abade7da62
Author:     Waiman Long <Waiman.Long@hp.com>
AuthorDate: Sat, 11 Jul 2015 21:19:19 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 21 Jul 2015 10:18:07 +0200

locking/pvqspinlock: Fix kernel panic in locking-selftest

Enabling locking-selftest in a VM guest may cause the following
kernel panic:

  kernel BUG at .../kernel/locking/qspinlock_paravirt.h:137!

This is due to the fact that the pvqspinlock unlock function is
expecting either a _Q_LOCKED_VAL or _Q_SLOW_VAL in the lock
byte. This patch prevents that bug report by ignoring it when
debug_locks_silent is set. Otherwise, a warning will be printed
if it contains an unexpected value.

With this patch applied, the kernel locking-selftest completed
without any noise.

Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Waiman Long <Waiman.Long@hp.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1436663959-53092-1-git-send-email-Waiman.Long@hp.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/locking/qspinlock_paravirt.h | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h
index 04ab181..df19ae4 100644
--- a/kernel/locking/qspinlock_paravirt.h
+++ b/kernel/locking/qspinlock_paravirt.h
@@ -4,6 +4,7 @@
 
 #include <linux/hash.h>
 #include <linux/bootmem.h>
+#include <linux/debug_locks.h>
 
 /*
  * Implement paravirt qspinlocks; the general idea is to halt the vcpus instead
@@ -286,15 +287,23 @@ __visible void __pv_queued_spin_unlock(struct qspinlock *lock)
 {
 	struct __qspinlock *l = (void *)lock;
 	struct pv_node *node;
+	u8 lockval = cmpxchg(&l->locked, _Q_LOCKED_VAL, 0);
 
 	/*
 	 * We must not unlock if SLOW, because in that case we must first
 	 * unhash. Otherwise it would be possible to have multiple @lock
 	 * entries, which would be BAD.
 	 */
-	if (likely(cmpxchg(&l->locked, _Q_LOCKED_VAL, 0) == _Q_LOCKED_VAL))
+	if (likely(lockval == _Q_LOCKED_VAL))
 		return;
 
+	if (unlikely(lockval != _Q_SLOW_VAL)) {
+		if (debug_locks_silent)
+			return;
+		WARN(1, "pvqspinlock: lock %p has corrupted value 0x%x!\n", lock, atomic_read(&lock->val));
+		return;
+	}
+
 	/*
 	 * Since the above failed to release, this must be the SLOW path.
 	 * Therefore start by looking up the blocked node and unhashing it.

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-07-21  9:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-12  1:19 [PATCH] locking/pvqspinlock: Fix kernel panic in locking-selftest Waiman Long
2015-07-12  3:13 ` Masami Hiramatsu
2015-07-21  9:41 ` [tip:locking/urgent] " tip-bot for Waiman Long

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.