All of 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 02/17] locking/lockdep: Add read-write type for dependency
Date: Mon, 13 May 2019 17:11:48 +0800	[thread overview]
Message-ID: <20190513091203.7299-3-duyuyang@gmail.com> (raw)
In-Reply-To: <20190513091203.7299-1-duyuyang@gmail.com>

Direct dependency needs to keep track of its locks' read-write types.  A
union field is added to lock_list struct so the type is stored there as
this:

	lock_type[1] (u16), lock_type[0] (u16)

			or:

	dep_type (int)

where value:

 0: exclusive / write
 1: read
 2: recursive read

Note that (int) dep_type value may vary with different architectural
endianness, so use helpers to operate on these types.

Signed-off-by: Yuyang Du <duyuyang@gmail.com>
---
 include/linux/lockdep.h            | 12 ++++++++++++
 kernel/locking/lockdep.c           | 34 +++++++++++++++++++++++++++++++---
 kernel/locking/lockdep_internals.h |  3 +++
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 441288c..6aa9af2 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -195,6 +195,18 @@ struct lock_list {
 	struct lock_class		*links_to;
 	struct lock_trace		trace;
 	int				distance;
+	/*
+	 * This field keeps track of the read-write type of this dependency.
+	 *
+	 * With L1 -> L2:
+	 *
+	 * lock_type[0] stores the type of L1, while lock_type[1] stores the
+	 * type of L2.
+	 */
+	union {
+		int	dep_type;
+		u16	lock_type[2];
+	};
 
 	/*
 	 * The parent field is used to implement breadth-first search, and the
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e9eafcf..4091002 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1225,7 +1225,7 @@ static struct lock_list *alloc_list_entry(void)
 static int add_lock_to_list(struct lock_class *this,
 			    struct lock_class *links_to, struct list_head *head,
 			    unsigned long ip, int distance,
-			    struct lock_trace *trace)
+			    struct lock_trace *trace, int dep_type)
 {
 	struct lock_list *entry;
 	/*
@@ -1240,6 +1240,8 @@ static int add_lock_to_list(struct lock_class *this,
 	entry->links_to = links_to;
 	entry->distance = distance;
 	entry->trace = *trace;
+	entry->dep_type = dep_type;
+
 	/*
 	 * Both allocation and removal are done under the graph lock; but
 	 * iteration is under RCU-sched; see look_up_lock_class() and
@@ -1677,6 +1679,30 @@ unsigned long lockdep_count_backward_deps(struct lock_class *class)
 	return ret;
 }
 
+static inline int get_dep_type(struct held_lock *lock1, struct held_lock *lock2)
+{
+	/*
+	 * With dependency lock1 -> lock2:
+	 *
+	 * lock_type[0] is lock1, while lock_type[1] is lock2.
+	 *
+	 * Avoid architectural endianness difference composing dep_type.
+	 */
+	u16 type[2] = { lock1->read, lock2->read };
+
+	return *(int *)type;
+}
+
+static inline int get_lock_type1(struct lock_list *lock)
+{
+	return lock->lock_type[0];
+}
+
+static inline int get_lock_type2(struct lock_list *lock)
+{
+	return lock->lock_type[1];
+}
+
 /*
  * Check that the dependency graph starting at <src> can lead to
  * <target> or not. Print an error and return 0 if it does.
@@ -2446,14 +2472,16 @@ static inline void inc_chains(void)
 	 */
 	ret = add_lock_to_list(hlock_class(next), hlock_class(prev),
 			       &hlock_class(prev)->locks_after,
-			       next->acquire_ip, distance, trace);
+			       next->acquire_ip, distance, trace,
+			       get_dep_type(prev, next));
 
 	if (!ret)
 		return 0;
 
 	ret = add_lock_to_list(hlock_class(prev), hlock_class(next),
 			       &hlock_class(next)->locks_before,
-			       next->acquire_ip, distance, trace);
+			       next->acquire_ip, distance, trace,
+			       get_dep_type(next, prev));
 	if (!ret)
 		return 0;
 
diff --git a/kernel/locking/lockdep_internals.h b/kernel/locking/lockdep_internals.h
index 150ec3f..c287bcb 100644
--- a/kernel/locking/lockdep_internals.h
+++ b/kernel/locking/lockdep_internals.h
@@ -26,6 +26,9 @@ enum lock_usage_bit {
 #define LOCK_USAGE_DIR_MASK  2
 #define LOCK_USAGE_STATE_MASK (~(LOCK_USAGE_READ_MASK | LOCK_USAGE_DIR_MASK))
 
+#define LOCK_TYPE_BITS	16
+#define LOCK_TYPE_MASK	0xFFFF
+
 /*
  * Usage-state bitmasks:
  */
-- 
1.8.3.1


  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 ` Yuyang Du [this message]
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 ` [PATCH 04/17] locking/lockdep: Update direct dependency's read-write type if it exists Yuyang Du
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-3-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 \
    /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 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.