LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Yuyang Du <duyuyang@gmail.com>
To: peterz@infradead.org, will.deacon@arm.com, mingo@kernel.org
Cc: bvanassche@acm.org, ming.lei@redhat.com, frederic@kernel.org,
tglx@linutronix.de, boqun.feng@gmail.com,
linux-kernel@vger.kernel.org, Yuyang Du <duyuyang@gmail.com>
Subject: [PATCH 04/17] locking/lockdep: Update direct dependency's read-write type if it exists
Date: Mon, 13 May 2019 17:11:50 +0800 [thread overview]
Message-ID: <20190513091203.7299-5-duyuyang@gmail.com> (raw)
In-Reply-To: <20190513091203.7299-1-duyuyang@gmail.com>
When adding a dependency, if the dependency exists - be it direct or
indirect - the dependency's read-write type may be updated.
We can keep all different-typed dependencies, but for simplicity we just
"upgrade" lock types if possible, making them more exlusive (in the order:
recursive read -> read -> write.
For indirect dependency, we do the redundancy check only when it has no
read locks (i.e., write-lock ended dependency); this makes the redundancy
check less complicated, which matters only when CONFIG_LOCKDEP_SMALL.
Signed-off-by: Yuyang Du <duyuyang@gmail.com>
---
kernel/locking/lockdep.c | 61 ++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 57 insertions(+), 4 deletions(-)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 0617375..27ca55f 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1734,6 +1734,16 @@ static inline int get_lock_type2(struct lock_list *lock)
return lock->lock_type[1];
}
+static inline void set_lock_type1(struct lock_list *lock, int read)
+{
+ lock->lock_type[0] = (u16)read;
+}
+
+static inline void set_lock_type2(struct lock_list *lock, int read)
+{
+ lock->lock_type[1] = (u16)read;
+}
+
/*
* Check that the dependency graph starting at <src> can lead to
* <target> or not. Print an error and return 0 if it does.
@@ -1814,6 +1824,32 @@ static inline int get_lock_type2(struct lock_list *lock)
ret = check_path(hlock_class(target), &src_entry, &target_entry);
if (!ret) {
+ struct lock_list *parent;
+
+ /*
+ * Do this indirect dependency has the same type as the
+ * direct dependency?
+ *
+ * Actually, we keep the more exclusive lock type
+ * between the indirect and direct dependencies by
+ * "upgrading" the indirect dependency's lock type if
+ * needed, and then consider this redundant.
+ */
+
+ /* Target end lock type: */
+ if (target->read < get_lock_type2(target_entry))
+ set_lock_type2(target_entry, target->read)
+
+ /* Source end lock type: */
+ parent = find_next_dep_in_path(&src_entry, target_entry);
+ if (!parent) {
+ DEBUG_LOCKS_WARN_ON(1);
+ return 0;
+ }
+
+ if (src->read < get_lock_type1(parent))
+ set_lock_type1(parent, src->read)
+
debug_atomic_inc(nr_redundant);
ret = 2;
} else if (ret < 0)
@@ -2479,6 +2515,17 @@ static inline void inc_chains(void)
*/
list_for_each_entry(entry, &hlock_class(prev)->locks_after, entry) {
if (entry->class == hlock_class(next)) {
+ /*
+ * For direct dependency, smaller type value
+ * generally means more exlusive; we keep the
+ * more exlusive ones, in other words, we
+ * "upgrade" the dependency if we can.
+ */
+ if (prev->read < get_lock_type1(entry))
+ set_lock_type1(entry, prev->read);
+ if (next->read < get_lock_type2(entry))
+ set_lock_type2(entry, next->read);
+
if (distance == 1)
entry->distance = 1;
return 1;
@@ -2487,11 +2534,17 @@ static inline void inc_chains(void)
#ifdef CONFIG_LOCKDEP_SMALL
/*
- * Is the <prev> -> <next> link redundant?
+ * Only when this dependency has no read lock/locks (i.e.,
+ * write-write dependency), we do redundancy check.
*/
- ret = check_redundant(prev, next);
- if (ret != 1)
- return ret;
+ if (!get_dep_type(prev, next)) {
+ /*
+ * Is the <prev> -> <next> link redundant?
+ */
+ ret = check_redundant(prev, next);
+ if (ret != 1)
+ return ret;
+ }
#endif
if (!trace->nr_entries && !save_trace(trace))
--
1.8.3.1
next prev parent reply other threads:[~2019-05-13 9:13 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-13 9:11 [PATCH 00/17] Support for read-write lock deadlock detection Yuyang Du
2019-05-13 9:11 ` [PATCH 01/17] locking/lockdep: Add lock type enum to explicitly specify read or write locks Yuyang Du
2019-05-13 11:45 ` Peter Zijlstra
2019-05-14 1:31 ` Yuyang Du
2019-05-14 12:04 ` Peter Zijlstra
2019-05-13 9:11 ` [PATCH 02/17] locking/lockdep: Add read-write type for dependency Yuyang Du
2019-05-13 9:11 ` [PATCH 03/17] locking/lockdep: Add helper functions to operate on the searched path Yuyang Du
2019-05-13 9:11 ` Yuyang Du [this message]
2019-05-13 9:11 ` [PATCH 05/17] locking/lockdep: Rename deadlock check functions Yuyang Du
2019-05-13 9:11 ` [PATCH 06/17] locking/lockdep: Adjust BFS algorithm to support multiple matches Yuyang Du
2019-05-13 9:11 ` [PATCH 07/17] locking/lockdep: Introduce mark_lock_unaccessed() Yuyang Du
2019-05-13 9:11 ` [PATCH 08/17] locking/lockdep: Introduce chain_hlocks_type for held lock's read-write type Yuyang Du
2019-05-13 9:11 ` [PATCH 09/17] locking/lockdep: Hash held lock's read-write type into chain key Yuyang Du
2019-05-13 9:11 ` [PATCH 10/17] locking/lockdep: Support read-write lock's deadlock detection Yuyang Du
2019-05-13 9:11 ` [PATCH 11/17] locking/lockdep: Adjust lockdep selftest cases Yuyang Du
2019-05-13 9:11 ` [PATCH 12/17] locking/lockdep: Remove useless lock type assignment Yuyang Du
2019-05-13 9:11 ` [PATCH 13/17] locking/lockdep: Add nest lock type Yuyang Du
2019-05-13 9:12 ` [PATCH 14/17] locking/lockdep: Support recursive read locks Yuyang Du
2019-05-13 9:12 ` [PATCH 15/17] locking/lockdep: Adjust selftest case for recursive read lock Yuyang Du
2019-05-13 9:12 ` [PATCH 16/17] locking/lockdep: Add more lockdep selftest cases Yuyang Du
2019-05-13 9:12 ` [PATCH 17/17] locking/lockdep: Remove irq-safe to irq-unsafe read check Yuyang Du
2019-05-13 9:17 ` [PATCH 00/17] Support for read-write lock deadlock detection Yuyang Du
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=20190513091203.7299-5-duyuyang@gmail.com \
--to=duyuyang@gmail.com \
--cc=boqun.feng@gmail.com \
--cc=bvanassche@acm.org \
--cc=frederic@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ming.lei@redhat.com \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=will.deacon@arm.com \
--subject='Re: [PATCH 04/17] locking/lockdep: Update direct dependency'\''s read-write type if it exists' \
/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
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).