From: Waiman Long <longman@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>, Will Deacon <will.deacon@arm.com>,
Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com,
linux-mm@kvack.org, Petr Mladek <pmladek@suse.com>,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
Andrey Ryabinin <aryabinin@virtuozzo.com>,
Tejun Heo <tj@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Waiman Long <longman@redhat.com>
Subject: [RFC PATCH 07/12] locking/lockdep: Add support for nested terminal locks
Date: Thu, 8 Nov 2018 15:34:23 -0500 [thread overview]
Message-ID: <1541709268-3766-8-git-send-email-longman@redhat.com> (raw)
In-Reply-To: <1541709268-3766-1-git-send-email-longman@redhat.com>
There are use cases where we want to allow 2-level nesting of one
terminal lock underneath another one. So the terminal lock type is now
extended to support a new nested terminal lock where it can allow the
acquisition of another regular terminal lock underneath it.
Signed-off-by: Waiman Long <longman@redhat.com>
---
include/linux/lockdep.h | 9 ++++++++-
kernel/locking/lockdep.c | 15 +++++++++++++--
kernel/locking/lockdep_internals.h | 2 +-
3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index c5ff8c5..ed4d177 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -147,12 +147,16 @@ struct lock_class_stats {
* 1) LOCKDEP_FLAG_NOVALIDATE: No full validation, just simple checks.
* 2) LOCKDEP_FLAG_TERMINAL: This is a terminal lock where lock/unlock on
* another lock within its critical section is not allowed.
+ * 3) LOCKDEP_FLAG_TERMINAL_NESTED: This is a terminal lock that allows
+ * one more regular terminal lock to be nested underneath it.
*/
#define LOCKDEP_FLAG_NOVALIDATE (1 << 0)
#define LOCKDEP_FLAG_TERMINAL (1 << 1)
+#define LOCKDEP_FLAG_TERMINAL_NESTED (1 << 2)
#define LOCKDEP_NOCHECK_FLAGS (LOCKDEP_FLAG_NOVALIDATE |\
- LOCKDEP_FLAG_TERMINAL)
+ LOCKDEP_FLAG_TERMINAL |\
+ LOCKDEP_FLAG_TERMINAL_NESTED)
/*
* Map the lock object (the lock instance) to the lock-class object.
@@ -314,6 +318,8 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
do { (lock)->dep_map.flags |= LOCKDEP_FLAG_NOVALIDATE; } while (0)
#define lockdep_set_terminal_class(lock) \
do { (lock)->dep_map.flags |= LOCKDEP_FLAG_TERMINAL; } while (0)
+#define lockdep_set_terminal_nested_class(lock) \
+ do { (lock)->dep_map.flags |= LOCKDEP_FLAG_TERMINAL_NESTED; } while (0)
/*
* Compare locking classes
@@ -431,6 +437,7 @@ static inline void lockdep_on(void)
#define lockdep_set_novalidate_class(lock) do { } while (0)
#define lockdep_set_terminal_class(lock) do { } while (0)
+#define lockdep_set_terminal_nested_class(lock) do { } while (0)
/*
* We don't define lockdep_match_class() and lockdep_match_key() for !LOCKDEP
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 02631a0..2b75613 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -3268,13 +3268,24 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
class_idx = class - lock_classes + 1;
if (depth) {
+ int prev_type;
+
hlock = curr->held_locks + depth - 1;
/*
- * Warn if the previous lock is a terminal lock.
+ * Warn if the previous lock is a terminal lock or the
+ * previous lock is a nested terminal lock and the current
+ * one isn't a regular terminal lock.
*/
- if (DEBUG_LOCKS_WARN_ON(hlock_is_terminal(hlock)))
+ prev_type = hlock_is_terminal(hlock);
+ if (DEBUG_LOCKS_WARN_ON((prev_type == LOCKDEP_FLAG_TERMINAL) ||
+ ((prev_type == LOCKDEP_FLAG_TERMINAL_NESTED) &&
+ (flags_is_terminal(class->flags) !=
+ LOCKDEP_FLAG_TERMINAL)))) {
+ pr_warn("Terminal lock error: prev lock = %s, curr lock = %s\n",
+ hlock->instance->name, class->name);
return 0;
+ }
if (hlock->class_idx == class_idx && nest_lock) {
if (hlock->references) {
diff --git a/kernel/locking/lockdep_internals.h b/kernel/locking/lockdep_internals.h
index 271fba8..abe646a 100644
--- a/kernel/locking/lockdep_internals.h
+++ b/kernel/locking/lockdep_internals.h
@@ -215,5 +215,5 @@ static inline unsigned long debug_class_ops_read(struct lock_class *class)
static inline unsigned int flags_is_terminal(unsigned int flags)
{
- return flags & LOCKDEP_FLAG_TERMINAL;
+ return flags & (LOCKDEP_FLAG_TERMINAL|LOCKDEP_FLAG_TERMINAL_NESTED);
}
--
1.8.3.1
next prev parent reply other threads:[~2018-11-08 20:35 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-08 20:34 [RFC PATCH 00/12] locking/lockdep: Add a new class of terminal locks Waiman Long
2018-11-08 20:34 ` [RFC PATCH 01/12] locking/lockdep: Rework lockdep_set_novalidate_class() Waiman Long
2018-11-10 14:14 ` Peter Zijlstra
2018-11-11 0:26 ` Waiman Long
2018-11-11 1:28 ` Peter Zijlstra
2018-11-11 1:28 ` Peter Zijlstra
2018-11-08 20:34 ` [RFC PATCH 02/12] locking/lockdep: Add a new terminal lock type Waiman Long
2018-11-10 14:17 ` Peter Zijlstra
2018-11-11 0:28 ` Waiman Long
2018-11-08 20:34 ` [RFC PATCH 03/12] locking/lockdep: Add DEFINE_TERMINAL_SPINLOCK() and related macros Waiman Long
2018-11-08 20:34 ` [RFC PATCH 04/12] printk: Make logbuf_lock a terminal lock Waiman Long
2018-11-08 20:34 ` [RFC PATCH 05/12] debugobjects: Mark pool_lock as " Waiman Long
2018-11-08 20:34 ` [RFC PATCH 06/12] debugobjects: Move printk out of db lock critical sections Waiman Long
2018-11-08 20:34 ` Waiman Long [this message]
2018-11-10 14:20 ` [RFC PATCH 07/12] locking/lockdep: Add support for nested terminal locks Peter Zijlstra
2018-11-11 0:30 ` Waiman Long
2018-11-11 1:30 ` Peter Zijlstra
2018-11-08 20:34 ` [RFC PATCH 08/12] debugobjects: Make object hash locks " Waiman Long
2018-11-08 20:34 ` [RFC PATCH 09/12] lib/stackdepot: Make depot_lock a terminal spinlock Waiman Long
2018-11-08 20:34 ` [RFC PATCH 10/12] locking/rwsem: Mark rwsem.wait_lock as a terminal lock Waiman Long
2018-11-08 20:34 ` [RFC PATCH 11/12] cgroup: Mark the rstat percpu lock as terminal Waiman Long
2018-11-08 20:34 ` [RFC PATCH 12/12] mm/kasan: Make quarantine_lock a terminal lock Waiman Long
2018-11-09 8:04 ` [RFC PATCH 00/12] locking/lockdep: Add a new class of terminal locks Ingo Molnar
2018-11-09 15:48 ` Waiman Long
2018-11-12 5:15 ` Ingo Molnar
2018-11-10 14:10 ` Peter Zijlstra
2018-11-10 23:35 ` Waiman Long
2018-11-12 5:10 ` Ingo Molnar
2018-11-12 5:53 ` Josh Poimboeuf
2018-11-12 6:30 ` Ingo Molnar
2018-11-12 22:22 ` Josh Poimboeuf
2018-11-12 22:56 ` Waiman Long
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=1541709268-3766-8-git-send-email-longman@redhat.com \
--to=longman@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=aryabinin@virtuozzo.com \
--cc=kasan-dev@googlegroups.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=sergey.senozhatsky@gmail.com \
--cc=tglx@linutronix.de \
--cc=tj@kernel.org \
--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.