From: tip-bot for Ingo Molnar <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: tglx@linutronix.de, alfredoalvarezernandez@gmail.com,
mingo@kernel.org, torvalds@linux-foundation.org,
alfredoalvarezfernandez@gmail.com, linux-kernel@vger.kernel.org,
hpa@zytor.com, peterz@infradead.org, paulmck@linux.vnet.ibm.com
Subject: [tip:locking/core] locking/lockdep: Detect chain_key collisions
Date: Mon, 29 Feb 2016 03:24:39 -0800 [thread overview]
Message-ID: <tip-9e4e7554e755aaad8df0e26268787438735b4b76@git.kernel.org> (raw)
In-Reply-To: <1455864533-7536-4-git-send-email-alfredoalvarezernandez@gmail.com>
Commit-ID: 9e4e7554e755aaad8df0e26268787438735b4b76
Gitweb: http://git.kernel.org/tip/9e4e7554e755aaad8df0e26268787438735b4b76
Author: Ingo Molnar <mingo@kernel.org>
AuthorDate: Mon, 29 Feb 2016 10:03:58 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 29 Feb 2016 10:32:29 +0100
locking/lockdep: Detect chain_key collisions
Add detection for chain_key collision under CONFIG_DEBUG_LOCKDEP.
When a collision is detected the problem is reported and all lock
debugging is turned off.
Tested using liblockdep and the added tests before and after
applying the fix, confirming both that the code added for the
detection correctly reports the problem and that the fix actually
fixes it.
Tested tweaking lockdep to generate false collisions and
verified that the problem is reported and that lock debugging is
turned off.
Also tested with lockdep's test suite after applying the patch:
[ 0.000000] Good, all 253 testcases passed! |
Signed-off-by: Alfredo Alvarez Fernandez <alfredoalvarezernandez@gmail.com>
Cc: Alfredo Alvarez Fernandez <alfredoalvarezfernandez@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: sasha.levin@oracle.com
Link: http://lkml.kernel.org/r/1455864533-7536-4-git-send-email-alfredoalvarezernandez@gmail.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
kernel/locking/lockdep.c | 59 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 51 insertions(+), 8 deletions(-)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 6f446eb..f894a2c 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1982,6 +1982,53 @@ struct lock_class *lock_chain_get_class(struct lock_chain *chain, int i)
}
/*
+ * Returns the index of the first held_lock of the current chain
+ */
+static inline int get_first_held_lock(struct task_struct *curr,
+ struct held_lock *hlock)
+{
+ int i;
+ struct held_lock *hlock_curr;
+
+ for (i = curr->lockdep_depth - 1; i >= 0; i--) {
+ hlock_curr = curr->held_locks + i;
+ if (hlock_curr->irq_context != hlock->irq_context)
+ break;
+
+ }
+
+ return ++i;
+}
+
+/*
+ * Checks whether the chain and the current held locks are consistent
+ * in depth and also in content. If they are not it most likely means
+ * that there was a collision during the calculation of the chain_key.
+ * Returns: 0 not passed, 1 passed
+ */
+static int check_no_collision(struct task_struct *curr,
+ struct held_lock *hlock,
+ struct lock_chain *chain)
+{
+#ifdef CONFIG_DEBUG_LOCKDEP
+ int i, j, id;
+
+ i = get_first_held_lock(curr, hlock);
+
+ if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1)))
+ return 0;
+
+ for (j = 0; j < chain->depth - 1; j++, i++) {
+ id = curr->held_locks[i].class_idx - 1;
+
+ if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id))
+ return 0;
+ }
+#endif
+ return 1;
+}
+
+/*
* Look up a dependency chain. If the key is not present yet then
* add it and return 1 - in this case the new dependency chain is
* validated. If the key is already hashed, return 0.
@@ -1994,7 +2041,6 @@ static inline int lookup_chain_cache(struct task_struct *curr,
struct lock_class *class = hlock_class(hlock);
struct hlist_head *hash_head = chainhashentry(chain_key);
struct lock_chain *chain;
- struct held_lock *hlock_curr;
int i, j;
/*
@@ -2012,6 +2058,9 @@ static inline int lookup_chain_cache(struct task_struct *curr,
if (chain->chain_key == chain_key) {
cache_hit:
debug_atomic_inc(chain_lookup_hits);
+ if (!check_no_collision(curr, hlock, chain))
+ return 0;
+
if (very_verbose(class))
printk("\nhash chain already cached, key: "
"%016Lx tail class: [%p] %s\n",
@@ -2049,13 +2098,7 @@ cache_hit:
chain = lock_chains + nr_lock_chains++;
chain->chain_key = chain_key;
chain->irq_context = hlock->irq_context;
- /* Find the first held_lock of current chain */
- for (i = curr->lockdep_depth - 1; i >= 0; i--) {
- hlock_curr = curr->held_locks + i;
- if (hlock_curr->irq_context != hlock->irq_context)
- break;
- }
- i++;
+ i = get_first_held_lock(curr, hlock);
chain->depth = curr->lockdep_depth + 1 - i;
if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) {
chain->base = nr_chain_hlocks;
next prev parent reply other threads:[~2016-02-29 11:25 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-10 23:33 [PATCH 0/3] lockdep: liblockdep: Prevent chain_key collisions Alfredo Alvarez Fernandez
2016-02-10 23:33 ` [PATCH 1/3] tools/liblockdep: add userspace version of READ_ONCE Alfredo Alvarez Fernandez
2016-02-11 15:16 ` Peter Zijlstra
2016-02-16 16:37 ` Sasha Levin
2016-02-10 23:33 ` [PATCH 2/3] tools/liblockdep: add tests Alfredo Alvarez Fernandez
2016-02-10 23:33 ` [PATCH 3/3] lockdep: prevent chain_key collisions Alfredo Alvarez Fernandez
2016-02-17 8:38 ` Ingo Molnar
2016-02-19 6:48 ` [PATCH v2 0/3] lockdep: liblockdep: Prevent " Alfredo Alvarez Fernandez
2016-02-19 6:48 ` [PATCH v2 1/3] tools/liblockdep: add userspace version of READ_ONCE Alfredo Alvarez Fernandez
2016-02-29 11:22 ` [tip:locking/core] tools/lib/lockdep: Add userspace version of READ_ONCE() tip-bot for Alfredo Alvarez Fernandez
2016-02-19 6:48 ` [PATCH v2 2/3] tools/liblockdep: add tests Alfredo Alvarez Fernandez
2016-02-29 11:23 ` [tip:locking/core] tools/lib/lockdep: Add tests for AA and ABBA locking tip-bot for Alfredo Alvarez Fernandez
2016-02-19 6:48 ` [PATCH v2 3/3] lockdep: prevent and detect chain_key collisions Alfredo Alvarez Fernandez
2016-02-29 11:24 ` tip-bot for Ingo Molnar [this message]
2016-02-29 11:24 ` [tip:locking/core] locking/lockdep: Prevent " tip-bot for Alfredo Alvarez Fernandez
2016-02-16 16:38 ` [PATCH 0/3] lockdep: liblockdep: " Sasha Levin
2016-02-16 17:22 ` Peter Zijlstra
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=tip-9e4e7554e755aaad8df0e26268787438735b4b76@git.kernel.org \
--to=tipbot@zytor.com \
--cc=alfredoalvarezernandez@gmail.com \
--cc=alfredoalvarezfernandez@gmail.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.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: link
Be 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).