* [PATCH 01/21] lockdep: annotate reclaim context (__GFP_NOFS)
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
@ 2009-01-28 13:53 ` Peter Zijlstra
[not found] ` <tip-bf722c9d324864b4256edaa330751b77f2a19861@git.kernel.org>
2009-01-28 13:53 ` [PATCH 02/21] lockdep: sanitize bit names Peter Zijlstra
` (20 subsequent siblings)
21 siblings, 1 reply; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:53 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: nick-lockdep-annotate_reclaim_context____GFP_NOFS.patch --]
[-- Type: text/plain, Size: 22290 bytes --]
From: Nick Piggin <npiggin@suse.de>
Here is another version, with the incremental patch rolled up, and
added reclaim context annotation to kswapd, and allocation tracing
to slab allocators (which may only ever reach the page allocator
in rare cases, so it is good to put annotations here too).
Haven't tested this version as such, but it should be getting closer
to merge worthy ;)
--
After noticing some code in mm/filemap.c accidentally perform a __GFP_FS
allocation when it should not have been, I thought it might be a good idea to
try to catch this kind of thing with lockdep.
I coded up a little idea that seems to work. Unfortunately the system has to
actually be in __GFP_FS page reclaim, then take the lock, before it will mark
it. But at least that might still be some orders of magnitude more common
(and more debuggable) than an actual deadlock condition, so we have some
improvement I hope (the concept is no less complete than discovery of a lock's
interrupt contexts).
I guess we could even do the same thing with __GFP_IO (normal reclaim), and
even GFP_NOIO locks too... but filesystems will have the most locks and fiddly
code paths, so let's start there and see how it goes.
It *seems* to work. I did a quick test.
=================================
[ INFO: inconsistent lock state ]
2.6.28-rc6-00007-ged31348-dirty #26
---------------------------------
inconsistent {in-reclaim-W} -> {ov-reclaim-W} usage.
modprobe/8526 [HC0[0]:SC0[0]:HE1:SE1] takes:
(testlock){--..}, at: [<ffffffffa0020055>] brd_init+0x55/0x216 [brd]
{in-reclaim-W} state was registered at:
[<ffffffff80267bdb>] __lock_acquire+0x75b/0x1a60
[<ffffffff80268f71>] lock_acquire+0x91/0xc0
[<ffffffff8070f0e1>] mutex_lock_nested+0xb1/0x310
[<ffffffffa002002b>] brd_init+0x2b/0x216 [brd]
[<ffffffff8020903b>] _stext+0x3b/0x170
[<ffffffff80272ebf>] sys_init_module+0xaf/0x1e0
[<ffffffff8020c3fb>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
irq event stamp: 3929
hardirqs last enabled at (3929): [<ffffffff8070f2b5>] mutex_lock_nested+0x285/0x310
hardirqs last disabled at (3928): [<ffffffff8070f089>] mutex_lock_nested+0x59/0x310
softirqs last enabled at (3732): [<ffffffff8061f623>] sk_filter+0x83/0xe0
softirqs last disabled at (3730): [<ffffffff8061f5b6>] sk_filter+0x16/0xe0
other info that might help us debug this:
1 lock held by modprobe/8526:
#0: (testlock){--..}, at: [<ffffffffa0020055>] brd_init+0x55/0x216 [brd]
stack backtrace:
Pid: 8526, comm: modprobe Not tainted 2.6.28-rc6-00007-ged31348-dirty #26
Call Trace:
[<ffffffff80265483>] print_usage_bug+0x193/0x1d0
[<ffffffff80266530>] mark_lock+0xaf0/0xca0
[<ffffffff80266735>] mark_held_locks+0x55/0xc0
[<ffffffffa0020000>] ? brd_init+0x0/0x216 [brd]
[<ffffffff802667ca>] trace_reclaim_fs+0x2a/0x60
[<ffffffff80285005>] __alloc_pages_internal+0x475/0x580
[<ffffffff8070f29e>] ? mutex_lock_nested+0x26e/0x310
[<ffffffffa0020000>] ? brd_init+0x0/0x216 [brd]
[<ffffffffa002006a>] brd_init+0x6a/0x216 [brd]
[<ffffffffa0020000>] ? brd_init+0x0/0x216 [brd]
[<ffffffff8020903b>] _stext+0x3b/0x170
[<ffffffff8070f8b9>] ? mutex_unlock+0x9/0x10
[<ffffffff8070f83d>] ? __mutex_unlock_slowpath+0x10d/0x180
[<ffffffff802669ec>] ? trace_hardirqs_on_caller+0x12c/0x190
[<ffffffff80272ebf>] sys_init_module+0xaf/0x1e0
[<ffffffff8020c3fb>] system_call_fastpath+0x16/0x1b
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/lockdep.h | 17 +++
include/linux/sched.h | 1
kernel/lockdep.c | 229 ++++++++++++++++++++++++++++++++++++++++++---
kernel/lockdep_internals.h | 3
kernel/lockdep_proc.c | 6 -
mm/page_alloc.c | 5
mm/slab.c | 4
mm/slob.c | 2
mm/slub.c | 1
mm/vmscan.c | 3
10 files changed, 254 insertions(+), 17 deletions(-)
Index: linux-2.6/include/linux/lockdep.h
===================================================================
--- linux-2.6.orig/include/linux/lockdep.h
+++ linux-2.6/include/linux/lockdep.h
@@ -27,12 +27,16 @@ enum lock_usage_bit
LOCK_USED = 0,
LOCK_USED_IN_HARDIRQ,
LOCK_USED_IN_SOFTIRQ,
+ LOCK_USED_IN_RECLAIM_FS,
LOCK_ENABLED_SOFTIRQS,
LOCK_ENABLED_HARDIRQS,
+ LOCK_HELD_OVER_RECLAIM_FS,
LOCK_USED_IN_HARDIRQ_READ,
LOCK_USED_IN_SOFTIRQ_READ,
+ LOCK_USED_IN_RECLAIM_FS_READ,
LOCK_ENABLED_SOFTIRQS_READ,
LOCK_ENABLED_HARDIRQS_READ,
+ LOCK_HELD_OVER_RECLAIM_FS_READ,
LOCK_USAGE_STATES
};
@@ -42,16 +46,20 @@ enum lock_usage_bit
#define LOCKF_USED (1 << LOCK_USED)
#define LOCKF_USED_IN_HARDIRQ (1 << LOCK_USED_IN_HARDIRQ)
#define LOCKF_USED_IN_SOFTIRQ (1 << LOCK_USED_IN_SOFTIRQ)
+#define LOCKF_USED_IN_RECLAIM_FS (1 << LOCK_USED_IN_RECLAIM_FS)
#define LOCKF_ENABLED_HARDIRQS (1 << LOCK_ENABLED_HARDIRQS)
#define LOCKF_ENABLED_SOFTIRQS (1 << LOCK_ENABLED_SOFTIRQS)
+#define LOCKF_HELD_OVER_RECLAIM_FS (1 << LOCK_HELD_OVER_RECLAIM_FS)
#define LOCKF_ENABLED_IRQS (LOCKF_ENABLED_HARDIRQS | LOCKF_ENABLED_SOFTIRQS)
#define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ)
#define LOCKF_USED_IN_HARDIRQ_READ (1 << LOCK_USED_IN_HARDIRQ_READ)
#define LOCKF_USED_IN_SOFTIRQ_READ (1 << LOCK_USED_IN_SOFTIRQ_READ)
+#define LOCKF_USED_IN_RECLAIM_FS_READ (1 << LOCK_USED_IN_RECLAIM_FS_READ)
#define LOCKF_ENABLED_HARDIRQS_READ (1 << LOCK_ENABLED_HARDIRQS_READ)
#define LOCKF_ENABLED_SOFTIRQS_READ (1 << LOCK_ENABLED_SOFTIRQS_READ)
+#define LOCKF_HELD_OVER_RECLAIM_FS_READ (1 << LOCK_HELD_OVER_RECLAIM_FS_READ)
#define LOCKF_ENABLED_IRQS_READ \
(LOCKF_ENABLED_HARDIRQS_READ | LOCKF_ENABLED_SOFTIRQS_READ)
@@ -324,7 +332,11 @@ static inline void lock_set_subclass(str
lock_set_class(lock, lock->name, lock->key, subclass, ip);
}
-# define INIT_LOCKDEP .lockdep_recursion = 0,
+extern void lockdep_set_current_reclaim_state(gfp_t gfp_mask);
+extern void lockdep_clear_current_reclaim_state(void);
+extern void lockdep_trace_alloc(gfp_t mask);
+
+# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0,
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
@@ -342,6 +354,9 @@ static inline void lockdep_on(void)
# define lock_release(l, n, i) do { } while (0)
# define lock_set_class(l, n, k, s, i) do { } while (0)
# define lock_set_subclass(l, s, i) do { } while (0)
+# define lockdep_set_current_reclaim_state(g) do { } while (0)
+# define lockdep_clear_current_reclaim_state() do { } while (0)
+# define lockdep_trace_alloc(g) do { } while (0)
# define lockdep_init() do { } while (0)
# define lockdep_info() do { } while (0)
# define lockdep_init_map(lock, name, key, sub) \
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -310,12 +310,14 @@ EXPORT_SYMBOL(lockdep_on);
#if VERBOSE
# define HARDIRQ_VERBOSE 1
# define SOFTIRQ_VERBOSE 1
+# define RECLAIM_VERBOSE 1
#else
# define HARDIRQ_VERBOSE 0
# define SOFTIRQ_VERBOSE 0
+# define RECLAIM_VERBOSE 0
#endif
-#if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE
+#if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE || RECLAIM_VERBOSE
/*
* Quick filtering for interesting events:
*/
@@ -454,6 +456,10 @@ static const char *usage_str[] =
[LOCK_USED_IN_SOFTIRQ_READ] = "in-softirq-R",
[LOCK_ENABLED_SOFTIRQS_READ] = "softirq-on-R",
[LOCK_ENABLED_HARDIRQS_READ] = "hardirq-on-R",
+ [LOCK_USED_IN_RECLAIM_FS] = "in-reclaim-W",
+ [LOCK_USED_IN_RECLAIM_FS_READ] = "in-reclaim-R",
+ [LOCK_HELD_OVER_RECLAIM_FS] = "ov-reclaim-W",
+ [LOCK_HELD_OVER_RECLAIM_FS_READ] = "ov-reclaim-R",
};
const char * __get_key_name(struct lockdep_subclass_key *key, char *str)
@@ -462,9 +468,10 @@ const char * __get_key_name(struct lockd
}
void
-get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4)
+get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
+ char *c4, char *c5, char *c6)
{
- *c1 = '.', *c2 = '.', *c3 = '.', *c4 = '.';
+ *c1 = '.', *c2 = '.', *c3 = '.', *c4 = '.', *c5 = '.', *c6 = '.';
if (class->usage_mask & LOCKF_USED_IN_HARDIRQ)
*c1 = '+';
@@ -493,14 +500,29 @@ get_usage_chars(struct lock_class *class
if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ)
*c4 = '?';
}
+
+ if (class->usage_mask & LOCKF_USED_IN_RECLAIM_FS)
+ *c5 = '+';
+ else
+ if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS)
+ *c5 = '-';
+
+ if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS_READ)
+ *c6 = '-';
+ if (class->usage_mask & LOCKF_USED_IN_RECLAIM_FS_READ) {
+ *c6 = '+';
+ if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS_READ)
+ *c6 = '?';
+ }
+
}
static void print_lock_name(struct lock_class *class)
{
- char str[KSYM_NAME_LEN], c1, c2, c3, c4;
+ char str[KSYM_NAME_LEN], c1, c2, c3, c4, c5, c6;
const char *name;
- get_usage_chars(class, &c1, &c2, &c3, &c4);
+ get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6);
name = class->name;
if (!name) {
@@ -513,7 +535,7 @@ static void print_lock_name(struct lock_
if (class->subclass)
printk("/%d", class->subclass);
}
- printk("){%c%c%c%c}", c1, c2, c3, c4);
+ printk("){%c%c%c%c%c%c}", c1, c2, c3, c4, c5, c6);
}
static void print_lockdep_cache(struct lockdep_map *lock)
@@ -1306,6 +1328,26 @@ check_prev_add_irq(struct task_struct *c
LOCK_ENABLED_SOFTIRQS, "soft"))
return 0;
+ /*
+ * Prove that the new dependency does not connect a reclaim-fs-safe
+ * lock with a reclaim-fs-unsafe lock - to achieve this we search
+ * the backwards-subgraph starting at <prev>, and the
+ * forwards-subgraph starting at <next>:
+ */
+ if (!check_usage(curr, prev, next, LOCK_USED_IN_RECLAIM_FS,
+ LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs"))
+ return 0;
+
+ /*
+ * Prove that the new dependency does not connect a reclaim-fs-safe-read
+ * lock with a reclaim-fs-unsafe lock - to achieve this we search
+ * the backwards-subgraph starting at <prev>, and the
+ * forwards-subgraph starting at <next>:
+ */
+ if (!check_usage(curr, prev, next, LOCK_USED_IN_RECLAIM_FS_READ,
+ LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs-read"))
+ return 0;
+
return 1;
}
@@ -1949,6 +1991,14 @@ static int softirq_verbose(struct lock_c
return 0;
}
+static int reclaim_verbose(struct lock_class *class)
+{
+#if RECLAIM_VERBOSE
+ return class_filter(class);
+#endif
+ return 0;
+}
+
#define STRICT_READ_CHECKS 1
static int mark_lock_irq(struct task_struct *curr, struct held_lock *this,
@@ -2007,6 +2057,31 @@ static int mark_lock_irq(struct task_str
if (softirq_verbose(hlock_class(this)))
ret = 2;
break;
+ case LOCK_USED_IN_RECLAIM_FS:
+ if (!valid_state(curr, this, new_bit, LOCK_HELD_OVER_RECLAIM_FS))
+ return 0;
+ if (!valid_state(curr, this, new_bit,
+ LOCK_HELD_OVER_RECLAIM_FS_READ))
+ return 0;
+ /*
+ * just marked it reclaim-fs-safe, check that this lock
+ * took no reclaim-fs-unsafe lock in the past:
+ */
+ if (!check_usage_forwards(curr, this,
+ LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs"))
+ return 0;
+#if STRICT_READ_CHECKS
+ /*
+ * just marked it reclaim-fs-safe, check that this lock
+ * took no reclaim-fs-unsafe-read lock in the past:
+ */
+ if (!check_usage_forwards(curr, this,
+ LOCK_HELD_OVER_RECLAIM_FS_READ, "reclaim-fs-read"))
+ return 0;
+#endif
+ if (reclaim_verbose(hlock_class(this)))
+ ret = 2;
+ break;
case LOCK_USED_IN_HARDIRQ_READ:
if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS))
return 0;
@@ -2033,6 +2108,19 @@ static int mark_lock_irq(struct task_str
if (softirq_verbose(hlock_class(this)))
ret = 2;
break;
+ case LOCK_USED_IN_RECLAIM_FS_READ:
+ if (!valid_state(curr, this, new_bit, LOCK_HELD_OVER_RECLAIM_FS))
+ return 0;
+ /*
+ * just marked it reclaim-fs-read-safe, check that this lock
+ * took no reclaim-fs-unsafe lock in the past:
+ */
+ if (!check_usage_forwards(curr, this,
+ LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs"))
+ return 0;
+ if (reclaim_verbose(hlock_class(this)))
+ ret = 2;
+ break;
case LOCK_ENABLED_HARDIRQS:
if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ))
return 0;
@@ -2085,6 +2173,32 @@ static int mark_lock_irq(struct task_str
if (softirq_verbose(hlock_class(this)))
ret = 2;
break;
+ case LOCK_HELD_OVER_RECLAIM_FS:
+ if (!valid_state(curr, this, new_bit, LOCK_USED_IN_RECLAIM_FS))
+ return 0;
+ if (!valid_state(curr, this, new_bit,
+ LOCK_USED_IN_RECLAIM_FS_READ))
+ return 0;
+ /*
+ * just marked it reclaim-fs-unsafe, check that no reclaim-fs-safe
+ * lock in the system ever took it in the past:
+ */
+ if (!check_usage_backwards(curr, this,
+ LOCK_USED_IN_RECLAIM_FS, "reclaim-fs"))
+ return 0;
+#if STRICT_READ_CHECKS
+ /*
+ * just marked it softirq-unsafe, check that no
+ * softirq-safe-read lock in the system ever took
+ * it in the past:
+ */
+ if (!check_usage_backwards(curr, this,
+ LOCK_USED_IN_RECLAIM_FS_READ, "reclaim-fs-read"))
+ return 0;
+#endif
+ if (reclaim_verbose(hlock_class(this)))
+ ret = 2;
+ break;
case LOCK_ENABLED_HARDIRQS_READ:
if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ))
return 0;
@@ -2115,6 +2229,21 @@ static int mark_lock_irq(struct task_str
if (softirq_verbose(hlock_class(this)))
ret = 2;
break;
+ case LOCK_HELD_OVER_RECLAIM_FS_READ:
+ if (!valid_state(curr, this, new_bit, LOCK_USED_IN_RECLAIM_FS))
+ return 0;
+#if STRICT_READ_CHECKS
+ /*
+ * just marked it reclaim-fs-read-unsafe, check that no
+ * reclaim-fs-safe lock in the system ever took it in the past:
+ */
+ if (!check_usage_backwards(curr, this,
+ LOCK_USED_IN_RECLAIM_FS, "reclaim-fs"))
+ return 0;
+#endif
+ if (reclaim_verbose(hlock_class(this)))
+ ret = 2;
+ break;
default:
WARN_ON(1);
break;
@@ -2123,11 +2252,17 @@ static int mark_lock_irq(struct task_str
return ret;
}
+enum mark_type {
+ HARDIRQ,
+ SOFTIRQ,
+ RECLAIM_FS,
+};
+
/*
* Mark all held locks with a usage bit:
*/
static int
-mark_held_locks(struct task_struct *curr, int hardirq)
+mark_held_locks(struct task_struct *curr, enum mark_type mark)
{
enum lock_usage_bit usage_bit;
struct held_lock *hlock;
@@ -2136,17 +2271,32 @@ mark_held_locks(struct task_struct *curr
for (i = 0; i < curr->lockdep_depth; i++) {
hlock = curr->held_locks + i;
- if (hardirq) {
+ switch (mark) {
+ case HARDIRQ:
if (hlock->read)
usage_bit = LOCK_ENABLED_HARDIRQS_READ;
else
usage_bit = LOCK_ENABLED_HARDIRQS;
- } else {
+ break;
+
+ case SOFTIRQ:
if (hlock->read)
usage_bit = LOCK_ENABLED_SOFTIRQS_READ;
else
usage_bit = LOCK_ENABLED_SOFTIRQS;
+ break;
+
+ case RECLAIM_FS:
+ if (hlock->read)
+ usage_bit = LOCK_HELD_OVER_RECLAIM_FS_READ;
+ else
+ usage_bit = LOCK_HELD_OVER_RECLAIM_FS;
+ break;
+
+ default:
+ BUG();
}
+
if (!mark_lock(curr, hlock, usage_bit))
return 0;
}
@@ -2200,7 +2350,7 @@ void trace_hardirqs_on_caller(unsigned l
* We are going to turn hardirqs on, so set the
* usage bit for all held locks:
*/
- if (!mark_held_locks(curr, 1))
+ if (!mark_held_locks(curr, HARDIRQ))
return;
/*
* If we have softirqs enabled, then set the usage
@@ -2208,7 +2358,7 @@ void trace_hardirqs_on_caller(unsigned l
* this bit from being set before)
*/
if (curr->softirqs_enabled)
- if (!mark_held_locks(curr, 0))
+ if (!mark_held_locks(curr, SOFTIRQ))
return;
curr->hardirq_enable_ip = ip;
@@ -2288,7 +2438,7 @@ void trace_softirqs_on(unsigned long ip)
* enabled too:
*/
if (curr->hardirqs_enabled)
- mark_held_locks(curr, 0);
+ mark_held_locks(curr, SOFTIRQ);
}
/*
@@ -2317,6 +2467,31 @@ void trace_softirqs_off(unsigned long ip
debug_atomic_inc(&redundant_softirqs_off);
}
+void lockdep_trace_alloc(gfp_t gfp_mask)
+{
+ struct task_struct *curr = current;
+
+ if (unlikely(!debug_locks))
+ return;
+
+ /* no reclaim without waiting on it */
+ if (!(gfp_mask & __GFP_WAIT))
+ return;
+
+ /* this guy won't enter reclaim */
+ if ((curr->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC))
+ return;
+
+ /* We're only interested __GFP_FS allocations for now */
+ if (!(gfp_mask & __GFP_FS))
+ return;
+
+ if (DEBUG_LOCKS_WARN_ON(irqs_disabled()))
+ return;
+
+ mark_held_locks(curr, RECLAIM_FS);
+}
+
static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock)
{
/*
@@ -2362,6 +2537,22 @@ static int mark_irqflags(struct task_str
}
}
+ /*
+ * We reuse the irq context infrastructure more broadly as a general
+ * context checking code. This tests GFP_FS recursion (a lock taken
+ * during reclaim for a GFP_FS allocation is held over a GFP_FS
+ * allocation).
+ */
+ if (!hlock->trylock && (curr->lockdep_reclaim_gfp & __GFP_FS)) {
+ if (hlock->read) {
+ if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS_READ))
+ return 0;
+ } else {
+ if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS))
+ return 0;
+ }
+ }
+
return 1;
}
@@ -2453,6 +2644,10 @@ static int mark_lock(struct task_struct
case LOCK_ENABLED_SOFTIRQS:
case LOCK_ENABLED_HARDIRQS_READ:
case LOCK_ENABLED_SOFTIRQS_READ:
+ case LOCK_USED_IN_RECLAIM_FS:
+ case LOCK_USED_IN_RECLAIM_FS_READ:
+ case LOCK_HELD_OVER_RECLAIM_FS:
+ case LOCK_HELD_OVER_RECLAIM_FS_READ:
ret = mark_lock_irq(curr, this, new_bit);
if (!ret)
return 0;
@@ -2966,6 +3161,16 @@ void lock_release(struct lockdep_map *lo
}
EXPORT_SYMBOL_GPL(lock_release);
+void lockdep_set_current_reclaim_state(gfp_t gfp_mask)
+{
+ current->lockdep_reclaim_gfp = gfp_mask;
+}
+
+void lockdep_clear_current_reclaim_state(void)
+{
+ current->lockdep_reclaim_gfp = 0;
+}
+
#ifdef CONFIG_LOCK_STAT
static int
print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock,
Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c
+++ linux-2.6/mm/page_alloc.c
@@ -1479,6 +1479,8 @@ __alloc_pages_internal(gfp_t gfp_mask, u
unsigned long did_some_progress;
unsigned long pages_reclaimed = 0;
+ lockdep_trace_alloc(gfp_mask);
+
might_sleep_if(wait);
if (should_fail_alloc_page(gfp_mask, order))
@@ -1578,12 +1580,15 @@ nofail_alloc:
*/
cpuset_update_task_memory_state();
p->flags |= PF_MEMALLOC;
+
+ lockdep_set_current_reclaim_state(gfp_mask);
reclaim_state.reclaimed_slab = 0;
p->reclaim_state = &reclaim_state;
did_some_progress = try_to_free_pages(zonelist, order, gfp_mask);
p->reclaim_state = NULL;
+ lockdep_clear_current_reclaim_state();
p->flags &= ~PF_MEMALLOC;
cond_resched();
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h
+++ linux-2.6/include/linux/sched.h
@@ -1327,6 +1327,7 @@ struct task_struct {
int lockdep_depth;
unsigned int lockdep_recursion;
struct held_lock held_locks[MAX_LOCK_DEPTH];
+ gfp_t lockdep_reclaim_gfp;
#endif
/* journalling filesystem info */
Index: linux-2.6/kernel/lockdep_internals.h
===================================================================
--- linux-2.6.orig/kernel/lockdep_internals.h
+++ linux-2.6/kernel/lockdep_internals.h
@@ -32,7 +32,8 @@ extern struct list_head all_lock_classes
extern struct lock_chain lock_chains[];
extern void
-get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4);
+get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
+ char *c4, char *c5, char *c6);
extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str);
Index: linux-2.6/kernel/lockdep_proc.c
===================================================================
--- linux-2.6.orig/kernel/lockdep_proc.c
+++ linux-2.6/kernel/lockdep_proc.c
@@ -84,7 +84,7 @@ static int l_show(struct seq_file *m, vo
{
struct lock_class *class = v;
struct lock_list *entry;
- char c1, c2, c3, c4;
+ char c1, c2, c3, c4, c5, c6;
if (v == SEQ_START_TOKEN) {
seq_printf(m, "all lock classes:\n");
@@ -100,8 +100,8 @@ static int l_show(struct seq_file *m, vo
seq_printf(m, " BD:%5ld", lockdep_count_backward_deps(class));
#endif
- get_usage_chars(class, &c1, &c2, &c3, &c4);
- seq_printf(m, " %c%c%c%c", c1, c2, c3, c4);
+ get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6);
+ seq_printf(m, " %c%c%c%c%c%c", c1, c2, c3, c4, c5, c6);
seq_printf(m, ": ");
print_name(m, class);
Index: linux-2.6/mm/slab.c
===================================================================
--- linux-2.6.orig/mm/slab.c
+++ linux-2.6/mm/slab.c
@@ -3254,6 +3254,8 @@ __cache_alloc_node(struct kmem_cache *ca
unsigned long save_flags;
void *ptr;
+ lockdep_trace_alloc(flags);
+
if (slab_should_failslab(cachep, flags))
return NULL;
@@ -3333,6 +3335,8 @@ __cache_alloc(struct kmem_cache *cachep,
unsigned long save_flags;
void *objp;
+ lockdep_trace_alloc(flags);
+
if (slab_should_failslab(cachep, flags))
return NULL;
Index: linux-2.6/mm/vmscan.c
===================================================================
--- linux-2.6.orig/mm/vmscan.c
+++ linux-2.6/mm/vmscan.c
@@ -1963,6 +1963,9 @@ static int kswapd(void *p)
struct reclaim_state reclaim_state = {
.reclaimed_slab = 0,
};
+
+ lockdep_set_current_reclaim_state(GFP_KERNEL);
+
node_to_cpumask_ptr(cpumask, pgdat->node_id);
if (!cpumask_empty(cpumask))
Index: linux-2.6/mm/slob.c
===================================================================
--- linux-2.6.orig/mm/slob.c
+++ linux-2.6/mm/slob.c
@@ -466,6 +466,8 @@ void *__kmalloc_node(size_t size, gfp_t
int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
void *ret;
+ lockdep_trace_alloc(flags);
+
if (size < PAGE_SIZE - align) {
if (!size)
return ZERO_SIZE_PTR;
Index: linux-2.6/mm/slub.c
===================================================================
--- linux-2.6.orig/mm/slub.c
+++ linux-2.6/mm/slub.c
@@ -1608,6 +1608,7 @@ static __always_inline void *slab_alloc(
unsigned long flags;
unsigned int objsize;
+ lockdep_trace_alloc(gfpflags);
might_sleep_if(gfpflags & __GFP_WAIT);
if (should_failslab(s->objsize, gfpflags))
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 02/21] lockdep: sanitize bit names
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
2009-01-28 13:53 ` [PATCH 01/21] lockdep: annotate reclaim context (__GFP_NOFS) Peter Zijlstra
@ 2009-01-28 13:53 ` Peter Zijlstra
2009-01-28 13:53 ` [PATCH 03/21] lockdep: sanitize reclaim " Peter Zijlstra
` (19 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:53 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-generate.patch --]
[-- Type: text/plain, Size: 13375 bytes --]
s/\(LOCKF\?_ENABLED_[^ ]*\)S\(_READ\)\?\>/\1\2/g
So that the USED_IN and ENABLED have the same names.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/lockdep.h | 22 ++++++------
kernel/lockdep.c | 84 ++++++++++++++++++++++++------------------------
kernel/lockdep_proc.c | 12 +++---
3 files changed, 59 insertions(+), 59 deletions(-)
Index: linux-2.6/include/linux/lockdep.h
===================================================================
--- linux-2.6.orig/include/linux/lockdep.h
+++ linux-2.6/include/linux/lockdep.h
@@ -28,14 +28,14 @@ enum lock_usage_bit
LOCK_USED_IN_HARDIRQ,
LOCK_USED_IN_SOFTIRQ,
LOCK_USED_IN_RECLAIM_FS,
- LOCK_ENABLED_SOFTIRQS,
- LOCK_ENABLED_HARDIRQS,
+ LOCK_ENABLED_SOFTIRQ,
+ LOCK_ENABLED_HARDIRQ,
LOCK_HELD_OVER_RECLAIM_FS,
LOCK_USED_IN_HARDIRQ_READ,
LOCK_USED_IN_SOFTIRQ_READ,
LOCK_USED_IN_RECLAIM_FS_READ,
- LOCK_ENABLED_SOFTIRQS_READ,
- LOCK_ENABLED_HARDIRQS_READ,
+ LOCK_ENABLED_SOFTIRQ_READ,
+ LOCK_ENABLED_HARDIRQ_READ,
LOCK_HELD_OVER_RECLAIM_FS_READ,
LOCK_USAGE_STATES
};
@@ -47,22 +47,22 @@ enum lock_usage_bit
#define LOCKF_USED_IN_HARDIRQ (1 << LOCK_USED_IN_HARDIRQ)
#define LOCKF_USED_IN_SOFTIRQ (1 << LOCK_USED_IN_SOFTIRQ)
#define LOCKF_USED_IN_RECLAIM_FS (1 << LOCK_USED_IN_RECLAIM_FS)
-#define LOCKF_ENABLED_HARDIRQS (1 << LOCK_ENABLED_HARDIRQS)
-#define LOCKF_ENABLED_SOFTIRQS (1 << LOCK_ENABLED_SOFTIRQS)
+#define LOCKF_ENABLED_HARDIRQ (1 << LOCK_ENABLED_HARDIRQ)
+#define LOCKF_ENABLED_SOFTIRQ (1 << LOCK_ENABLED_SOFTIRQ)
#define LOCKF_HELD_OVER_RECLAIM_FS (1 << LOCK_HELD_OVER_RECLAIM_FS)
-#define LOCKF_ENABLED_IRQS (LOCKF_ENABLED_HARDIRQS | LOCKF_ENABLED_SOFTIRQS)
+#define LOCKF_ENABLED_IRQ (LOCKF_ENABLED_HARDIRQ | LOCKF_ENABLED_SOFTIRQ)
#define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ)
#define LOCKF_USED_IN_HARDIRQ_READ (1 << LOCK_USED_IN_HARDIRQ_READ)
#define LOCKF_USED_IN_SOFTIRQ_READ (1 << LOCK_USED_IN_SOFTIRQ_READ)
#define LOCKF_USED_IN_RECLAIM_FS_READ (1 << LOCK_USED_IN_RECLAIM_FS_READ)
-#define LOCKF_ENABLED_HARDIRQS_READ (1 << LOCK_ENABLED_HARDIRQS_READ)
-#define LOCKF_ENABLED_SOFTIRQS_READ (1 << LOCK_ENABLED_SOFTIRQS_READ)
+#define LOCKF_ENABLED_HARDIRQ_READ (1 << LOCK_ENABLED_HARDIRQ_READ)
+#define LOCKF_ENABLED_SOFTIRQ_READ (1 << LOCK_ENABLED_SOFTIRQ_READ)
#define LOCKF_HELD_OVER_RECLAIM_FS_READ (1 << LOCK_HELD_OVER_RECLAIM_FS_READ)
-#define LOCKF_ENABLED_IRQS_READ \
- (LOCKF_ENABLED_HARDIRQS_READ | LOCKF_ENABLED_SOFTIRQS_READ)
+#define LOCKF_ENABLED_IRQ_READ \
+ (LOCKF_ENABLED_HARDIRQ_READ | LOCKF_ENABLED_SOFTIRQ_READ)
#define LOCKF_USED_IN_IRQ_READ \
(LOCKF_USED_IN_HARDIRQ_READ | LOCKF_USED_IN_SOFTIRQ_READ)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -450,12 +450,12 @@ static const char *usage_str[] =
[LOCK_USED] = "initial-use ",
[LOCK_USED_IN_HARDIRQ] = "in-hardirq-W",
[LOCK_USED_IN_SOFTIRQ] = "in-softirq-W",
- [LOCK_ENABLED_SOFTIRQS] = "softirq-on-W",
- [LOCK_ENABLED_HARDIRQS] = "hardirq-on-W",
+ [LOCK_ENABLED_SOFTIRQ] = "softirq-on-W",
+ [LOCK_ENABLED_HARDIRQ] = "hardirq-on-W",
[LOCK_USED_IN_HARDIRQ_READ] = "in-hardirq-R",
[LOCK_USED_IN_SOFTIRQ_READ] = "in-softirq-R",
- [LOCK_ENABLED_SOFTIRQS_READ] = "softirq-on-R",
- [LOCK_ENABLED_HARDIRQS_READ] = "hardirq-on-R",
+ [LOCK_ENABLED_SOFTIRQ_READ] = "softirq-on-R",
+ [LOCK_ENABLED_HARDIRQ_READ] = "hardirq-on-R",
[LOCK_USED_IN_RECLAIM_FS] = "in-reclaim-W",
[LOCK_USED_IN_RECLAIM_FS_READ] = "in-reclaim-R",
[LOCK_HELD_OVER_RECLAIM_FS] = "ov-reclaim-W",
@@ -476,28 +476,28 @@ get_usage_chars(struct lock_class *class
if (class->usage_mask & LOCKF_USED_IN_HARDIRQ)
*c1 = '+';
else
- if (class->usage_mask & LOCKF_ENABLED_HARDIRQS)
+ if (class->usage_mask & LOCKF_ENABLED_HARDIRQ)
*c1 = '-';
if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ)
*c2 = '+';
else
- if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS)
+ if (class->usage_mask & LOCKF_ENABLED_SOFTIRQ)
*c2 = '-';
- if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_HARDIRQ_READ)
*c3 = '-';
if (class->usage_mask & LOCKF_USED_IN_HARDIRQ_READ) {
*c3 = '+';
- if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_HARDIRQ_READ)
*c3 = '?';
}
- if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_SOFTIRQ_READ)
*c4 = '-';
if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ_READ) {
*c4 = '+';
- if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_SOFTIRQ_READ)
*c4 = '?';
}
@@ -1296,7 +1296,7 @@ check_prev_add_irq(struct task_struct *c
* forwards-subgraph starting at <next>:
*/
if (!check_usage(curr, prev, next, LOCK_USED_IN_HARDIRQ,
- LOCK_ENABLED_HARDIRQS, "hard"))
+ LOCK_ENABLED_HARDIRQ, "hard"))
return 0;
/*
@@ -1306,7 +1306,7 @@ check_prev_add_irq(struct task_struct *c
* forwards-subgraph starting at <next>:
*/
if (!check_usage(curr, prev, next, LOCK_USED_IN_HARDIRQ_READ,
- LOCK_ENABLED_HARDIRQS, "hard-read"))
+ LOCK_ENABLED_HARDIRQ, "hard-read"))
return 0;
/*
@@ -1316,7 +1316,7 @@ check_prev_add_irq(struct task_struct *c
* forwards-subgraph starting at <next>:
*/
if (!check_usage(curr, prev, next, LOCK_USED_IN_SOFTIRQ,
- LOCK_ENABLED_SOFTIRQS, "soft"))
+ LOCK_ENABLED_SOFTIRQ, "soft"))
return 0;
/*
* Prove that the new dependency does not connect a softirq-safe-read
@@ -1325,7 +1325,7 @@ check_prev_add_irq(struct task_struct *c
* forwards-subgraph starting at <next>:
*/
if (!check_usage(curr, prev, next, LOCK_USED_IN_SOFTIRQ_READ,
- LOCK_ENABLED_SOFTIRQS, "soft"))
+ LOCK_ENABLED_SOFTIRQ, "soft"))
return 0;
/*
@@ -2008,17 +2008,17 @@ static int mark_lock_irq(struct task_str
switch(new_bit) {
case LOCK_USED_IN_HARDIRQ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS))
+ if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQ))
return 0;
if (!valid_state(curr, this, new_bit,
- LOCK_ENABLED_HARDIRQS_READ))
+ LOCK_ENABLED_HARDIRQ_READ))
return 0;
/*
* just marked it hardirq-safe, check that this lock
* took no hardirq-unsafe lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_HARDIRQS, "hard"))
+ LOCK_ENABLED_HARDIRQ, "hard"))
return 0;
#if STRICT_READ_CHECKS
/*
@@ -2026,24 +2026,24 @@ static int mark_lock_irq(struct task_str
* took no hardirq-unsafe-read lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_HARDIRQS_READ, "hard-read"))
+ LOCK_ENABLED_HARDIRQ_READ, "hard-read"))
return 0;
#endif
if (hardirq_verbose(hlock_class(this)))
ret = 2;
break;
case LOCK_USED_IN_SOFTIRQ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQS))
+ if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQ))
return 0;
if (!valid_state(curr, this, new_bit,
- LOCK_ENABLED_SOFTIRQS_READ))
+ LOCK_ENABLED_SOFTIRQ_READ))
return 0;
/*
* just marked it softirq-safe, check that this lock
* took no softirq-unsafe lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_SOFTIRQS, "soft"))
+ LOCK_ENABLED_SOFTIRQ, "soft"))
return 0;
#if STRICT_READ_CHECKS
/*
@@ -2051,7 +2051,7 @@ static int mark_lock_irq(struct task_str
* took no softirq-unsafe-read lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_SOFTIRQS_READ, "soft-read"))
+ LOCK_ENABLED_SOFTIRQ_READ, "soft-read"))
return 0;
#endif
if (softirq_verbose(hlock_class(this)))
@@ -2083,27 +2083,27 @@ static int mark_lock_irq(struct task_str
ret = 2;
break;
case LOCK_USED_IN_HARDIRQ_READ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS))
+ if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQ))
return 0;
/*
* just marked it hardirq-read-safe, check that this lock
* took no hardirq-unsafe lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_HARDIRQS, "hard"))
+ LOCK_ENABLED_HARDIRQ, "hard"))
return 0;
if (hardirq_verbose(hlock_class(this)))
ret = 2;
break;
case LOCK_USED_IN_SOFTIRQ_READ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQS))
+ if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQ))
return 0;
/*
* just marked it softirq-read-safe, check that this lock
* took no softirq-unsafe lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_SOFTIRQS, "soft"))
+ LOCK_ENABLED_SOFTIRQ, "soft"))
return 0;
if (softirq_verbose(hlock_class(this)))
ret = 2;
@@ -2121,7 +2121,7 @@ static int mark_lock_irq(struct task_str
if (reclaim_verbose(hlock_class(this)))
ret = 2;
break;
- case LOCK_ENABLED_HARDIRQS:
+ case LOCK_ENABLED_HARDIRQ:
if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ))
return 0;
if (!valid_state(curr, this, new_bit,
@@ -2147,7 +2147,7 @@ static int mark_lock_irq(struct task_str
if (hardirq_verbose(hlock_class(this)))
ret = 2;
break;
- case LOCK_ENABLED_SOFTIRQS:
+ case LOCK_ENABLED_SOFTIRQ:
if (!valid_state(curr, this, new_bit, LOCK_USED_IN_SOFTIRQ))
return 0;
if (!valid_state(curr, this, new_bit,
@@ -2199,7 +2199,7 @@ static int mark_lock_irq(struct task_str
if (reclaim_verbose(hlock_class(this)))
ret = 2;
break;
- case LOCK_ENABLED_HARDIRQS_READ:
+ case LOCK_ENABLED_HARDIRQ_READ:
if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ))
return 0;
#if STRICT_READ_CHECKS
@@ -2214,7 +2214,7 @@ static int mark_lock_irq(struct task_str
if (hardirq_verbose(hlock_class(this)))
ret = 2;
break;
- case LOCK_ENABLED_SOFTIRQS_READ:
+ case LOCK_ENABLED_SOFTIRQ_READ:
if (!valid_state(curr, this, new_bit, LOCK_USED_IN_SOFTIRQ))
return 0;
#if STRICT_READ_CHECKS
@@ -2274,16 +2274,16 @@ mark_held_locks(struct task_struct *curr
switch (mark) {
case HARDIRQ:
if (hlock->read)
- usage_bit = LOCK_ENABLED_HARDIRQS_READ;
+ usage_bit = LOCK_ENABLED_HARDIRQ_READ;
else
- usage_bit = LOCK_ENABLED_HARDIRQS;
+ usage_bit = LOCK_ENABLED_HARDIRQ;
break;
case SOFTIRQ:
if (hlock->read)
- usage_bit = LOCK_ENABLED_SOFTIRQS_READ;
+ usage_bit = LOCK_ENABLED_SOFTIRQ_READ;
else
- usage_bit = LOCK_ENABLED_SOFTIRQS;
+ usage_bit = LOCK_ENABLED_SOFTIRQ;
break;
case RECLAIM_FS:
@@ -2520,19 +2520,19 @@ static int mark_irqflags(struct task_str
if (!hlock->hardirqs_off) {
if (hlock->read) {
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_HARDIRQS_READ))
+ LOCK_ENABLED_HARDIRQ_READ))
return 0;
if (curr->softirqs_enabled)
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_SOFTIRQS_READ))
+ LOCK_ENABLED_SOFTIRQ_READ))
return 0;
} else {
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_HARDIRQS))
+ LOCK_ENABLED_HARDIRQ))
return 0;
if (curr->softirqs_enabled)
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_SOFTIRQS))
+ LOCK_ENABLED_SOFTIRQ))
return 0;
}
}
@@ -2640,10 +2640,10 @@ static int mark_lock(struct task_struct
case LOCK_USED_IN_SOFTIRQ:
case LOCK_USED_IN_HARDIRQ_READ:
case LOCK_USED_IN_SOFTIRQ_READ:
- case LOCK_ENABLED_HARDIRQS:
- case LOCK_ENABLED_SOFTIRQS:
- case LOCK_ENABLED_HARDIRQS_READ:
- case LOCK_ENABLED_SOFTIRQS_READ:
+ case LOCK_ENABLED_HARDIRQ:
+ case LOCK_ENABLED_SOFTIRQ:
+ case LOCK_ENABLED_HARDIRQ_READ:
+ case LOCK_ENABLED_SOFTIRQ_READ:
case LOCK_USED_IN_RECLAIM_FS:
case LOCK_USED_IN_RECLAIM_FS_READ:
case LOCK_HELD_OVER_RECLAIM_FS:
Index: linux-2.6/kernel/lockdep_proc.c
===================================================================
--- linux-2.6.orig/kernel/lockdep_proc.c
+++ linux-2.6/kernel/lockdep_proc.c
@@ -300,27 +300,27 @@ static int lockdep_stats_show(struct seq
nr_uncategorized++;
if (class->usage_mask & LOCKF_USED_IN_IRQ)
nr_irq_safe++;
- if (class->usage_mask & LOCKF_ENABLED_IRQS)
+ if (class->usage_mask & LOCKF_ENABLED_IRQ)
nr_irq_unsafe++;
if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ)
nr_softirq_safe++;
- if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS)
+ if (class->usage_mask & LOCKF_ENABLED_SOFTIRQ)
nr_softirq_unsafe++;
if (class->usage_mask & LOCKF_USED_IN_HARDIRQ)
nr_hardirq_safe++;
- if (class->usage_mask & LOCKF_ENABLED_HARDIRQS)
+ if (class->usage_mask & LOCKF_ENABLED_HARDIRQ)
nr_hardirq_unsafe++;
if (class->usage_mask & LOCKF_USED_IN_IRQ_READ)
nr_irq_read_safe++;
- if (class->usage_mask & LOCKF_ENABLED_IRQS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_IRQ_READ)
nr_irq_read_unsafe++;
if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ_READ)
nr_softirq_read_safe++;
- if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_SOFTIRQ_READ)
nr_softirq_read_unsafe++;
if (class->usage_mask & LOCKF_USED_IN_HARDIRQ_READ)
nr_hardirq_read_safe++;
- if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_HARDIRQ_READ)
nr_hardirq_read_unsafe++;
#ifdef CONFIG_PROVE_LOCKING
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 03/21] lockdep: sanitize reclaim bit names
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
2009-01-28 13:53 ` [PATCH 01/21] lockdep: annotate reclaim context (__GFP_NOFS) Peter Zijlstra
2009-01-28 13:53 ` [PATCH 02/21] lockdep: sanitize bit names Peter Zijlstra
@ 2009-01-28 13:53 ` Peter Zijlstra
2009-01-28 13:53 ` [PATCH 04/21] lockdep: lockdep_states.h Peter Zijlstra
` (18 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:53 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-generate2.patch --]
[-- Type: text/plain, Size: 6753 bytes --]
s/HELD_OVER/ENABLED/g
so that its similar to the hard and soft-irq names.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/lockdep.h | 8 ++++----
kernel/lockdep.c | 38 +++++++++++++++++++-------------------
2 files changed, 23 insertions(+), 23 deletions(-)
Index: linux-2.6/include/linux/lockdep.h
===================================================================
--- linux-2.6.orig/include/linux/lockdep.h
+++ linux-2.6/include/linux/lockdep.h
@@ -30,13 +30,13 @@ enum lock_usage_bit
LOCK_USED_IN_RECLAIM_FS,
LOCK_ENABLED_SOFTIRQ,
LOCK_ENABLED_HARDIRQ,
- LOCK_HELD_OVER_RECLAIM_FS,
+ LOCK_ENABLED_RECLAIM_FS,
LOCK_USED_IN_HARDIRQ_READ,
LOCK_USED_IN_SOFTIRQ_READ,
LOCK_USED_IN_RECLAIM_FS_READ,
LOCK_ENABLED_SOFTIRQ_READ,
LOCK_ENABLED_HARDIRQ_READ,
- LOCK_HELD_OVER_RECLAIM_FS_READ,
+ LOCK_ENABLED_RECLAIM_FS_READ,
LOCK_USAGE_STATES
};
@@ -49,7 +49,7 @@ enum lock_usage_bit
#define LOCKF_USED_IN_RECLAIM_FS (1 << LOCK_USED_IN_RECLAIM_FS)
#define LOCKF_ENABLED_HARDIRQ (1 << LOCK_ENABLED_HARDIRQ)
#define LOCKF_ENABLED_SOFTIRQ (1 << LOCK_ENABLED_SOFTIRQ)
-#define LOCKF_HELD_OVER_RECLAIM_FS (1 << LOCK_HELD_OVER_RECLAIM_FS)
+#define LOCKF_ENABLED_RECLAIM_FS (1 << LOCK_ENABLED_RECLAIM_FS)
#define LOCKF_ENABLED_IRQ (LOCKF_ENABLED_HARDIRQ | LOCKF_ENABLED_SOFTIRQ)
#define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ)
@@ -59,7 +59,7 @@ enum lock_usage_bit
#define LOCKF_USED_IN_RECLAIM_FS_READ (1 << LOCK_USED_IN_RECLAIM_FS_READ)
#define LOCKF_ENABLED_HARDIRQ_READ (1 << LOCK_ENABLED_HARDIRQ_READ)
#define LOCKF_ENABLED_SOFTIRQ_READ (1 << LOCK_ENABLED_SOFTIRQ_READ)
-#define LOCKF_HELD_OVER_RECLAIM_FS_READ (1 << LOCK_HELD_OVER_RECLAIM_FS_READ)
+#define LOCKF_ENABLED_RECLAIM_FS_READ (1 << LOCK_ENABLED_RECLAIM_FS_READ)
#define LOCKF_ENABLED_IRQ_READ \
(LOCKF_ENABLED_HARDIRQ_READ | LOCKF_ENABLED_SOFTIRQ_READ)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -458,8 +458,8 @@ static const char *usage_str[] =
[LOCK_ENABLED_HARDIRQ_READ] = "hardirq-on-R",
[LOCK_USED_IN_RECLAIM_FS] = "in-reclaim-W",
[LOCK_USED_IN_RECLAIM_FS_READ] = "in-reclaim-R",
- [LOCK_HELD_OVER_RECLAIM_FS] = "ov-reclaim-W",
- [LOCK_HELD_OVER_RECLAIM_FS_READ] = "ov-reclaim-R",
+ [LOCK_ENABLED_RECLAIM_FS] = "ov-reclaim-W",
+ [LOCK_ENABLED_RECLAIM_FS_READ] = "ov-reclaim-R",
};
const char * __get_key_name(struct lockdep_subclass_key *key, char *str)
@@ -504,14 +504,14 @@ get_usage_chars(struct lock_class *class
if (class->usage_mask & LOCKF_USED_IN_RECLAIM_FS)
*c5 = '+';
else
- if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS)
+ if (class->usage_mask & LOCKF_ENABLED_RECLAIM_FS)
*c5 = '-';
- if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_RECLAIM_FS_READ)
*c6 = '-';
if (class->usage_mask & LOCKF_USED_IN_RECLAIM_FS_READ) {
*c6 = '+';
- if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS_READ)
+ if (class->usage_mask & LOCKF_ENABLED_RECLAIM_FS_READ)
*c6 = '?';
}
@@ -1335,7 +1335,7 @@ check_prev_add_irq(struct task_struct *c
* forwards-subgraph starting at <next>:
*/
if (!check_usage(curr, prev, next, LOCK_USED_IN_RECLAIM_FS,
- LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs"))
+ LOCK_ENABLED_RECLAIM_FS, "reclaim-fs"))
return 0;
/*
@@ -1345,7 +1345,7 @@ check_prev_add_irq(struct task_struct *c
* forwards-subgraph starting at <next>:
*/
if (!check_usage(curr, prev, next, LOCK_USED_IN_RECLAIM_FS_READ,
- LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs-read"))
+ LOCK_ENABLED_RECLAIM_FS, "reclaim-fs-read"))
return 0;
return 1;
@@ -2058,17 +2058,17 @@ static int mark_lock_irq(struct task_str
ret = 2;
break;
case LOCK_USED_IN_RECLAIM_FS:
- if (!valid_state(curr, this, new_bit, LOCK_HELD_OVER_RECLAIM_FS))
+ if (!valid_state(curr, this, new_bit, LOCK_ENABLED_RECLAIM_FS))
return 0;
if (!valid_state(curr, this, new_bit,
- LOCK_HELD_OVER_RECLAIM_FS_READ))
+ LOCK_ENABLED_RECLAIM_FS_READ))
return 0;
/*
* just marked it reclaim-fs-safe, check that this lock
* took no reclaim-fs-unsafe lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs"))
+ LOCK_ENABLED_RECLAIM_FS, "reclaim-fs"))
return 0;
#if STRICT_READ_CHECKS
/*
@@ -2076,7 +2076,7 @@ static int mark_lock_irq(struct task_str
* took no reclaim-fs-unsafe-read lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_HELD_OVER_RECLAIM_FS_READ, "reclaim-fs-read"))
+ LOCK_ENABLED_RECLAIM_FS_READ, "reclaim-fs-read"))
return 0;
#endif
if (reclaim_verbose(hlock_class(this)))
@@ -2109,14 +2109,14 @@ static int mark_lock_irq(struct task_str
ret = 2;
break;
case LOCK_USED_IN_RECLAIM_FS_READ:
- if (!valid_state(curr, this, new_bit, LOCK_HELD_OVER_RECLAIM_FS))
+ if (!valid_state(curr, this, new_bit, LOCK_ENABLED_RECLAIM_FS))
return 0;
/*
* just marked it reclaim-fs-read-safe, check that this lock
* took no reclaim-fs-unsafe lock in the past:
*/
if (!check_usage_forwards(curr, this,
- LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs"))
+ LOCK_ENABLED_RECLAIM_FS, "reclaim-fs"))
return 0;
if (reclaim_verbose(hlock_class(this)))
ret = 2;
@@ -2173,7 +2173,7 @@ static int mark_lock_irq(struct task_str
if (softirq_verbose(hlock_class(this)))
ret = 2;
break;
- case LOCK_HELD_OVER_RECLAIM_FS:
+ case LOCK_ENABLED_RECLAIM_FS:
if (!valid_state(curr, this, new_bit, LOCK_USED_IN_RECLAIM_FS))
return 0;
if (!valid_state(curr, this, new_bit,
@@ -2229,7 +2229,7 @@ static int mark_lock_irq(struct task_str
if (softirq_verbose(hlock_class(this)))
ret = 2;
break;
- case LOCK_HELD_OVER_RECLAIM_FS_READ:
+ case LOCK_ENABLED_RECLAIM_FS_READ:
if (!valid_state(curr, this, new_bit, LOCK_USED_IN_RECLAIM_FS))
return 0;
#if STRICT_READ_CHECKS
@@ -2288,9 +2288,9 @@ mark_held_locks(struct task_struct *curr
case RECLAIM_FS:
if (hlock->read)
- usage_bit = LOCK_HELD_OVER_RECLAIM_FS_READ;
+ usage_bit = LOCK_ENABLED_RECLAIM_FS_READ;
else
- usage_bit = LOCK_HELD_OVER_RECLAIM_FS;
+ usage_bit = LOCK_ENABLED_RECLAIM_FS;
break;
default:
@@ -2646,8 +2646,8 @@ static int mark_lock(struct task_struct
case LOCK_ENABLED_SOFTIRQ_READ:
case LOCK_USED_IN_RECLAIM_FS:
case LOCK_USED_IN_RECLAIM_FS_READ:
- case LOCK_HELD_OVER_RECLAIM_FS:
- case LOCK_HELD_OVER_RECLAIM_FS_READ:
+ case LOCK_ENABLED_RECLAIM_FS:
+ case LOCK_ENABLED_RECLAIM_FS_READ:
ret = mark_lock_irq(curr, this, new_bit);
if (!ret)
return 0;
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 04/21] lockdep: lockdep_states.h
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (2 preceding siblings ...)
2009-01-28 13:53 ` [PATCH 03/21] lockdep: sanitize reclaim " Peter Zijlstra
@ 2009-01-28 13:53 ` Peter Zijlstra
2009-01-28 13:53 ` [PATCH 05/21] lockdep: simplify mark_held_locks Peter Zijlstra
` (17 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:53 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-generate4.patch --]
[-- Type: text/plain, Size: 445 bytes --]
Introduce a header file to generate all the states from.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep_states.h | 3 +++
1 file changed, 3 insertions(+)
Index: linux-2.6/kernel/lockdep_states.h
===================================================================
--- /dev/null
+++ linux-2.6/kernel/lockdep_states.h
@@ -0,0 +1,3 @@
+LOCKDEP_STATE(HARDIRQ)
+LOCKDEP_STATE(SOFTIRQ)
+LOCKDEP_STATE(RECLAIM_FS)
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 05/21] lockdep: simplify mark_held_locks
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (3 preceding siblings ...)
2009-01-28 13:53 ` [PATCH 04/21] lockdep: lockdep_states.h Peter Zijlstra
@ 2009-01-28 13:53 ` Peter Zijlstra
2009-01-28 13:53 ` [PATCH 06/21] lockdep: simplify mark_lock() Peter Zijlstra
` (16 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:53 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-generate5.patch --]
[-- Type: text/plain, Size: 1561 bytes --]
remove the explicit state iteration
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 38 ++++++++++++++------------------------
1 file changed, 14 insertions(+), 24 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2253,11 +2253,19 @@ static int mark_lock_irq(struct task_str
}
enum mark_type {
- HARDIRQ,
- SOFTIRQ,
- RECLAIM_FS,
+#define LOCKDEP_STATE(__STATE) __STATE,
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
};
+#define MARK_HELD_CASE(__STATE) \
+ case __STATE: \
+ if (hlock->read) \
+ usage_bit = LOCK_ENABLED_##__STATE##_READ; \
+ else \
+ usage_bit = LOCK_ENABLED_##__STATE; \
+ break;
+
/*
* Mark all held locks with a usage bit:
*/
@@ -2272,27 +2280,9 @@ mark_held_locks(struct task_struct *curr
hlock = curr->held_locks + i;
switch (mark) {
- case HARDIRQ:
- if (hlock->read)
- usage_bit = LOCK_ENABLED_HARDIRQ_READ;
- else
- usage_bit = LOCK_ENABLED_HARDIRQ;
- break;
-
- case SOFTIRQ:
- if (hlock->read)
- usage_bit = LOCK_ENABLED_SOFTIRQ_READ;
- else
- usage_bit = LOCK_ENABLED_SOFTIRQ;
- break;
-
- case RECLAIM_FS:
- if (hlock->read)
- usage_bit = LOCK_ENABLED_RECLAIM_FS_READ;
- else
- usage_bit = LOCK_ENABLED_RECLAIM_FS;
- break;
-
+#define LOCKDEP_STATE(__STATE) MARK_HELD_CASE(__STATE)
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
default:
BUG();
}
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 06/21] lockdep: simplify mark_lock()
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (4 preceding siblings ...)
2009-01-28 13:53 ` [PATCH 05/21] lockdep: simplify mark_held_locks Peter Zijlstra
@ 2009-01-28 13:53 ` Peter Zijlstra
2009-01-28 13:53 ` [PATCH 07/21] lockdep: move state bit definitions around Peter Zijlstra
` (15 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:53 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-generate6.patch --]
[-- Type: text/plain, Size: 1154 bytes --]
remove the state iteration
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2626,18 +2626,13 @@ static int mark_lock(struct task_struct
return 0;
switch (new_bit) {
- case LOCK_USED_IN_HARDIRQ:
- case LOCK_USED_IN_SOFTIRQ:
- case LOCK_USED_IN_HARDIRQ_READ:
- case LOCK_USED_IN_SOFTIRQ_READ:
- case LOCK_ENABLED_HARDIRQ:
- case LOCK_ENABLED_SOFTIRQ:
- case LOCK_ENABLED_HARDIRQ_READ:
- case LOCK_ENABLED_SOFTIRQ_READ:
- case LOCK_USED_IN_RECLAIM_FS:
- case LOCK_USED_IN_RECLAIM_FS_READ:
- case LOCK_ENABLED_RECLAIM_FS:
- case LOCK_ENABLED_RECLAIM_FS_READ:
+#define LOCKDEP_STATE(__STATE) \
+ case LOCK_USED_IN_##__STATE: \
+ case LOCK_USED_IN_##__STATE##_READ: \
+ case LOCK_ENABLED_##__STATE: \
+ case LOCK_ENABLED_##__STATE##_READ:
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
ret = mark_lock_irq(curr, this, new_bit);
if (!ret)
return 0;
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 07/21] lockdep: move state bit definitions around
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (5 preceding siblings ...)
2009-01-28 13:53 ` [PATCH 06/21] lockdep: simplify mark_lock() Peter Zijlstra
@ 2009-01-28 13:53 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 08/21] lockdep: generate the state bit definitions Peter Zijlstra
` (14 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:53 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-generate7.patch --]
[-- Type: text/plain, Size: 5173 bytes --]
For convenience later.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/lockdep.h | 49 +++------------------------------------------
kernel/lockdep_internals.h | 46 ++++++++++++++++++++++++++++++++++++++++++
kernel/lockdep_states.h | 6 +++++
3 files changed, 56 insertions(+), 45 deletions(-)
Index: linux-2.6/kernel/lockdep_internals.h
===================================================================
--- linux-2.6.orig/kernel/lockdep_internals.h
+++ linux-2.6/kernel/lockdep_internals.h
@@ -7,6 +7,52 @@
*/
/*
+ * Lock-class usage-state bits:
+ */
+enum lock_usage_bit {
+ LOCK_USED = 0,
+ LOCK_USED_IN_HARDIRQ,
+ LOCK_USED_IN_SOFTIRQ,
+ LOCK_USED_IN_RECLAIM_FS,
+ LOCK_ENABLED_SOFTIRQ,
+ LOCK_ENABLED_HARDIRQ,
+ LOCK_ENABLED_RECLAIM_FS,
+ LOCK_USED_IN_HARDIRQ_READ,
+ LOCK_USED_IN_SOFTIRQ_READ,
+ LOCK_USED_IN_RECLAIM_FS_READ,
+ LOCK_ENABLED_SOFTIRQ_READ,
+ LOCK_ENABLED_HARDIRQ_READ,
+ LOCK_ENABLED_RECLAIM_FS_READ,
+ LOCK_USAGE_STATES
+};
+
+/*
+ * Usage-state bitmasks:
+ */
+#define LOCKF_USED (1 << LOCK_USED)
+#define LOCKF_USED_IN_HARDIRQ (1 << LOCK_USED_IN_HARDIRQ)
+#define LOCKF_USED_IN_SOFTIRQ (1 << LOCK_USED_IN_SOFTIRQ)
+#define LOCKF_USED_IN_RECLAIM_FS (1 << LOCK_USED_IN_RECLAIM_FS)
+#define LOCKF_ENABLED_HARDIRQ (1 << LOCK_ENABLED_HARDIRQ)
+#define LOCKF_ENABLED_SOFTIRQ (1 << LOCK_ENABLED_SOFTIRQ)
+#define LOCKF_ENABLED_RECLAIM_FS (1 << LOCK_ENABLED_RECLAIM_FS)
+
+#define LOCKF_ENABLED_IRQ (LOCKF_ENABLED_HARDIRQ | LOCKF_ENABLED_SOFTIRQ)
+#define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ)
+
+#define LOCKF_USED_IN_HARDIRQ_READ (1 << LOCK_USED_IN_HARDIRQ_READ)
+#define LOCKF_USED_IN_SOFTIRQ_READ (1 << LOCK_USED_IN_SOFTIRQ_READ)
+#define LOCKF_USED_IN_RECLAIM_FS_READ (1 << LOCK_USED_IN_RECLAIM_FS_READ)
+#define LOCKF_ENABLED_HARDIRQ_READ (1 << LOCK_ENABLED_HARDIRQ_READ)
+#define LOCKF_ENABLED_SOFTIRQ_READ (1 << LOCK_ENABLED_SOFTIRQ_READ)
+#define LOCKF_ENABLED_RECLAIM_FS_READ (1 << LOCK_ENABLED_RECLAIM_FS_READ)
+
+#define LOCKF_ENABLED_IRQ_READ \
+ (LOCKF_ENABLED_HARDIRQ_READ | LOCKF_ENABLED_SOFTIRQ_READ)
+#define LOCKF_USED_IN_IRQ_READ \
+ (LOCKF_USED_IN_HARDIRQ_READ | LOCKF_USED_IN_SOFTIRQ_READ)
+
+/*
* MAX_LOCKDEP_ENTRIES is the maximum number of lock dependencies
* we track.
*
Index: linux-2.6/include/linux/lockdep.h
===================================================================
--- linux-2.6.orig/include/linux/lockdep.h
+++ linux-2.6/include/linux/lockdep.h
@@ -20,51 +20,10 @@ struct lockdep_map;
#include <linux/stacktrace.h>
/*
- * Lock-class usage-state bits:
+ * We'd rather not expose kernel/lockdep_states.h this wide, but we do need
+ * the total number of states... :-(
*/
-enum lock_usage_bit
-{
- LOCK_USED = 0,
- LOCK_USED_IN_HARDIRQ,
- LOCK_USED_IN_SOFTIRQ,
- LOCK_USED_IN_RECLAIM_FS,
- LOCK_ENABLED_SOFTIRQ,
- LOCK_ENABLED_HARDIRQ,
- LOCK_ENABLED_RECLAIM_FS,
- LOCK_USED_IN_HARDIRQ_READ,
- LOCK_USED_IN_SOFTIRQ_READ,
- LOCK_USED_IN_RECLAIM_FS_READ,
- LOCK_ENABLED_SOFTIRQ_READ,
- LOCK_ENABLED_HARDIRQ_READ,
- LOCK_ENABLED_RECLAIM_FS_READ,
- LOCK_USAGE_STATES
-};
-
-/*
- * Usage-state bitmasks:
- */
-#define LOCKF_USED (1 << LOCK_USED)
-#define LOCKF_USED_IN_HARDIRQ (1 << LOCK_USED_IN_HARDIRQ)
-#define LOCKF_USED_IN_SOFTIRQ (1 << LOCK_USED_IN_SOFTIRQ)
-#define LOCKF_USED_IN_RECLAIM_FS (1 << LOCK_USED_IN_RECLAIM_FS)
-#define LOCKF_ENABLED_HARDIRQ (1 << LOCK_ENABLED_HARDIRQ)
-#define LOCKF_ENABLED_SOFTIRQ (1 << LOCK_ENABLED_SOFTIRQ)
-#define LOCKF_ENABLED_RECLAIM_FS (1 << LOCK_ENABLED_RECLAIM_FS)
-
-#define LOCKF_ENABLED_IRQ (LOCKF_ENABLED_HARDIRQ | LOCKF_ENABLED_SOFTIRQ)
-#define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ)
-
-#define LOCKF_USED_IN_HARDIRQ_READ (1 << LOCK_USED_IN_HARDIRQ_READ)
-#define LOCKF_USED_IN_SOFTIRQ_READ (1 << LOCK_USED_IN_SOFTIRQ_READ)
-#define LOCKF_USED_IN_RECLAIM_FS_READ (1 << LOCK_USED_IN_RECLAIM_FS_READ)
-#define LOCKF_ENABLED_HARDIRQ_READ (1 << LOCK_ENABLED_HARDIRQ_READ)
-#define LOCKF_ENABLED_SOFTIRQ_READ (1 << LOCK_ENABLED_SOFTIRQ_READ)
-#define LOCKF_ENABLED_RECLAIM_FS_READ (1 << LOCK_ENABLED_RECLAIM_FS_READ)
-
-#define LOCKF_ENABLED_IRQ_READ \
- (LOCKF_ENABLED_HARDIRQ_READ | LOCKF_ENABLED_SOFTIRQ_READ)
-#define LOCKF_USED_IN_IRQ_READ \
- (LOCKF_USED_IN_HARDIRQ_READ | LOCKF_USED_IN_SOFTIRQ_READ)
+#define XXX_LOCK_USAGE_STATES (1+3*4)
#define MAX_LOCKDEP_SUBCLASSES 8UL
@@ -105,7 +64,7 @@ struct lock_class {
* IRQ/softirq usage tracking bits:
*/
unsigned long usage_mask;
- struct stack_trace usage_traces[LOCK_USAGE_STATES];
+ struct stack_trace usage_traces[XXX_LOCK_USAGE_STATES];
/*
* These fields represent a directed graph of lock dependencies,
Index: linux-2.6/kernel/lockdep_states.h
===================================================================
--- linux-2.6.orig/kernel/lockdep_states.h
+++ linux-2.6/kernel/lockdep_states.h
@@ -1,3 +1,9 @@
+/*
+ * Lockdep states,
+ *
+ * please update XXX_LOCK_USAGE_STATES in include/linux/lockdep.h whenever
+ * you add one, or come up with a nice dynamic solution.
+ */
LOCKDEP_STATE(HARDIRQ)
LOCKDEP_STATE(SOFTIRQ)
LOCKDEP_STATE(RECLAIM_FS)
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 08/21] lockdep: generate the state bit definitions
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (6 preceding siblings ...)
2009-01-28 13:53 ` [PATCH 07/21] lockdep: move state bit definitions around Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 09/21] lockdep: generate usage strings Peter Zijlstra
` (13 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-generate8.patch --]
[-- Type: text/plain, Size: 2790 bytes --]
Generate the state bit definitions from the lockdep_states.h file.
Also, move LOCK_USED to last, so that the
USED_IN
USED_IN_READ
ENABLED
ENABLED_READ
states are nicely bit aligned -- we're going to use that property
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep_internals.h | 47 +++++++++++++++++++--------------------------
1 file changed, 20 insertions(+), 27 deletions(-)
Index: linux-2.6/kernel/lockdep_internals.h
===================================================================
--- linux-2.6.orig/kernel/lockdep_internals.h
+++ linux-2.6/kernel/lockdep_internals.h
@@ -10,43 +10,36 @@
* Lock-class usage-state bits:
*/
enum lock_usage_bit {
- LOCK_USED = 0,
- LOCK_USED_IN_HARDIRQ,
- LOCK_USED_IN_SOFTIRQ,
- LOCK_USED_IN_RECLAIM_FS,
- LOCK_ENABLED_SOFTIRQ,
- LOCK_ENABLED_HARDIRQ,
- LOCK_ENABLED_RECLAIM_FS,
- LOCK_USED_IN_HARDIRQ_READ,
- LOCK_USED_IN_SOFTIRQ_READ,
- LOCK_USED_IN_RECLAIM_FS_READ,
- LOCK_ENABLED_SOFTIRQ_READ,
- LOCK_ENABLED_HARDIRQ_READ,
- LOCK_ENABLED_RECLAIM_FS_READ,
+#define LOCKDEP_STATE(__STATE) \
+ LOCK_USED_IN_##__STATE, \
+ LOCK_USED_IN_##__STATE##_READ, \
+ LOCK_ENABLED_##__STATE, \
+ LOCK_ENABLED_##__STATE##_READ,
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+ LOCK_USED,
LOCK_USAGE_STATES
};
/*
* Usage-state bitmasks:
*/
-#define LOCKF_USED (1 << LOCK_USED)
-#define LOCKF_USED_IN_HARDIRQ (1 << LOCK_USED_IN_HARDIRQ)
-#define LOCKF_USED_IN_SOFTIRQ (1 << LOCK_USED_IN_SOFTIRQ)
-#define LOCKF_USED_IN_RECLAIM_FS (1 << LOCK_USED_IN_RECLAIM_FS)
-#define LOCKF_ENABLED_HARDIRQ (1 << LOCK_ENABLED_HARDIRQ)
-#define LOCKF_ENABLED_SOFTIRQ (1 << LOCK_ENABLED_SOFTIRQ)
-#define LOCKF_ENABLED_RECLAIM_FS (1 << LOCK_ENABLED_RECLAIM_FS)
+#define __LOCKF(__STATE) LOCKF_##__STATE = (1 << LOCK_##__STATE),
+
+enum {
+#define LOCKDEP_STATE(__STATE) \
+ __LOCKF(USED_IN_##__STATE) \
+ __LOCKF(USED_IN_##__STATE##_READ) \
+ __LOCKF(ENABLED_##__STATE) \
+ __LOCKF(ENABLED_##__STATE##_READ)
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+ __LOCKF(USED)
+};
#define LOCKF_ENABLED_IRQ (LOCKF_ENABLED_HARDIRQ | LOCKF_ENABLED_SOFTIRQ)
#define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ)
-#define LOCKF_USED_IN_HARDIRQ_READ (1 << LOCK_USED_IN_HARDIRQ_READ)
-#define LOCKF_USED_IN_SOFTIRQ_READ (1 << LOCK_USED_IN_SOFTIRQ_READ)
-#define LOCKF_USED_IN_RECLAIM_FS_READ (1 << LOCK_USED_IN_RECLAIM_FS_READ)
-#define LOCKF_ENABLED_HARDIRQ_READ (1 << LOCK_ENABLED_HARDIRQ_READ)
-#define LOCKF_ENABLED_SOFTIRQ_READ (1 << LOCK_ENABLED_SOFTIRQ_READ)
-#define LOCKF_ENABLED_RECLAIM_FS_READ (1 << LOCK_ENABLED_RECLAIM_FS_READ)
-
#define LOCKF_ENABLED_IRQ_READ \
(LOCKF_ENABLED_HARDIRQ_READ | LOCKF_ENABLED_SOFTIRQ_READ)
#define LOCKF_USED_IN_IRQ_READ \
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 09/21] lockdep: generate usage strings
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (7 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 08/21] lockdep: generate the state bit definitions Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 10/21] lockdep: split up mark_lock_irq() Peter Zijlstra
` (12 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-generate9.patch --]
[-- Type: text/plain, Size: 1643 bytes --]
generate the usage strings
XXX capital invasion :-(
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -445,21 +445,21 @@ atomic_t nr_find_usage_backwards_recursi
* Locking printouts:
*/
+#define __STR(foo) #foo
+#define STR(foo) __STR(foo)
+
+#define __USAGE(__STATE) \
+ [LOCK_USED_IN_##__STATE] = "IN-"STR(__STATE)"-W", \
+ [LOCK_ENABLED_##__STATE] = STR(__STATE)"-ON-W", \
+ [LOCK_USED_IN_##__STATE##_READ] = "IN-"STR(__STATE)"-R", \
+ [LOCK_ENABLED_##__STATE##_READ] = STR(__STATE)"-ON-R",
+
static const char *usage_str[] =
{
- [LOCK_USED] = "initial-use ",
- [LOCK_USED_IN_HARDIRQ] = "in-hardirq-W",
- [LOCK_USED_IN_SOFTIRQ] = "in-softirq-W",
- [LOCK_ENABLED_SOFTIRQ] = "softirq-on-W",
- [LOCK_ENABLED_HARDIRQ] = "hardirq-on-W",
- [LOCK_USED_IN_HARDIRQ_READ] = "in-hardirq-R",
- [LOCK_USED_IN_SOFTIRQ_READ] = "in-softirq-R",
- [LOCK_ENABLED_SOFTIRQ_READ] = "softirq-on-R",
- [LOCK_ENABLED_HARDIRQ_READ] = "hardirq-on-R",
- [LOCK_USED_IN_RECLAIM_FS] = "in-reclaim-W",
- [LOCK_USED_IN_RECLAIM_FS_READ] = "in-reclaim-R",
- [LOCK_ENABLED_RECLAIM_FS] = "ov-reclaim-W",
- [LOCK_ENABLED_RECLAIM_FS_READ] = "ov-reclaim-R",
+#define LOCKDEP_STATE(__STATE) __USAGE(__STATE)
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+ [LOCK_USED] = "INITIAL USE",
};
const char * __get_key_name(struct lockdep_subclass_key *key, char *str)
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 10/21] lockdep: split up mark_lock_irq()
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (8 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 09/21] lockdep: generate usage strings Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 11/21] lockdep: simplify the mark_lock_irq() helpers Peter Zijlstra
` (11 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_irq.patch --]
[-- Type: text/plain, Size: 12237 bytes --]
split mark_lock_irq() into 4 simple helper functions
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 372 +++++++++++++++++++++----------------------------------
1 file changed, 147 insertions(+), 225 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2001,6 +2001,109 @@ static int reclaim_verbose(struct lock_c
#define STRICT_READ_CHECKS 1
+static int
+mark_lock_irq_used_in(struct task_struct *curr, struct held_lock *this,
+ int new_bit, int excl_bit,
+ const char *name, const char *rname,
+ int (*verbose)(struct lock_class *class))
+{
+ if (!valid_state(curr, this, new_bit, excl_bit))
+ return 0;
+ if (!valid_state(curr, this, new_bit, excl_bit + 1))
+ return 0;
+ /*
+ * just marked it hardirq-safe, check that this lock
+ * took no hardirq-unsafe lock in the past:
+ */
+ if (!check_usage_forwards(curr, this, excl_bit, name))
+ return 0;
+#if STRICT_READ_CHECKS
+ /*
+ * just marked it hardirq-safe, check that this lock
+ * took no hardirq-unsafe-read lock in the past:
+ */
+ if (!check_usage_forwards(curr, this, excl_bit + 1, rname))
+ return 0;
+#endif
+ if (verbose(hlock_class(this)))
+ return 2;
+
+ return 1;
+}
+
+static int
+mark_lock_irq_used_in_read(struct task_struct *curr, struct held_lock *this,
+ int new_bit, int excl_bit,
+ const char *name, const char *rname,
+ int (*verbose)(struct lock_class *class))
+{
+ if (!valid_state(curr, this, new_bit, excl_bit))
+ return 0;
+ /*
+ * just marked it hardirq-read-safe, check that this lock
+ * took no hardirq-unsafe lock in the past:
+ */
+ if (!check_usage_forwards(curr, this, excl_bit, name))
+ return 0;
+ if (verbose(hlock_class(this)))
+ return 2;
+
+ return 1;
+}
+
+static int
+mark_lock_irq_enabled(struct task_struct *curr, struct held_lock *this,
+ int new_bit, int excl_bit,
+ const char *name, const char *rname,
+ int (*verbose)(struct lock_class *class))
+{
+ if (!valid_state(curr, this, new_bit, excl_bit))
+ return 0;
+ if (!valid_state(curr, this, new_bit, excl_bit + 1))
+ return 0;
+ /*
+ * just marked it hardirq-unsafe, check that no hardirq-safe
+ * lock in the system ever took it in the past:
+ */
+ if (!check_usage_backwards(curr, this, excl_bit, name))
+ return 0;
+#if STRICT_READ_CHECKS
+ /*
+ * just marked it hardirq-unsafe, check that no
+ * hardirq-safe-read lock in the system ever took
+ * it in the past:
+ */
+ if (!check_usage_backwards(curr, this, excl_bit + 1, rname))
+ return 0;
+#endif
+ if (verbose(hlock_class(this)))
+ return 2;
+
+ return 1;
+}
+
+static int
+mark_lock_irq_enabled_read(struct task_struct *curr, struct held_lock *this,
+ int new_bit, int excl_bit,
+ const char *name, const char *rname,
+ int (*verbose)(struct lock_class *class))
+{
+ if (!valid_state(curr, this, new_bit, excl_bit))
+ return 0;
+#if STRICT_READ_CHECKS
+ /*
+ * just marked it hardirq-read-unsafe, check that no
+ * hardirq-safe lock in the system ever took it in the past:
+ */
+ if (!check_usage_backwards(curr, this, excl_bit, name))
+ return 0;
+#endif
+ if (verbose(hlock_class(this)))
+ return 2;
+
+ return 1;
+}
+
static int mark_lock_irq(struct task_struct *curr, struct held_lock *this,
enum lock_usage_bit new_bit)
{
@@ -2008,242 +2111,61 @@ static int mark_lock_irq(struct task_str
switch(new_bit) {
case LOCK_USED_IN_HARDIRQ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQ))
- return 0;
- if (!valid_state(curr, this, new_bit,
- LOCK_ENABLED_HARDIRQ_READ))
- return 0;
- /*
- * just marked it hardirq-safe, check that this lock
- * took no hardirq-unsafe lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_HARDIRQ, "hard"))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it hardirq-safe, check that this lock
- * took no hardirq-unsafe-read lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_HARDIRQ_READ, "hard-read"))
- return 0;
-#endif
- if (hardirq_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_used_in(curr, this, new_bit,
+ LOCK_ENABLED_HARDIRQ,
+ "hard", "hard-read", hardirq_verbose);
case LOCK_USED_IN_SOFTIRQ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQ))
- return 0;
- if (!valid_state(curr, this, new_bit,
- LOCK_ENABLED_SOFTIRQ_READ))
- return 0;
- /*
- * just marked it softirq-safe, check that this lock
- * took no softirq-unsafe lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_SOFTIRQ, "soft"))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it softirq-safe, check that this lock
- * took no softirq-unsafe-read lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_SOFTIRQ_READ, "soft-read"))
- return 0;
-#endif
- if (softirq_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_used_in(curr, this, new_bit,
+ LOCK_ENABLED_SOFTIRQ,
+ "soft", "soft-read", softirq_verbose);
case LOCK_USED_IN_RECLAIM_FS:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_RECLAIM_FS))
- return 0;
- if (!valid_state(curr, this, new_bit,
- LOCK_ENABLED_RECLAIM_FS_READ))
- return 0;
- /*
- * just marked it reclaim-fs-safe, check that this lock
- * took no reclaim-fs-unsafe lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_RECLAIM_FS, "reclaim-fs"))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it reclaim-fs-safe, check that this lock
- * took no reclaim-fs-unsafe-read lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_RECLAIM_FS_READ, "reclaim-fs-read"))
- return 0;
-#endif
- if (reclaim_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_used_in(curr, this, new_bit,
+ LOCK_ENABLED_RECLAIM_FS,
+ "reclaim-fs", "reclaim-fs-read",
+ reclaim_verbose);
+
case LOCK_USED_IN_HARDIRQ_READ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQ))
- return 0;
- /*
- * just marked it hardirq-read-safe, check that this lock
- * took no hardirq-unsafe lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_HARDIRQ, "hard"))
- return 0;
- if (hardirq_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_used_in_read(curr, this, new_bit,
+ LOCK_ENABLED_HARDIRQ,
+ "hard", "hard-read", hardirq_verbose);
case LOCK_USED_IN_SOFTIRQ_READ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQ))
- return 0;
- /*
- * just marked it softirq-read-safe, check that this lock
- * took no softirq-unsafe lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_SOFTIRQ, "soft"))
- return 0;
- if (softirq_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_used_in_read(curr, this, new_bit,
+ LOCK_ENABLED_SOFTIRQ,
+ "soft", "soft-read", softirq_verbose);
case LOCK_USED_IN_RECLAIM_FS_READ:
- if (!valid_state(curr, this, new_bit, LOCK_ENABLED_RECLAIM_FS))
- return 0;
- /*
- * just marked it reclaim-fs-read-safe, check that this lock
- * took no reclaim-fs-unsafe lock in the past:
- */
- if (!check_usage_forwards(curr, this,
- LOCK_ENABLED_RECLAIM_FS, "reclaim-fs"))
- return 0;
- if (reclaim_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_used_in_read(curr, this, new_bit,
+ LOCK_ENABLED_RECLAIM_FS,
+ "reclaim-fs", "reclaim-fs-read",
+ reclaim_verbose);
+
case LOCK_ENABLED_HARDIRQ:
- if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ))
- return 0;
- if (!valid_state(curr, this, new_bit,
- LOCK_USED_IN_HARDIRQ_READ))
- return 0;
- /*
- * just marked it hardirq-unsafe, check that no hardirq-safe
- * lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_HARDIRQ, "hard"))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it hardirq-unsafe, check that no
- * hardirq-safe-read lock in the system ever took
- * it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_HARDIRQ_READ, "hard-read"))
- return 0;
-#endif
- if (hardirq_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_enabled(curr, this, new_bit,
+ LOCK_USED_IN_HARDIRQ,
+ "hard", "hard-read", hardirq_verbose);
case LOCK_ENABLED_SOFTIRQ:
- if (!valid_state(curr, this, new_bit, LOCK_USED_IN_SOFTIRQ))
- return 0;
- if (!valid_state(curr, this, new_bit,
- LOCK_USED_IN_SOFTIRQ_READ))
- return 0;
- /*
- * just marked it softirq-unsafe, check that no softirq-safe
- * lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_SOFTIRQ, "soft"))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it softirq-unsafe, check that no
- * softirq-safe-read lock in the system ever took
- * it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_SOFTIRQ_READ, "soft-read"))
- return 0;
-#endif
- if (softirq_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_enabled(curr, this, new_bit,
+ LOCK_USED_IN_SOFTIRQ,
+ "soft", "soft-read", softirq_verbose);
case LOCK_ENABLED_RECLAIM_FS:
- if (!valid_state(curr, this, new_bit, LOCK_USED_IN_RECLAIM_FS))
- return 0;
- if (!valid_state(curr, this, new_bit,
- LOCK_USED_IN_RECLAIM_FS_READ))
- return 0;
- /*
- * just marked it reclaim-fs-unsafe, check that no reclaim-fs-safe
- * lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_RECLAIM_FS, "reclaim-fs"))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it softirq-unsafe, check that no
- * softirq-safe-read lock in the system ever took
- * it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_RECLAIM_FS_READ, "reclaim-fs-read"))
- return 0;
-#endif
- if (reclaim_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_enabled(curr, this, new_bit,
+ LOCK_USED_IN_RECLAIM_FS,
+ "reclaim-fs", "reclaim-fs-read",
+ reclaim_verbose);
+
case LOCK_ENABLED_HARDIRQ_READ:
- if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it hardirq-read-unsafe, check that no
- * hardirq-safe lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_HARDIRQ, "hard"))
- return 0;
-#endif
- if (hardirq_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_enabled_read(curr, this, new_bit,
+ LOCK_USED_IN_HARDIRQ,
+ "hard", "hard-read", hardirq_verbose);
case LOCK_ENABLED_SOFTIRQ_READ:
- if (!valid_state(curr, this, new_bit, LOCK_USED_IN_SOFTIRQ))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it softirq-read-unsafe, check that no
- * softirq-safe lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_SOFTIRQ, "soft"))
- return 0;
-#endif
- if (softirq_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_enabled_read(curr, this, new_bit,
+ LOCK_USED_IN_SOFTIRQ,
+ "soft", "soft-read", softirq_verbose);
case LOCK_ENABLED_RECLAIM_FS_READ:
- if (!valid_state(curr, this, new_bit, LOCK_USED_IN_RECLAIM_FS))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it reclaim-fs-read-unsafe, check that no
- * reclaim-fs-safe lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this,
- LOCK_USED_IN_RECLAIM_FS, "reclaim-fs"))
- return 0;
-#endif
- if (reclaim_verbose(hlock_class(this)))
- ret = 2;
- break;
+ return mark_lock_irq_enabled_read(curr, this, new_bit,
+ LOCK_USED_IN_RECLAIM_FS,
+ "reclaim-fs", "reclaim-fs-read",
+ reclaim_verbose);
+
default:
WARN_ON(1);
break;
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 11/21] lockdep: simplify the mark_lock_irq() helpers
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (9 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 10/21] lockdep: split up mark_lock_irq() Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 12/21] lockdep: further simplify " Peter Zijlstra
` (10 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_irq1.patch --]
[-- Type: text/plain, Size: 5099 bytes --]
In order to unify them, take some arguments away
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 60 ++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 16 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2001,12 +2001,38 @@ static int reclaim_verbose(struct lock_c
#define STRICT_READ_CHECKS 1
+static const char *state_names[] = {
+#define LOCKDEP_STATE(__STATE) \
+ STR(__STATE),
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+};
+
+static inline const char *state_name(enum lock_usage_bit bit)
+{
+ return state_names[bit >> 2];
+}
+
+static const char *state_rnames[] = {
+#define LOCKDEP_STATE(__STATE) \
+ STR(__STATE)"-READ",
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+};
+
+static inline const char *state_rname(enum lock_usage_bit bit)
+{
+ return state_rnames[bit >> 2];
+}
+
static int
mark_lock_irq_used_in(struct task_struct *curr, struct held_lock *this,
int new_bit, int excl_bit,
- const char *name, const char *rname,
int (*verbose)(struct lock_class *class))
{
+ const char *name = state_name(new_bit);
+ const char *rname = state_rname(new_bit);
+
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
if (!valid_state(curr, this, new_bit, excl_bit + 1))
@@ -2034,9 +2060,11 @@ mark_lock_irq_used_in(struct task_struct
static int
mark_lock_irq_used_in_read(struct task_struct *curr, struct held_lock *this,
int new_bit, int excl_bit,
- const char *name, const char *rname,
int (*verbose)(struct lock_class *class))
{
+ const char *name = state_name(new_bit);
+ const char *rname = state_rname(new_bit);
+
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
/*
@@ -2054,9 +2082,11 @@ mark_lock_irq_used_in_read(struct task_s
static int
mark_lock_irq_enabled(struct task_struct *curr, struct held_lock *this,
int new_bit, int excl_bit,
- const char *name, const char *rname,
int (*verbose)(struct lock_class *class))
{
+ const char *name = state_name(new_bit);
+ const char *rname = state_rname(new_bit);
+
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
if (!valid_state(curr, this, new_bit, excl_bit + 1))
@@ -2085,9 +2115,11 @@ mark_lock_irq_enabled(struct task_struct
static int
mark_lock_irq_enabled_read(struct task_struct *curr, struct held_lock *this,
int new_bit, int excl_bit,
- const char *name, const char *rname,
int (*verbose)(struct lock_class *class))
{
+ const char *name = state_name(new_bit);
+ const char *rname = state_rname(new_bit);
+
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
#if STRICT_READ_CHECKS
@@ -2113,57 +2145,53 @@ static int mark_lock_irq(struct task_str
case LOCK_USED_IN_HARDIRQ:
return mark_lock_irq_used_in(curr, this, new_bit,
LOCK_ENABLED_HARDIRQ,
- "hard", "hard-read", hardirq_verbose);
+ hardirq_verbose);
case LOCK_USED_IN_SOFTIRQ:
return mark_lock_irq_used_in(curr, this, new_bit,
LOCK_ENABLED_SOFTIRQ,
- "soft", "soft-read", softirq_verbose);
+ softirq_verbose);
case LOCK_USED_IN_RECLAIM_FS:
return mark_lock_irq_used_in(curr, this, new_bit,
LOCK_ENABLED_RECLAIM_FS,
- "reclaim-fs", "reclaim-fs-read",
reclaim_verbose);
case LOCK_USED_IN_HARDIRQ_READ:
return mark_lock_irq_used_in_read(curr, this, new_bit,
LOCK_ENABLED_HARDIRQ,
- "hard", "hard-read", hardirq_verbose);
+ hardirq_verbose);
case LOCK_USED_IN_SOFTIRQ_READ:
return mark_lock_irq_used_in_read(curr, this, new_bit,
LOCK_ENABLED_SOFTIRQ,
- "soft", "soft-read", softirq_verbose);
+ softirq_verbose);
case LOCK_USED_IN_RECLAIM_FS_READ:
return mark_lock_irq_used_in_read(curr, this, new_bit,
LOCK_ENABLED_RECLAIM_FS,
- "reclaim-fs", "reclaim-fs-read",
reclaim_verbose);
case LOCK_ENABLED_HARDIRQ:
return mark_lock_irq_enabled(curr, this, new_bit,
LOCK_USED_IN_HARDIRQ,
- "hard", "hard-read", hardirq_verbose);
+ hardirq_verbose);
case LOCK_ENABLED_SOFTIRQ:
return mark_lock_irq_enabled(curr, this, new_bit,
LOCK_USED_IN_SOFTIRQ,
- "soft", "soft-read", softirq_verbose);
+ softirq_verbose);
case LOCK_ENABLED_RECLAIM_FS:
return mark_lock_irq_enabled(curr, this, new_bit,
LOCK_USED_IN_RECLAIM_FS,
- "reclaim-fs", "reclaim-fs-read",
reclaim_verbose);
case LOCK_ENABLED_HARDIRQ_READ:
return mark_lock_irq_enabled_read(curr, this, new_bit,
LOCK_USED_IN_HARDIRQ,
- "hard", "hard-read", hardirq_verbose);
+ hardirq_verbose);
case LOCK_ENABLED_SOFTIRQ_READ:
return mark_lock_irq_enabled_read(curr, this, new_bit,
LOCK_USED_IN_SOFTIRQ,
- "soft", "soft-read", softirq_verbose);
+ softirq_verbose);
case LOCK_ENABLED_RECLAIM_FS_READ:
return mark_lock_irq_enabled_read(curr, this, new_bit,
LOCK_USED_IN_RECLAIM_FS,
- "reclaim-fs", "reclaim-fs-read",
reclaim_verbose);
default:
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 12/21] lockdep: further simplify mark_lock_irq() helpers
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (10 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 11/21] lockdep: simplify the mark_lock_irq() helpers Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 13/21] lockdep: simplify mark_lock_irq() helpers #3 Peter Zijlstra
` (9 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_irq2.patch --]
[-- Type: text/plain, Size: 4451 bytes --]
take away another parameter
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 47 +++++++++++++++++++++++++++++++----------------
1 file changed, 31 insertions(+), 16 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2025,14 +2025,35 @@ static inline const char *state_rname(en
return state_rnames[bit >> 2];
}
+static int exclusive_bit(int new_bit)
+{
+ /*
+ * USED_IN
+ * USED_IN_READ
+ * ENABLED
+ * ENABLED_READ
+ *
+ * bit 0 - write/read
+ * bit 1 - used_in/enabled
+ * bit 2+ state
+ */
+
+ int state = new_bit & ~3;
+ int dir = new_bit & 2;
+
+ return state | (dir ^ 2);
+}
+
static int
mark_lock_irq_used_in(struct task_struct *curr, struct held_lock *this,
- int new_bit, int excl_bit,
+ int new_bit,
int (*verbose)(struct lock_class *class))
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
+ int excl_bit = exclusive_bit(new_bit);
+
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
if (!valid_state(curr, this, new_bit, excl_bit + 1))
@@ -2059,12 +2080,14 @@ mark_lock_irq_used_in(struct task_struct
static int
mark_lock_irq_used_in_read(struct task_struct *curr, struct held_lock *this,
- int new_bit, int excl_bit,
+ int new_bit,
int (*verbose)(struct lock_class *class))
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
+ int excl_bit = exclusive_bit(new_bit);
+
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
/*
@@ -2081,12 +2104,14 @@ mark_lock_irq_used_in_read(struct task_s
static int
mark_lock_irq_enabled(struct task_struct *curr, struct held_lock *this,
- int new_bit, int excl_bit,
+ int new_bit,
int (*verbose)(struct lock_class *class))
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
+ int excl_bit = exclusive_bit(new_bit);
+
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
if (!valid_state(curr, this, new_bit, excl_bit + 1))
@@ -2114,12 +2139,14 @@ mark_lock_irq_enabled(struct task_struct
static int
mark_lock_irq_enabled_read(struct task_struct *curr, struct held_lock *this,
- int new_bit, int excl_bit,
+ int new_bit,
int (*verbose)(struct lock_class *class))
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
+ int excl_bit = exclusive_bit(new_bit);
+
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
#if STRICT_READ_CHECKS
@@ -2144,54 +2171,42 @@ static int mark_lock_irq(struct task_str
switch(new_bit) {
case LOCK_USED_IN_HARDIRQ:
return mark_lock_irq_used_in(curr, this, new_bit,
- LOCK_ENABLED_HARDIRQ,
hardirq_verbose);
case LOCK_USED_IN_SOFTIRQ:
return mark_lock_irq_used_in(curr, this, new_bit,
- LOCK_ENABLED_SOFTIRQ,
softirq_verbose);
case LOCK_USED_IN_RECLAIM_FS:
return mark_lock_irq_used_in(curr, this, new_bit,
- LOCK_ENABLED_RECLAIM_FS,
reclaim_verbose);
case LOCK_USED_IN_HARDIRQ_READ:
return mark_lock_irq_used_in_read(curr, this, new_bit,
- LOCK_ENABLED_HARDIRQ,
hardirq_verbose);
case LOCK_USED_IN_SOFTIRQ_READ:
return mark_lock_irq_used_in_read(curr, this, new_bit,
- LOCK_ENABLED_SOFTIRQ,
softirq_verbose);
case LOCK_USED_IN_RECLAIM_FS_READ:
return mark_lock_irq_used_in_read(curr, this, new_bit,
- LOCK_ENABLED_RECLAIM_FS,
reclaim_verbose);
case LOCK_ENABLED_HARDIRQ:
return mark_lock_irq_enabled(curr, this, new_bit,
- LOCK_USED_IN_HARDIRQ,
hardirq_verbose);
case LOCK_ENABLED_SOFTIRQ:
return mark_lock_irq_enabled(curr, this, new_bit,
- LOCK_USED_IN_SOFTIRQ,
softirq_verbose);
case LOCK_ENABLED_RECLAIM_FS:
return mark_lock_irq_enabled(curr, this, new_bit,
- LOCK_USED_IN_RECLAIM_FS,
reclaim_verbose);
case LOCK_ENABLED_HARDIRQ_READ:
return mark_lock_irq_enabled_read(curr, this, new_bit,
- LOCK_USED_IN_HARDIRQ,
hardirq_verbose);
case LOCK_ENABLED_SOFTIRQ_READ:
return mark_lock_irq_enabled_read(curr, this, new_bit,
- LOCK_USED_IN_SOFTIRQ,
softirq_verbose);
case LOCK_ENABLED_RECLAIM_FS_READ:
return mark_lock_irq_enabled_read(curr, this, new_bit,
- LOCK_USED_IN_RECLAIM_FS,
reclaim_verbose);
default:
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 13/21] lockdep: simplify mark_lock_irq() helpers #3
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (11 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 12/21] lockdep: further simplify " Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 14/21] lockdep: merge the _READ mark_lock_irq() helpers Peter Zijlstra
` (8 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_irq3.patch --]
[-- Type: text/plain, Size: 5385 bytes --]
Kill another argument
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 65 ++++++++++++++++++++++---------------------------------
1 file changed, 27 insertions(+), 38 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -1975,7 +1975,7 @@ void print_irqtrace_events(struct task_s
print_ip_sym(curr->softirq_disable_ip);
}
-static int hardirq_verbose(struct lock_class *class)
+static int HARDIRQ_verbose(struct lock_class *class)
{
#if HARDIRQ_VERBOSE
return class_filter(class);
@@ -1983,7 +1983,7 @@ static int hardirq_verbose(struct lock_c
return 0;
}
-static int softirq_verbose(struct lock_class *class)
+static int SOFTIRQ_verbose(struct lock_class *class)
{
#if SOFTIRQ_VERBOSE
return class_filter(class);
@@ -1991,7 +1991,7 @@ static int softirq_verbose(struct lock_c
return 0;
}
-static int reclaim_verbose(struct lock_class *class)
+static int RECLAIM_FS_verbose(struct lock_class *class)
{
#if RECLAIM_VERBOSE
return class_filter(class);
@@ -2025,6 +2025,19 @@ static inline const char *state_rname(en
return state_rnames[bit >> 2];
}
+static int (*state_verbose_f[])(struct lock_class *class) = {
+#define LOCKDEP_STATE(__STATE) \
+ __STATE##_verbose,
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+};
+
+static inline int state_verbose(enum lock_usage_bit bit,
+ struct lock_class *class)
+{
+ return state_verbose_f[bit >> 2](class);
+}
+
static int exclusive_bit(int new_bit)
{
/*
@@ -2046,8 +2059,7 @@ static int exclusive_bit(int new_bit)
static int
mark_lock_irq_used_in(struct task_struct *curr, struct held_lock *this,
- int new_bit,
- int (*verbose)(struct lock_class *class))
+ int new_bit)
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
@@ -2072,7 +2084,7 @@ mark_lock_irq_used_in(struct task_struct
if (!check_usage_forwards(curr, this, excl_bit + 1, rname))
return 0;
#endif
- if (verbose(hlock_class(this)))
+ if (state_verbose(new_bit, hlock_class(this)))
return 2;
return 1;
@@ -2080,8 +2092,7 @@ mark_lock_irq_used_in(struct task_struct
static int
mark_lock_irq_used_in_read(struct task_struct *curr, struct held_lock *this,
- int new_bit,
- int (*verbose)(struct lock_class *class))
+ int new_bit)
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
@@ -2096,7 +2107,7 @@ mark_lock_irq_used_in_read(struct task_s
*/
if (!check_usage_forwards(curr, this, excl_bit, name))
return 0;
- if (verbose(hlock_class(this)))
+ if (state_verbose(new_bit, hlock_class(this)))
return 2;
return 1;
@@ -2104,8 +2115,7 @@ mark_lock_irq_used_in_read(struct task_s
static int
mark_lock_irq_enabled(struct task_struct *curr, struct held_lock *this,
- int new_bit,
- int (*verbose)(struct lock_class *class))
+ int new_bit)
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
@@ -2131,7 +2141,7 @@ mark_lock_irq_enabled(struct task_struct
if (!check_usage_backwards(curr, this, excl_bit + 1, rname))
return 0;
#endif
- if (verbose(hlock_class(this)))
+ if (state_verbose(new_bit, hlock_class(this)))
return 2;
return 1;
@@ -2139,8 +2149,7 @@ mark_lock_irq_enabled(struct task_struct
static int
mark_lock_irq_enabled_read(struct task_struct *curr, struct held_lock *this,
- int new_bit,
- int (*verbose)(struct lock_class *class))
+ int new_bit)
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
@@ -2170,44 +2179,24 @@ static int mark_lock_irq(struct task_str
switch(new_bit) {
case LOCK_USED_IN_HARDIRQ:
- return mark_lock_irq_used_in(curr, this, new_bit,
- hardirq_verbose);
case LOCK_USED_IN_SOFTIRQ:
- return mark_lock_irq_used_in(curr, this, new_bit,
- softirq_verbose);
case LOCK_USED_IN_RECLAIM_FS:
- return mark_lock_irq_used_in(curr, this, new_bit,
- reclaim_verbose);
+ return mark_lock_irq_used_in(curr, this, new_bit);
case LOCK_USED_IN_HARDIRQ_READ:
- return mark_lock_irq_used_in_read(curr, this, new_bit,
- hardirq_verbose);
case LOCK_USED_IN_SOFTIRQ_READ:
- return mark_lock_irq_used_in_read(curr, this, new_bit,
- softirq_verbose);
case LOCK_USED_IN_RECLAIM_FS_READ:
- return mark_lock_irq_used_in_read(curr, this, new_bit,
- reclaim_verbose);
+ return mark_lock_irq_used_in_read(curr, this, new_bit);
case LOCK_ENABLED_HARDIRQ:
- return mark_lock_irq_enabled(curr, this, new_bit,
- hardirq_verbose);
case LOCK_ENABLED_SOFTIRQ:
- return mark_lock_irq_enabled(curr, this, new_bit,
- softirq_verbose);
case LOCK_ENABLED_RECLAIM_FS:
- return mark_lock_irq_enabled(curr, this, new_bit,
- reclaim_verbose);
+ return mark_lock_irq_enabled(curr, this, new_bit);
case LOCK_ENABLED_HARDIRQ_READ:
- return mark_lock_irq_enabled_read(curr, this, new_bit,
- hardirq_verbose);
case LOCK_ENABLED_SOFTIRQ_READ:
- return mark_lock_irq_enabled_read(curr, this, new_bit,
- softirq_verbose);
case LOCK_ENABLED_RECLAIM_FS_READ:
- return mark_lock_irq_enabled_read(curr, this, new_bit,
- reclaim_verbose);
+ return mark_lock_irq_enabled_read(curr, this, new_bit);
default:
WARN_ON(1);
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 14/21] lockdep: merge the _READ mark_lock_irq() helpers
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (12 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 13/21] lockdep: simplify mark_lock_irq() helpers #3 Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 15/21] lockdep: merge the !_READ " Peter Zijlstra
` (7 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_irq4.patch --]
[-- Type: text/plain, Size: 3139 bytes --]
The _READ helpers show remarkable similarity, merge them.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 61 ++++++++++++++++++++-----------------------------------
1 file changed, 23 insertions(+), 38 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2091,22 +2091,34 @@ mark_lock_irq_used_in(struct task_struct
}
static int
-mark_lock_irq_used_in_read(struct task_struct *curr, struct held_lock *this,
+mark_lock_irq_read(struct task_struct *curr, struct held_lock *this,
int new_bit)
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
int excl_bit = exclusive_bit(new_bit);
+ int dir = new_bit & 2;
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
- /*
- * just marked it hardirq-read-safe, check that this lock
- * took no hardirq-unsafe lock in the past:
- */
- if (!check_usage_forwards(curr, this, excl_bit, name))
- return 0;
+
+ if (!dir) {
+ /*
+ * just marked it hardirq-read-safe, check that this lock
+ * took no hardirq-unsafe lock in the past:
+ */
+ if (!check_usage_forwards(curr, this, excl_bit, name))
+ return 0;
+ } else if (STRICT_READ_CHECKS) {
+ /*
+ * just marked it hardirq-read-unsafe, check that no
+ * hardirq-safe lock in the system ever took it in the past:
+ */
+ if (!check_usage_backwards(curr, this, excl_bit, name))
+ return 0;
+ }
+
if (state_verbose(new_bit, hlock_class(this)))
return 2;
@@ -2147,31 +2159,6 @@ mark_lock_irq_enabled(struct task_struct
return 1;
}
-static int
-mark_lock_irq_enabled_read(struct task_struct *curr, struct held_lock *this,
- int new_bit)
-{
- const char *name = state_name(new_bit);
- const char *rname = state_rname(new_bit);
-
- int excl_bit = exclusive_bit(new_bit);
-
- if (!valid_state(curr, this, new_bit, excl_bit))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it hardirq-read-unsafe, check that no
- * hardirq-safe lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this, excl_bit, name))
- return 0;
-#endif
- if (verbose(hlock_class(this)))
- return 2;
-
- return 1;
-}
-
static int mark_lock_irq(struct task_struct *curr, struct held_lock *this,
enum lock_usage_bit new_bit)
{
@@ -2186,18 +2173,16 @@ static int mark_lock_irq(struct task_str
case LOCK_USED_IN_HARDIRQ_READ:
case LOCK_USED_IN_SOFTIRQ_READ:
case LOCK_USED_IN_RECLAIM_FS_READ:
- return mark_lock_irq_used_in_read(curr, this, new_bit);
+ case LOCK_ENABLED_HARDIRQ_READ:
+ case LOCK_ENABLED_SOFTIRQ_READ:
+ case LOCK_ENABLED_RECLAIM_FS_READ:
+ return mark_lock_irq_read(curr, this, new_bit);
case LOCK_ENABLED_HARDIRQ:
case LOCK_ENABLED_SOFTIRQ:
case LOCK_ENABLED_RECLAIM_FS:
return mark_lock_irq_enabled(curr, this, new_bit);
- case LOCK_ENABLED_HARDIRQ_READ:
- case LOCK_ENABLED_SOFTIRQ_READ:
- case LOCK_ENABLED_RECLAIM_FS_READ:
- return mark_lock_irq_enabled_read(curr, this, new_bit);
-
default:
WARN_ON(1);
break;
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 15/21] lockdep: merge the !_READ mark_lock_irq() helpers
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (13 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 14/21] lockdep: merge the _READ mark_lock_irq() helpers Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 16/21] lockdep: fully reduce mark_lock_irq() Peter Zijlstra
` (6 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_irq5.patch --]
[-- Type: text/plain, Size: 3562 bytes --]
These two are also remakably similar
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 58 ++++++++++++++-----------------------------------------
1 file changed, 15 insertions(+), 43 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2057,31 +2057,39 @@ static int exclusive_bit(int new_bit)
return state | (dir ^ 2);
}
+typedef int (*check_usage_f)(struct task_struct *, struct held_lock *,
+ enum lock_usage_bit bit, const char *name);
+
static int
-mark_lock_irq_used_in(struct task_struct *curr, struct held_lock *this,
+mark_lock_irq_write(struct task_struct *curr, struct held_lock *this,
int new_bit)
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
int excl_bit = exclusive_bit(new_bit);
+ int dir = new_bit & 2;
+
+ check_usage_f usage = dir ?
+ check_usage_backwards : check_usage_forwards;
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
if (!valid_state(curr, this, new_bit, excl_bit + 1))
return 0;
+
/*
* just marked it hardirq-safe, check that this lock
* took no hardirq-unsafe lock in the past:
*/
- if (!check_usage_forwards(curr, this, excl_bit, name))
+ if (!usage(curr, this, excl_bit, name))
return 0;
#if STRICT_READ_CHECKS
/*
* just marked it hardirq-safe, check that this lock
* took no hardirq-unsafe-read lock in the past:
*/
- if (!check_usage_forwards(curr, this, excl_bit + 1, rname))
+ if (!usage(curr, this, excl_bit + 1, rname))
return 0;
#endif
if (state_verbose(new_bit, hlock_class(this)))
@@ -2125,40 +2133,6 @@ mark_lock_irq_read(struct task_struct *c
return 1;
}
-static int
-mark_lock_irq_enabled(struct task_struct *curr, struct held_lock *this,
- int new_bit)
-{
- const char *name = state_name(new_bit);
- const char *rname = state_rname(new_bit);
-
- int excl_bit = exclusive_bit(new_bit);
-
- if (!valid_state(curr, this, new_bit, excl_bit))
- return 0;
- if (!valid_state(curr, this, new_bit, excl_bit + 1))
- return 0;
- /*
- * just marked it hardirq-unsafe, check that no hardirq-safe
- * lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this, excl_bit, name))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it hardirq-unsafe, check that no
- * hardirq-safe-read lock in the system ever took
- * it in the past:
- */
- if (!check_usage_backwards(curr, this, excl_bit + 1, rname))
- return 0;
-#endif
- if (state_verbose(new_bit, hlock_class(this)))
- return 2;
-
- return 1;
-}
-
static int mark_lock_irq(struct task_struct *curr, struct held_lock *this,
enum lock_usage_bit new_bit)
{
@@ -2168,7 +2142,10 @@ static int mark_lock_irq(struct task_str
case LOCK_USED_IN_HARDIRQ:
case LOCK_USED_IN_SOFTIRQ:
case LOCK_USED_IN_RECLAIM_FS:
- return mark_lock_irq_used_in(curr, this, new_bit);
+ case LOCK_ENABLED_HARDIRQ:
+ case LOCK_ENABLED_SOFTIRQ:
+ case LOCK_ENABLED_RECLAIM_FS:
+ return mark_lock_irq_write(curr, this, new_bit);
case LOCK_USED_IN_HARDIRQ_READ:
case LOCK_USED_IN_SOFTIRQ_READ:
@@ -2178,11 +2155,6 @@ static int mark_lock_irq(struct task_str
case LOCK_ENABLED_RECLAIM_FS_READ:
return mark_lock_irq_read(curr, this, new_bit);
- case LOCK_ENABLED_HARDIRQ:
- case LOCK_ENABLED_SOFTIRQ:
- case LOCK_ENABLED_RECLAIM_FS:
- return mark_lock_irq_enabled(curr, this, new_bit);
-
default:
WARN_ON(1);
break;
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 16/21] lockdep: fully reduce mark_lock_irq()
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (14 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 15/21] lockdep: merge the !_READ " Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 17/21] lockdep: remove macro usage from mark_held_locks() Peter Zijlstra
` (5 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_irq6.patch --]
[-- Type: text/plain, Size: 3576 bytes --]
Now what its only two functions, they again look rather similar.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 86 +++++--------------------------------------------------
1 file changed, 8 insertions(+), 78 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2061,13 +2061,13 @@ typedef int (*check_usage_f)(struct task
enum lock_usage_bit bit, const char *name);
static int
-mark_lock_irq_write(struct task_struct *curr, struct held_lock *this,
- int new_bit)
+mark_lock_irq(struct task_struct *curr, struct held_lock *this, int new_bit)
{
const char *name = state_name(new_bit);
const char *rname = state_rname(new_bit);
int excl_bit = exclusive_bit(new_bit);
+ int read = new_bit & 1;
int dir = new_bit & 2;
check_usage_f usage = dir ?
@@ -2075,57 +2075,17 @@ mark_lock_irq_write(struct task_struct *
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
- if (!valid_state(curr, this, new_bit, excl_bit + 1))
- return 0;
- /*
- * just marked it hardirq-safe, check that this lock
- * took no hardirq-unsafe lock in the past:
- */
- if (!usage(curr, this, excl_bit, name))
- return 0;
-#if STRICT_READ_CHECKS
- /*
- * just marked it hardirq-safe, check that this lock
- * took no hardirq-unsafe-read lock in the past:
- */
- if (!usage(curr, this, excl_bit + 1, rname))
+ if (!read && !valid_state(curr, this, new_bit, excl_bit + 1))
return 0;
-#endif
- if (state_verbose(new_bit, hlock_class(this)))
- return 2;
- return 1;
-}
-
-static int
-mark_lock_irq_read(struct task_struct *curr, struct held_lock *this,
- int new_bit)
-{
- const char *name = state_name(new_bit);
- const char *rname = state_rname(new_bit);
-
- int excl_bit = exclusive_bit(new_bit);
- int dir = new_bit & 2;
-
- if (!valid_state(curr, this, new_bit, excl_bit))
+ if ((!read || (!dir || STRICT_READ_CHECKS)) &&
+ !usage(curr, this, excl_bit, name))
return 0;
- if (!dir) {
- /*
- * just marked it hardirq-read-safe, check that this lock
- * took no hardirq-unsafe lock in the past:
- */
- if (!check_usage_forwards(curr, this, excl_bit, name))
- return 0;
- } else if (STRICT_READ_CHECKS) {
- /*
- * just marked it hardirq-read-unsafe, check that no
- * hardirq-safe lock in the system ever took it in the past:
- */
- if (!check_usage_backwards(curr, this, excl_bit, name))
- return 0;
- }
+ if ((!read && STRICT_READ_CHECKS) &&
+ !usage(curr, this, excl_bit + 1, rname))
+ return 0;
if (state_verbose(new_bit, hlock_class(this)))
return 2;
@@ -2133,36 +2093,6 @@ mark_lock_irq_read(struct task_struct *c
return 1;
}
-static int mark_lock_irq(struct task_struct *curr, struct held_lock *this,
- enum lock_usage_bit new_bit)
-{
- int ret = 1;
-
- switch(new_bit) {
- case LOCK_USED_IN_HARDIRQ:
- case LOCK_USED_IN_SOFTIRQ:
- case LOCK_USED_IN_RECLAIM_FS:
- case LOCK_ENABLED_HARDIRQ:
- case LOCK_ENABLED_SOFTIRQ:
- case LOCK_ENABLED_RECLAIM_FS:
- return mark_lock_irq_write(curr, this, new_bit);
-
- case LOCK_USED_IN_HARDIRQ_READ:
- case LOCK_USED_IN_SOFTIRQ_READ:
- case LOCK_USED_IN_RECLAIM_FS_READ:
- case LOCK_ENABLED_HARDIRQ_READ:
- case LOCK_ENABLED_SOFTIRQ_READ:
- case LOCK_ENABLED_RECLAIM_FS_READ:
- return mark_lock_irq_read(curr, this, new_bit);
-
- default:
- WARN_ON(1);
- break;
- }
-
- return ret;
-}
-
enum mark_type {
#define LOCKDEP_STATE(__STATE) __STATE,
#include "lockdep_states.h"
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 17/21] lockdep: remove macro usage from mark_held_locks()
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (15 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 16/21] lockdep: fully reduce mark_lock_irq() Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 18/21] lockdep: add comments to mark_lock_irq() Peter Zijlstra
` (4 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_held_locks.patch --]
[-- Type: text/plain, Size: 1245 bytes --]
Now that we have nice numerical relations for the states, remove the macro
magics.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2099,14 +2099,6 @@ enum mark_type {
#undef LOCKDEP_STATE
};
-#define MARK_HELD_CASE(__STATE) \
- case __STATE: \
- if (hlock->read) \
- usage_bit = LOCK_ENABLED_##__STATE##_READ; \
- else \
- usage_bit = LOCK_ENABLED_##__STATE; \
- break;
-
/*
* Mark all held locks with a usage bit:
*/
@@ -2120,13 +2112,11 @@ mark_held_locks(struct task_struct *curr
for (i = 0; i < curr->lockdep_depth; i++) {
hlock = curr->held_locks + i;
- switch (mark) {
-#define LOCKDEP_STATE(__STATE) MARK_HELD_CASE(__STATE)
-#include "lockdep_states.h"
-#undef LOCKDEP_STATE
- default:
- BUG();
- }
+ usage_bit = 2 + (mark << 2); /* ENABLED */
+ if (hlock->read)
+ usage_bit += 1; /* READ */
+
+ BUG_ON(usage_bit >= LOCK_USAGE_STATES);
if (!mark_lock(curr, hlock, usage_bit))
return 0;
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 18/21] lockdep: add comments to mark_lock_irq()
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (16 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 17/21] lockdep: remove macro usage from mark_held_locks() Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 19/21] lockdep: simplify get_user_chars() Peter Zijlstra
` (3 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-mark_irq7.patch --]
[-- Type: text/plain, Size: 1991 bytes --]
re-add some of the comments that got lost in the refactoring.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 37 ++++++++++++++++++++++++++++++-------
1 file changed, 30 insertions(+), 7 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -2054,6 +2054,9 @@ static int exclusive_bit(int new_bit)
int state = new_bit & ~3;
int dir = new_bit & 2;
+ /*
+ * keep state, bit flip the direction and strip read.
+ */
return state | (dir ^ 2);
}
@@ -2070,22 +2073,42 @@ mark_lock_irq(struct task_struct *curr,
int read = new_bit & 1;
int dir = new_bit & 2;
+ /*
+ * mark USED_IN has to look forwards -- to ensure no dependency
+ * has ENABLED state, which would allow recursion deadlocks.
+ *
+ * mark ENABLED has to look backwards -- to ensure no dependee
+ * has USED_IN state, which, again, would allow recursion deadlocks.
+ */
check_usage_f usage = dir ?
check_usage_backwards : check_usage_forwards;
+ /*
+ * Validate that this particular lock does not have conflicting
+ * usage states.
+ */
if (!valid_state(curr, this, new_bit, excl_bit))
return 0;
- if (!read && !valid_state(curr, this, new_bit, excl_bit + 1))
- return 0;
-
- if ((!read || (!dir || STRICT_READ_CHECKS)) &&
+ /*
+ * Validate that the lock dependencies don't have conflicting usage
+ * states.
+ */
+ if ((!read || !dir || STRICT_READ_CHECKS) &&
!usage(curr, this, excl_bit, name))
return 0;
- if ((!read && STRICT_READ_CHECKS) &&
- !usage(curr, this, excl_bit + 1, rname))
- return 0;
+ /*
+ * Check for read in write conflicts
+ */
+ if (!read) {
+ if (!valid_state(curr, this, new_bit, excl_bit + 1))
+ return 0;
+
+ if (STRICT_READ_CHECKS &&
+ !usage(curr, this, excl_bit + 1, rname))
+ return 0;
+ }
if (state_verbose(new_bit, hlock_class(this)))
return 2;
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 19/21] lockdep: simplify get_user_chars()
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (17 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 18/21] lockdep: add comments to mark_lock_irq() Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 20/21] lockdep: get_user_chars() redo Peter Zijlstra
` (2 subsequent siblings)
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-get_usage_chars.patch --]
[-- Type: text/plain, Size: 2691 bytes --]
there's too much repetition of code..
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 65 ++++++++++++++++++++-----------------------------------
1 file changed, 24 insertions(+), 41 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -467,54 +467,37 @@ const char * __get_key_name(struct lockd
return kallsyms_lookup((unsigned long)key, NULL, NULL, NULL, str);
}
-void
-get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
- char *c4, char *c5, char *c6)
+static inline unsigned long lock_flag(enum lock_usage_bit bit)
{
- *c1 = '.', *c2 = '.', *c3 = '.', *c4 = '.', *c5 = '.', *c6 = '.';
-
- if (class->usage_mask & LOCKF_USED_IN_HARDIRQ)
- *c1 = '+';
- else
- if (class->usage_mask & LOCKF_ENABLED_HARDIRQ)
- *c1 = '-';
+ return 1UL << bit;
+}
- if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ)
- *c2 = '+';
- else
- if (class->usage_mask & LOCKF_ENABLED_SOFTIRQ)
- *c2 = '-';
+static char get_usage_char(struct lock_class *class, enum lock_usage_bit bit)
+{
+ char c = '.';
- if (class->usage_mask & LOCKF_ENABLED_HARDIRQ_READ)
- *c3 = '-';
- if (class->usage_mask & LOCKF_USED_IN_HARDIRQ_READ) {
- *c3 = '+';
- if (class->usage_mask & LOCKF_ENABLED_HARDIRQ_READ)
- *c3 = '?';
- }
-
- if (class->usage_mask & LOCKF_ENABLED_SOFTIRQ_READ)
- *c4 = '-';
- if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ_READ) {
- *c4 = '+';
- if (class->usage_mask & LOCKF_ENABLED_SOFTIRQ_READ)
- *c4 = '?';
+ if (class->usage_mask & lock_flag(bit + 2))
+ c = '+';
+ if (class->usage_mask & lock_flag(bit)) {
+ c = '-';
+ if (class->usage_mask & lock_flag(bit + 2))
+ c = '?';
}
- if (class->usage_mask & LOCKF_USED_IN_RECLAIM_FS)
- *c5 = '+';
- else
- if (class->usage_mask & LOCKF_ENABLED_RECLAIM_FS)
- *c5 = '-';
+ return c;
+}
- if (class->usage_mask & LOCKF_ENABLED_RECLAIM_FS_READ)
- *c6 = '-';
- if (class->usage_mask & LOCKF_USED_IN_RECLAIM_FS_READ) {
- *c6 = '+';
- if (class->usage_mask & LOCKF_ENABLED_RECLAIM_FS_READ)
- *c6 = '?';
- }
+void
+get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
+ char *c4, char *c5, char *c6)
+{
+ *c1 = get_usage_char(class, LOCK_USED_IN_HARDIRQ);
+ *c2 = get_usage_char(class, LOCK_USED_IN_SOFTITQ);
+ *c3 = get_usage_char(class, LOCK_USED_IN_HARDIRQ_READ);
+ *c4 = get_usage_char(class, LOCK_USED_IN_SOFTITQ_READ);
+ *c5 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS);
+ *c6 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS_READ);
}
static void print_lock_name(struct lock_class *class)
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 20/21] lockdep: get_user_chars() redo
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (18 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 19/21] lockdep: simplify get_user_chars() Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-28 13:54 ` [PATCH 21/21] lockdep: simplify check_prev_add_irq() Peter Zijlstra
2009-01-29 13:54 ` [PATCH 22/21] lockdep: use stringify.h Peter Zijlstra
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-get_usage_chars2.patch --]
[-- Type: text/plain, Size: 5758 bytes --]
Generic, states independent, get_user_chars().
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
Documentation/lockdep-design.txt | 30 +++++++++++++++++-------------
kernel/lockdep.c | 26 +++++++++++++-------------
kernel/lockdep_internals.h | 7 ++++---
kernel/lockdep_proc.c | 6 +++---
4 files changed, 37 insertions(+), 32 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -487,25 +487,25 @@ static char get_usage_char(struct lock_c
return c;
}
-void
-get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
- char *c4, char *c5, char *c6)
-{
- *c1 = get_usage_char(class, LOCK_USED_IN_HARDIRQ);
- *c2 = get_usage_char(class, LOCK_USED_IN_SOFTITQ);
- *c3 = get_usage_char(class, LOCK_USED_IN_HARDIRQ_READ);
- *c4 = get_usage_char(class, LOCK_USED_IN_SOFTITQ_READ);
+void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS])
+{
+ int i = 0;
+
+#define LOCKDEP_STATE(__STATE) \
+ usage[i++] = get_usage_char(class, LOCK_USED_IN_##__STATE); \
+ usage[i++] = get_usage_char(class, LOCK_USED_IN_##__STATE##_READ);
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
- *c5 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS);
- *c6 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS_READ);
+ usage[i] = '\0';
}
static void print_lock_name(struct lock_class *class)
{
- char str[KSYM_NAME_LEN], c1, c2, c3, c4, c5, c6;
+ char str[KSYM_NAME_LEN], usage[LOCK_USAGE_CHARS];
const char *name;
- get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6);
+ get_usage_chars(class, usage);
name = class->name;
if (!name) {
@@ -518,7 +518,7 @@ static void print_lock_name(struct lock_
if (class->subclass)
printk("/%d", class->subclass);
}
- printk("){%c%c%c%c%c%c}", c1, c2, c3, c4, c5, c6);
+ printk("){%s}", usage);
}
static void print_lockdep_cache(struct lockdep_map *lock)
Index: linux-2.6/kernel/lockdep_internals.h
===================================================================
--- linux-2.6.orig/kernel/lockdep_internals.h
+++ linux-2.6/kernel/lockdep_internals.h
@@ -70,9 +70,10 @@ enum {
extern struct list_head all_lock_classes;
extern struct lock_chain lock_chains[];
-extern void
-get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
- char *c4, char *c5, char *c6);
+#define LOCK_USAGE_CHARS (1+LOCK_USAGE_STATES/2)
+
+extern void get_usage_chars(struct lock_class *class,
+ char usage[LOCK_USAGE_CHARS]);
extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str);
Index: linux-2.6/kernel/lockdep_proc.c
===================================================================
--- linux-2.6.orig/kernel/lockdep_proc.c
+++ linux-2.6/kernel/lockdep_proc.c
@@ -84,7 +84,7 @@ static int l_show(struct seq_file *m, vo
{
struct lock_class *class = v;
struct lock_list *entry;
- char c1, c2, c3, c4, c5, c6;
+ char usage[LOCK_USAGE_CHARS];
if (v == SEQ_START_TOKEN) {
seq_printf(m, "all lock classes:\n");
@@ -100,8 +100,8 @@ static int l_show(struct seq_file *m, vo
seq_printf(m, " BD:%5ld", lockdep_count_backward_deps(class));
#endif
- get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6);
- seq_printf(m, " %c%c%c%c%c%c", c1, c2, c3, c4, c5, c6);
+ get_usage_chars(class, usage);
+ seq_printf(m, " %s", usage);
seq_printf(m, ": ");
print_name(m, class);
Index: linux-2.6/Documentation/lockdep-design.txt
===================================================================
--- linux-2.6.orig/Documentation/lockdep-design.txt
+++ linux-2.6/Documentation/lockdep-design.txt
@@ -27,33 +27,37 @@ lock-class.
State
-----
-The validator tracks lock-class usage history into 5 separate state bits:
+The validator tracks lock-class usage history into 4n + 1 separate state bits:
-- 'ever held in hardirq context' [ == hardirq-safe ]
-- 'ever held in softirq context' [ == softirq-safe ]
-- 'ever held with hardirqs enabled' [ == hardirq-unsafe ]
-- 'ever held with softirqs and hardirqs enabled' [ == softirq-unsafe ]
+- 'ever held in STATE context'
+- 'ever head as readlock in STATE context'
+- 'ever head with STATE enabled'
+- 'ever head as readlock with STATE enabled'
+
+Where STATE can be either one of (kernel/lockdep_states.h)
+ - hardirq
+ - softirq
+ - reclaim_fs
- 'ever used' [ == !unused ]
-When locking rules are violated, these 4 state bits are presented in the
-locking error messages, inside curlies. A contrived example:
+When locking rules are violated, these state bits are presented in the
+locking error messages, inside curlies. A contrived example:
modprobe/2287 is trying to acquire lock:
- (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
+ (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
but task is already holding lock:
- (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
+ (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
-The bit position indicates hardirq, softirq, hardirq-read,
-softirq-read respectively, and the character displayed in each
-indicates:
+The bit position indicates STATE, STATE-read, for each of the states listed
+above, and the character displayed in each indicates:
'.' acquired while irqs disabled
'+' acquired in irq context
'-' acquired with irqs enabled
- '?' read acquired in irq context with irqs enabled.
+ '?' acquired in irq context with irqs enabled.
Unused mutexes cannot be part of the cause of an error.
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 21/21] lockdep: simplify check_prev_add_irq()
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (19 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 20/21] lockdep: get_user_chars() redo Peter Zijlstra
@ 2009-01-28 13:54 ` Peter Zijlstra
2009-01-29 13:54 ` [PATCH 22/21] lockdep: use stringify.h Peter Zijlstra
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-28 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Peter Zijlstra
[-- Attachment #1: lockdep-check_prev_add_irq.patch --]
[-- Type: text/plain, Size: 6561 bytes --]
Remove the manual state iteration thingy.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/lockdep.c | 154 +++++++++++++++++++++----------------------------------
1 file changed, 61 insertions(+), 93 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -1268,68 +1268,84 @@ check_usage(struct task_struct *curr, st
bit_backwards, bit_forwards, irqclass);
}
-static int
-check_prev_add_irq(struct task_struct *curr, struct held_lock *prev,
- struct held_lock *next)
+static const char *state_names[] = {
+#define LOCKDEP_STATE(__STATE) \
+ STR(__STATE),
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+};
+
+static const char *state_rnames[] = {
+#define LOCKDEP_STATE(__STATE) \
+ STR(__STATE)"-READ",
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+};
+
+static inline const char *state_name(enum lock_usage_bit bit)
{
- /*
- * Prove that the new dependency does not connect a hardirq-safe
- * lock with a hardirq-unsafe lock - to achieve this we search
- * the backwards-subgraph starting at <prev>, and the
- * forwards-subgraph starting at <next>:
- */
- if (!check_usage(curr, prev, next, LOCK_USED_IN_HARDIRQ,
- LOCK_ENABLED_HARDIRQ, "hard"))
- return 0;
+ return (bit & 1) ? state_rnames[bit >> 2] : state_names[bit >> 2];
+}
+static int exclusive_bit(int new_bit)
+{
/*
- * Prove that the new dependency does not connect a hardirq-safe-read
- * lock with a hardirq-unsafe lock - to achieve this we search
- * the backwards-subgraph starting at <prev>, and the
- * forwards-subgraph starting at <next>:
+ * USED_IN
+ * USED_IN_READ
+ * ENABLED
+ * ENABLED_READ
+ *
+ * bit 0 - write/read
+ * bit 1 - used_in/enabled
+ * bit 2+ state
*/
- if (!check_usage(curr, prev, next, LOCK_USED_IN_HARDIRQ_READ,
- LOCK_ENABLED_HARDIRQ, "hard-read"))
- return 0;
+
+ int state = new_bit & ~3;
+ int dir = new_bit & 2;
/*
- * Prove that the new dependency does not connect a softirq-safe
- * lock with a softirq-unsafe lock - to achieve this we search
- * the backwards-subgraph starting at <prev>, and the
- * forwards-subgraph starting at <next>:
+ * keep state, bit flip the direction and strip read.
*/
- if (!check_usage(curr, prev, next, LOCK_USED_IN_SOFTIRQ,
- LOCK_ENABLED_SOFTIRQ, "soft"))
- return 0;
+ return state | (dir ^ 2);
+}
+
+static int check_irq_usage(struct task_struct *curr, struct held_lock *prev,
+ struct held_lock *next, enum lock_usage_bit bit)
+{
/*
- * Prove that the new dependency does not connect a softirq-safe-read
- * lock with a softirq-unsafe lock - to achieve this we search
+ * Prove that the new dependency does not connect a hardirq-safe
+ * lock with a hardirq-unsafe lock - to achieve this we search
* the backwards-subgraph starting at <prev>, and the
* forwards-subgraph starting at <next>:
*/
- if (!check_usage(curr, prev, next, LOCK_USED_IN_SOFTIRQ_READ,
- LOCK_ENABLED_SOFTIRQ, "soft"))
+ if (!check_usage(curr, prev, next, bit,
+ exclusive_bit(bit), state_name(bit)))
return 0;
+ bit++; /* _READ */
+
/*
- * Prove that the new dependency does not connect a reclaim-fs-safe
- * lock with a reclaim-fs-unsafe lock - to achieve this we search
+ * Prove that the new dependency does not connect a hardirq-safe-read
+ * lock with a hardirq-unsafe lock - to achieve this we search
* the backwards-subgraph starting at <prev>, and the
* forwards-subgraph starting at <next>:
*/
- if (!check_usage(curr, prev, next, LOCK_USED_IN_RECLAIM_FS,
- LOCK_ENABLED_RECLAIM_FS, "reclaim-fs"))
+ if (!check_usage(curr, prev, next, bit,
+ exclusive_bit(bit), state_name(bit)))
return 0;
- /*
- * Prove that the new dependency does not connect a reclaim-fs-safe-read
- * lock with a reclaim-fs-unsafe lock - to achieve this we search
- * the backwards-subgraph starting at <prev>, and the
- * forwards-subgraph starting at <next>:
- */
- if (!check_usage(curr, prev, next, LOCK_USED_IN_RECLAIM_FS_READ,
- LOCK_ENABLED_RECLAIM_FS, "reclaim-fs-read"))
+ return 1;
+}
+
+static int
+check_prev_add_irq(struct task_struct *curr, struct held_lock *prev,
+ struct held_lock *next)
+{
+#define LOCKDEP_STATE(__STATE) \
+ if (!check_irq_usage(curr, prev, next, LOCK_USED_IN_##__STATE)) \
return 0;
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
return 1;
}
@@ -1984,30 +2000,6 @@ static int RECLAIM_FS_verbose(struct loc
#define STRICT_READ_CHECKS 1
-static const char *state_names[] = {
-#define LOCKDEP_STATE(__STATE) \
- STR(__STATE),
-#include "lockdep_states.h"
-#undef LOCKDEP_STATE
-};
-
-static inline const char *state_name(enum lock_usage_bit bit)
-{
- return state_names[bit >> 2];
-}
-
-static const char *state_rnames[] = {
-#define LOCKDEP_STATE(__STATE) \
- STR(__STATE)"-READ",
-#include "lockdep_states.h"
-#undef LOCKDEP_STATE
-};
-
-static inline const char *state_rname(enum lock_usage_bit bit)
-{
- return state_rnames[bit >> 2];
-}
-
static int (*state_verbose_f[])(struct lock_class *class) = {
#define LOCKDEP_STATE(__STATE) \
__STATE##_verbose,
@@ -2021,37 +2013,12 @@ static inline int state_verbose(enum loc
return state_verbose_f[bit >> 2](class);
}
-static int exclusive_bit(int new_bit)
-{
- /*
- * USED_IN
- * USED_IN_READ
- * ENABLED
- * ENABLED_READ
- *
- * bit 0 - write/read
- * bit 1 - used_in/enabled
- * bit 2+ state
- */
-
- int state = new_bit & ~3;
- int dir = new_bit & 2;
-
- /*
- * keep state, bit flip the direction and strip read.
- */
- return state | (dir ^ 2);
-}
-
typedef int (*check_usage_f)(struct task_struct *, struct held_lock *,
enum lock_usage_bit bit, const char *name);
static int
mark_lock_irq(struct task_struct *curr, struct held_lock *this, int new_bit)
{
- const char *name = state_name(new_bit);
- const char *rname = state_rname(new_bit);
-
int excl_bit = exclusive_bit(new_bit);
int read = new_bit & 1;
int dir = new_bit & 2;
@@ -2078,7 +2045,7 @@ mark_lock_irq(struct task_struct *curr,
* states.
*/
if ((!read || !dir || STRICT_READ_CHECKS) &&
- !usage(curr, this, excl_bit, name))
+ !usage(curr, this, excl_bit, state_name(new_bit)))
return 0;
/*
@@ -2089,7 +2056,8 @@ mark_lock_irq(struct task_struct *curr,
return 0;
if (STRICT_READ_CHECKS &&
- !usage(curr, this, excl_bit + 1, rname))
+ !usage(curr, this, excl_bit + 1,
+ state_name(new_bit + 1)))
return 0;
}
--
^ permalink raw reply [flat|nested] 38+ messages in thread* [PATCH 22/21] lockdep: use stringify.h
2009-01-28 13:53 [PATCH 00/21] lockdep: pending queue Peter Zijlstra
` (20 preceding siblings ...)
2009-01-28 13:54 ` [PATCH 21/21] lockdep: simplify check_prev_add_irq() Peter Zijlstra
@ 2009-01-29 13:54 ` Peter Zijlstra
21 siblings, 0 replies; 38+ messages in thread
From: Peter Zijlstra @ 2009-01-29 13:54 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, npiggin, Arnd Bergmann
Subject: lockdep: use stringify.h
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Thu Jan 29 14:50:36 CET 2009
Arnd pointed out we have the stringify macro magic already in-kernel.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
CC: Arnd Bergmann <arnd@arndb.de>
---
kernel/lockdep.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
Index: linux-2.6/kernel/lockdep.c
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -41,6 +41,7 @@
#include <linux/utsname.h>
#include <linux/hash.h>
#include <linux/ftrace.h>
+#include <linux/stringify.h>
#include <asm/sections.h>
@@ -445,14 +446,11 @@ atomic_t nr_find_usage_backwards_recursi
* Locking printouts:
*/
-#define __STR(foo) #foo
-#define STR(foo) __STR(foo)
-
#define __USAGE(__STATE) \
- [LOCK_USED_IN_##__STATE] = "IN-"STR(__STATE)"-W", \
- [LOCK_ENABLED_##__STATE] = STR(__STATE)"-ON-W", \
- [LOCK_USED_IN_##__STATE##_READ] = "IN-"STR(__STATE)"-R", \
- [LOCK_ENABLED_##__STATE##_READ] = STR(__STATE)"-ON-R",
+ [LOCK_USED_IN_##__STATE] = "IN-"__stringify(__STATE)"-W", \
+ [LOCK_ENABLED_##__STATE] = __stringify(__STATE)"-ON-W", \
+ [LOCK_USED_IN_##__STATE##_READ] = "IN-"__stringify(__STATE)"-R",\
+ [LOCK_ENABLED_##__STATE##_READ] = __stringify(__STATE)"-ON-R",
static const char *usage_str[] =
{
@@ -1270,14 +1268,14 @@ check_usage(struct task_struct *curr, st
static const char *state_names[] = {
#define LOCKDEP_STATE(__STATE) \
- STR(__STATE),
+ __stringify(__STATE),
#include "lockdep_states.h"
#undef LOCKDEP_STATE
};
static const char *state_rnames[] = {
#define LOCKDEP_STATE(__STATE) \
- STR(__STATE)"-READ",
+ __stringify(__STATE)"-READ",
#include "lockdep_states.h"
#undef LOCKDEP_STATE
};
^ permalink raw reply [flat|nested] 38+ messages in thread