* [PATCH 1/2] lockdep: lockdep_set_class_and_subclass
2006-09-26 11:31 [PATCH 0/2] serio lockdep annotation Peter Zijlstra
@ 2006-09-26 11:31 ` Peter Zijlstra
2006-09-26 11:54 ` Ingo Molnar
2006-09-26 11:31 ` [PATCH 2/2] serio: lockdep annotation for ps2dev->cmd_mutex and serio->lock Peter Zijlstra
1 sibling, 1 reply; 8+ messages in thread
From: Peter Zijlstra @ 2006-09-26 11:31 UTC (permalink / raw)
To: Dmitry Torokhov, linux-kernel
Cc: Jiri Kosina, Andrew Morton, Arjan van de Ven, Dave Jones,
Ingo Molnar, Peter Zijlstra
[-- Attachment #1: lockdep-init-subclass.patch --]
[-- Type: text/plain, Size: 7699 bytes --]
Add lockdep_set_class_and_subclass() to the lockdep annotations.
This annotation makes it possible to assign a subclass on lock init. This
annotation is meant to reduce the _nested() annotations by assigning a
default subclass.
One could do without this annotation and rely on lockdep_set_class()
exclusively, but that would require a manual stack of struct lock_class_key
objects.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/lockdep.h | 12 ++++++++----
kernel/lockdep.c | 10 ++++++----
kernel/mutex-debug.c | 2 +-
lib/rwsem-spinlock.c | 2 +-
lib/rwsem.c | 2 +-
lib/spinlock_debug.c | 4 ++--
net/core/sock.c | 2 +-
7 files changed, 20 insertions(+), 14 deletions(-)
Index: linux-2.6-mm/include/linux/lockdep.h
===================================================================
--- linux-2.6-mm.orig/include/linux/lockdep.h 2006-09-26 11:05:29.000000000 +0200
+++ linux-2.6-mm/include/linux/lockdep.h 2006-09-26 13:10:40.000000000 +0200
@@ -202,7 +202,7 @@ extern int lockdep_internal(void);
*/
extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
- struct lock_class_key *key);
+ struct lock_class_key *key, int subclass);
/*
* Reinitialize a lock key - for cases where there is special locking or
@@ -211,9 +211,11 @@ extern void lockdep_init_map(struct lock
* or they are too narrow (they suffer from a false class-split):
*/
#define lockdep_set_class(lock, key) \
- lockdep_init_map(&(lock)->dep_map, #key, key)
+ lockdep_init_map(&(lock)->dep_map, #key, key, 0)
#define lockdep_set_class_and_name(lock, key, name) \
- lockdep_init_map(&(lock)->dep_map, name, key)
+ lockdep_init_map(&(lock)->dep_map, name, key, 0)
+#define lockdep_set_class_and_subclass(lock, key, sub) \
+ lockdep_init_map(&(lock)->dep_map, #key, key, sub)
/*
* Acquire a lock.
@@ -257,10 +259,12 @@ static inline int lockdep_internal(void)
# define lock_release(l, n, i) do { } while (0)
# define lockdep_init() do { } while (0)
# define lockdep_info() do { } while (0)
-# define lockdep_init_map(lock, name, key) do { (void)(key); } while (0)
+# define lockdep_init_map(lock, name, key, sub) do { (void)(key); } while (0)
# define lockdep_set_class(lock, key) do { (void)(key); } while (0)
# define lockdep_set_class_and_name(lock, key, name) \
do { (void)(key); } while (0)
+#define lockdep_set_class_and_subclass(lock, key, sub) \
+ do { (void)(key); } while (0)
# define INIT_LOCKDEP
# define lockdep_reset() do { debug_locks = 1; } while (0)
# define lockdep_free_key_range(start, size) do { } while (0)
Index: linux-2.6-mm/kernel/lockdep.c
===================================================================
--- linux-2.6-mm.orig/kernel/lockdep.c 2006-09-26 11:05:29.000000000 +0200
+++ linux-2.6-mm/kernel/lockdep.c 2006-09-26 13:13:09.000000000 +0200
@@ -1177,7 +1177,7 @@ look_up_lock_class(struct lockdep_map *l
* itself, so actual lookup of the hash should be once per lock object.
*/
static inline struct lock_class *
-register_lock_class(struct lockdep_map *lock, unsigned int subclass)
+register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
{
struct lockdep_subclass_key *key;
struct list_head *hash_head;
@@ -1249,7 +1249,7 @@ register_lock_class(struct lockdep_map *
out_unlock_set:
__raw_spin_unlock(&hash_lock);
- if (!subclass)
+ if (!subclass || force)
lock->class_cache = class;
DEBUG_LOCKS_WARN_ON(class->subclass != subclass);
@@ -1937,7 +1937,7 @@ void trace_softirqs_off(unsigned long ip
* Initialize a lock instance's lock-class mapping info:
*/
void lockdep_init_map(struct lockdep_map *lock, const char *name,
- struct lock_class_key *key)
+ struct lock_class_key *key, int subclass)
{
if (unlikely(!debug_locks))
return;
@@ -1957,6 +1957,8 @@ void lockdep_init_map(struct lockdep_map
lock->name = name;
lock->key = key;
lock->class_cache = NULL;
+ if (subclass)
+ register_lock_class(lock, subclass, 1);
}
EXPORT_SYMBOL_GPL(lockdep_init_map);
@@ -1995,7 +1997,7 @@ static int __lock_acquire(struct lockdep
* Not cached yet or subclass?
*/
if (unlikely(!class)) {
- class = register_lock_class(lock, subclass);
+ class = register_lock_class(lock, subclass, 0);
if (!class)
return 0;
}
Index: linux-2.6-mm/kernel/mutex-debug.c
===================================================================
--- linux-2.6-mm.orig/kernel/mutex-debug.c 2006-09-26 11:05:29.000000000 +0200
+++ linux-2.6-mm/kernel/mutex-debug.c 2006-09-26 13:10:40.000000000 +0200
@@ -91,7 +91,7 @@ void debug_mutex_init(struct mutex *lock
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
- lockdep_init_map(&lock->dep_map, name, key);
+ lockdep_init_map(&lock->dep_map, name, key, 0);
#endif
lock->owner = NULL;
lock->magic = lock;
Index: linux-2.6-mm/lib/rwsem-spinlock.c
===================================================================
--- linux-2.6-mm.orig/lib/rwsem-spinlock.c 2006-09-26 11:05:29.000000000 +0200
+++ linux-2.6-mm/lib/rwsem-spinlock.c 2006-09-26 13:10:40.000000000 +0200
@@ -28,7 +28,7 @@ void __init_rwsem(struct rw_semaphore *s
* Make sure we are not reinitializing a held semaphore:
*/
debug_check_no_locks_freed((void *)sem, sizeof(*sem));
- lockdep_init_map(&sem->dep_map, name, key);
+ lockdep_init_map(&sem->dep_map, name, key, 0);
#endif
sem->activity = 0;
spin_lock_init(&sem->wait_lock);
Index: linux-2.6-mm/lib/rwsem.c
===================================================================
--- linux-2.6-mm.orig/lib/rwsem.c 2006-09-26 11:05:29.000000000 +0200
+++ linux-2.6-mm/lib/rwsem.c 2006-09-26 13:10:40.000000000 +0200
@@ -19,7 +19,7 @@ void __init_rwsem(struct rw_semaphore *s
* Make sure we are not reinitializing a held semaphore:
*/
debug_check_no_locks_freed((void *)sem, sizeof(*sem));
- lockdep_init_map(&sem->dep_map, name, key);
+ lockdep_init_map(&sem->dep_map, name, key, 0);
#endif
sem->count = RWSEM_UNLOCKED_VALUE;
spin_lock_init(&sem->wait_lock);
Index: linux-2.6-mm/lib/spinlock_debug.c
===================================================================
--- linux-2.6-mm.orig/lib/spinlock_debug.c 2006-09-26 11:05:29.000000000 +0200
+++ linux-2.6-mm/lib/spinlock_debug.c 2006-09-26 13:10:40.000000000 +0200
@@ -20,7 +20,7 @@ void __spin_lock_init(spinlock_t *lock,
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
- lockdep_init_map(&lock->dep_map, name, key);
+ lockdep_init_map(&lock->dep_map, name, key, 0);
#endif
lock->raw_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
lock->magic = SPINLOCK_MAGIC;
@@ -38,7 +38,7 @@ void __rwlock_init(rwlock_t *lock, const
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
- lockdep_init_map(&lock->dep_map, name, key);
+ lockdep_init_map(&lock->dep_map, name, key, 0);
#endif
lock->raw_lock = (raw_rwlock_t) __RAW_RW_LOCK_UNLOCKED;
lock->magic = RWLOCK_MAGIC;
Index: linux-2.6-mm/net/core/sock.c
===================================================================
--- linux-2.6-mm.orig/net/core/sock.c 2006-09-26 11:05:29.000000000 +0200
+++ linux-2.6-mm/net/core/sock.c 2006-09-26 13:10:40.000000000 +0200
@@ -823,7 +823,7 @@ static void inline sock_lock_init(struct
af_family_slock_key_strings[sk->sk_family]);
lockdep_init_map(&sk->sk_lock.dep_map,
af_family_key_strings[sk->sk_family],
- af_family_keys + sk->sk_family);
+ af_family_keys + sk->sk_family, 0);
}
/**
--
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 2/2] serio: lockdep annotation for ps2dev->cmd_mutex and serio->lock
2006-09-26 11:31 [PATCH 0/2] serio lockdep annotation Peter Zijlstra
2006-09-26 11:31 ` [PATCH 1/2] lockdep: lockdep_set_class_and_subclass Peter Zijlstra
@ 2006-09-26 11:31 ` Peter Zijlstra
2006-09-26 13:21 ` Jiri Kosina
1 sibling, 1 reply; 8+ messages in thread
From: Peter Zijlstra @ 2006-09-26 11:31 UTC (permalink / raw)
To: Dmitry Torokhov, linux-kernel
Cc: Jiri Kosina, Andrew Morton, Arjan van de Ven, Dave Jones,
Ingo Molnar
[-- Attachment #1: serio-lockdep.patch --]
[-- Type: text/plain, Size: 2749 bytes --]
Based ideas from Jiri Kosina, this patch tracks the nesting depth
and uses the new lockdep_set_class_and_subclass() annotation to store
this information in the lock objects.
Signed-of-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
drivers/input/serio/libps2.c | 4 ++++
drivers/input/serio/serio.c | 9 ++++++++-
include/linux/serio.h | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)
Index: linux-2.6-mm/drivers/input/serio/libps2.c
===================================================================
--- linux-2.6-mm.orig/drivers/input/serio/libps2.c 2006-09-26 10:25:22.000000000 +0200
+++ linux-2.6-mm/drivers/input/serio/libps2.c 2006-09-26 10:34:49.000000000 +0200
@@ -280,6 +280,8 @@ int ps2_schedule_command(struct ps2dev *
return 0;
}
+static struct lock_class_key ps2_mutex_key;
+
/*
* ps2_init() initializes ps2dev structure
*/
@@ -287,6 +289,8 @@ int ps2_schedule_command(struct ps2dev *
void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
{
mutex_init(&ps2dev->cmd_mutex);
+ lockdep_set_class_and_subclass(&ps2dev->cmd_mutex, &ps2_mutex_key,
+ serio->depth);
init_waitqueue_head(&ps2dev->wait);
ps2dev->serio = serio;
}
Index: linux-2.6-mm/drivers/input/serio/serio.c
===================================================================
--- linux-2.6-mm.orig/drivers/input/serio/serio.c 2006-09-26 10:25:22.000000000 +0200
+++ linux-2.6-mm/drivers/input/serio/serio.c 2006-09-26 10:34:04.000000000 +0200
@@ -521,6 +521,8 @@ static void serio_release_port(struct de
module_put(THIS_MODULE);
}
+static struct lock_class_key serio_lock_key;
+
/*
* Prepare serio port for registration.
*/
@@ -538,8 +540,13 @@ static void serio_init_port(struct serio
"serio%ld", (long)atomic_inc_return(&serio_no) - 1);
serio->dev.bus = &serio_bus;
serio->dev.release = serio_release_port;
- if (serio->parent)
+ if (serio->parent) {
serio->dev.parent = &serio->parent->dev;
+ serio->depth = serio->parent->depth + 1;
+ } else
+ serio->depth = 0;
+ lockdep_set_class_and_subclass(&serio->lock, &serio_lock_key,
+ serio->depth);
}
/*
Index: linux-2.6-mm/include/linux/serio.h
===================================================================
--- linux-2.6-mm.orig/include/linux/serio.h 2006-09-26 10:25:22.000000000 +0200
+++ linux-2.6-mm/include/linux/serio.h 2006-09-26 10:34:04.000000000 +0200
@@ -41,6 +41,7 @@ struct serio {
void (*stop)(struct serio *);
struct serio *parent, *child;
+ unsigned int depth; /* level of nesting in serio hierarchy */
struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */
struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */
--
^ permalink raw reply [flat|nested] 8+ messages in thread