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

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.