History

locking/lockdep: Mark local_lock_t

The local_lock_t's are special, because they cannot form IRQ inversions, make sure we can tell them apart from the rest of the locks.

Peter Zijlstra committed 5 years ago

Commit dfd5e3f1 parent 5831c0f4 files · +39 −15Browse files

Unified · Split

4 files
  1. include/linux/local_lock_internal.h +4 −1
  2. include/linux/lockdep.h +12 −3
  3. include/linux/lockdep_types.h +14 −4
  4. kernel/locking/lockdep.c +9 −7
include/linux/local_lock_internal.h+4−1
@@ -18,6 +18,7 @@ typedef struct { · 17 unmodified lines
18 .dep_map = { \18 .dep_map = { \
19 .name = #lockname, \19 .name = #lockname, \
20 .wait_type_inner = LD_WAIT_CONFIG, \20 .wait_type_inner = LD_WAIT_CONFIG, \
21 .lock_type = LD_LOCK_PERCPU, \
21 }22 }
22#else23#else
23# define LL_DEP_MAP_INIT(lockname)24# define LL_DEP_MAP_INIT(lockname)
@@ -30,7 +31,9 @@ do { \ · 6 unmodified lines
30 static struct lock_class_key __key; \31 static struct lock_class_key __key; \
31 \32 \
32 debug_check_no_locks_freed((void *)lock, sizeof(*lock));\33 debug_check_no_locks_freed((void *)lock, sizeof(*lock));\
33 lockdep_init_map_wait(&(lock)->dep_map, #lock, &__key, 0, LD_WAIT_CONFIG);\34 lockdep_init_map_type(&(lock)->dep_map, #lock, &__key, 0, \
35 LD_WAIT_CONFIG, LD_WAIT_INV, \
36 LD_LOCK_PERCPU); \
34} while (0)37} while (0)
35 38
36#ifdef CONFIG_DEBUG_LOCK_ALLOC39#ifdef CONFIG_DEBUG_LOCK_ALLOC
include/linux/lockdep.h+12−3
@@ -185,12 +185,19 @@ extern void lockdep_unregister_key(struct lock_class_key *key); · 184 unmodified lines
185 * to lockdep:185 * to lockdep:
186 */186 */
187 187
188extern void lockdep_init_map_waits(struct lockdep_map *lock, const char *name,188extern void lockdep_init_map_type(struct lockdep_map *lock, const char *name,
189 struct lock_class_key *key, int subclass, short inner, short outer);189 struct lock_class_key *key, int subclass, u8 inner, u8 outer, u8 lock_type);
190
191static inline void
192lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
193 struct lock_class_key *key, int subclass, u8 inner, u8 outer)
194{
195 lockdep_init_map_type(lock, name, key, subclass, inner, LD_WAIT_INV, LD_LOCK_NORMAL);
196}
190 197
191static inline void198static inline void
192lockdep_init_map_wait(struct lockdep_map *lock, const char *name,199lockdep_init_map_wait(struct lockdep_map *lock, const char *name,
193 struct lock_class_key *key, int subclass, short inner)200 struct lock_class_key *key, int subclass, u8 inner)
194{201{
195 lockdep_init_map_waits(lock, name, key, subclass, inner, LD_WAIT_INV);202 lockdep_init_map_waits(lock, name, key, subclass, inner, LD_WAIT_INV);
196}203}
@@ -340,6 +347,8 @@ static inline void lockdep_set_selftest_task(struct task_struct *task) · 143 unmodified lines
340# define lock_set_class(l, n, k, s, i) do { } while (0)347# define lock_set_class(l, n, k, s, i) do { } while (0)
341# define lock_set_subclass(l, s, i) do { } while (0)348# define lock_set_subclass(l, s, i) do { } while (0)
342# define lockdep_init() do { } while (0)349# define lockdep_init() do { } while (0)
350# define lockdep_init_map_type(lock, name, key, sub, inner, outer, type) \
351 do { (void)(name); (void)(key); } while (0)
343# define lockdep_init_map_waits(lock, name, key, sub, inner, outer) \352# define lockdep_init_map_waits(lock, name, key, sub, inner, outer) \
344 do { (void)(name); (void)(key); } while (0)353 do { (void)(name); (void)(key); } while (0)
345# define lockdep_init_map_wait(lock, name, key, sub, inner) \354# define lockdep_init_map_wait(lock, name, key, sub, inner) \
include/linux/lockdep_types.h+14−4
@@ -30,6 +30,12 @@ enum lockdep_wait_type { · 29 unmodified lines
30 LD_WAIT_MAX, /* must be last */30 LD_WAIT_MAX, /* must be last */
31};31};
32 32
33enum lockdep_lock_type {
34 LD_LOCK_NORMAL = 0, /* normal, catch all */
35 LD_LOCK_PERCPU, /* percpu */
36 LD_LOCK_MAX,
37};
38
33#ifdef CONFIG_LOCKDEP39#ifdef CONFIG_LOCKDEP
34 40
35/*41/*
@@ -119,8 +125,10 @@ struct lock_class { · 83 unmodified lines
119 int name_version;125 int name_version;
120 const char *name;126 const char *name;
121 127
122 short wait_type_inner;128 u8 wait_type_inner;
123 short wait_type_outer;129 u8 wait_type_outer;
130 u8 lock_type;
131 /* u8 hole; */
124 132
125#ifdef CONFIG_LOCK_STAT133#ifdef CONFIG_LOCK_STAT
126 unsigned long contention_point[LOCKSTAT_POINTS];134 unsigned long contention_point[LOCKSTAT_POINTS];
@@ -169,8 +177,10 @@ struct lockdep_map { · 42 unmodified lines
169 struct lock_class_key *key;177 struct lock_class_key *key;
170 struct lock_class *class_cache[NR_LOCKDEP_CACHING_CLASSES];178 struct lock_class *class_cache[NR_LOCKDEP_CACHING_CLASSES];
171 const char *name;179 const char *name;
172 short wait_type_outer; /* can be taken in this context */180 u8 wait_type_outer; /* can be taken in this context */
173 short wait_type_inner; /* presents this context */181 u8 wait_type_inner; /* presents this context */
182 u8 lock_type;
183 /* u8 hole; */
174#ifdef CONFIG_LOCK_STAT184#ifdef CONFIG_LOCK_STAT
175 int cpu;185 int cpu;
176 unsigned long ip;186 unsigned long ip;
kernel/locking/lockdep.c+9−7
@@ -1290,6 +1290,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) · 1289 unmodified lines
1290 class->name_version = count_matching_names(class);1290 class->name_version = count_matching_names(class);
1291 class->wait_type_inner = lock->wait_type_inner;1291 class->wait_type_inner = lock->wait_type_inner;
1292 class->wait_type_outer = lock->wait_type_outer;1292 class->wait_type_outer = lock->wait_type_outer;
1293 class->lock_type = lock->lock_type;
1293 /*1294 /*
1294 * We use RCU's safe list-add method to make1295 * We use RCU's safe list-add method to make
1295 * parallel walking of the hash-list safe:1296 * parallel walking of the hash-list safe:
@@ -4503,9 +4504,9 @@ print_lock_invalid_wait_context(struct task_struct *curr, · 3207 unmodified lines
4503 */4504 */
4504static int check_wait_context(struct task_struct *curr, struct held_lock *next)4505static int check_wait_context(struct task_struct *curr, struct held_lock *next)
4505{4506{
4506 short next_inner = hlock_class(next)->wait_type_inner;4507 u8 next_inner = hlock_class(next)->wait_type_inner;
4507 short next_outer = hlock_class(next)->wait_type_outer;4508 u8 next_outer = hlock_class(next)->wait_type_outer;
4508 short curr_inner;4509 u8 curr_inner;
4509 int depth;4510 int depth;
4510 4511
4511 if (!curr->lockdep_depth || !next_inner || next->trylock)4512 if (!curr->lockdep_depth || !next_inner || next->trylock)
@@ -4528,7 +4529,7 @@ static int check_wait_context(struct task_struct *curr, struct held_lock *next) · 16 unmodified lines
4528 4529
4529 for (; depth < curr->lockdep_depth; depth++) {4530 for (; depth < curr->lockdep_depth; depth++) {
4530 struct held_lock *prev = curr->held_locks + depth;4531 struct held_lock *prev = curr->held_locks + depth;
4531 short prev_inner = hlock_class(prev)->wait_type_inner;4532 u8 prev_inner = hlock_class(prev)->wait_type_inner;
4532 4533
4533 if (prev_inner) {4534 if (prev_inner) {
4534 /*4535 /*
@@ -4577,9 +4578,9 @@ static inline int check_wait_context(struct task_struct *curr, · 42 unmodified lines
4577/*4578/*
4578 * Initialize a lock instance's lock-class mapping info:4579 * Initialize a lock instance's lock-class mapping info:
4579 */4580 */
4580void lockdep_init_map_waits(struct lockdep_map *lock, const char *name,4581void lockdep_init_map_type(struct lockdep_map *lock, const char *name,
4581 struct lock_class_key *key, int subclass,4582 struct lock_class_key *key, int subclass,
4582 short inner, short outer)4583 u8 inner, u8 outer, u8 lock_type)
4583{4584{
4584 int i;4585 int i;
4585 4586
@@ -4602,6 +4603,7 @@ void lockdep_init_map_waits(struct lockdep_map *lock, const char *name, · 16 unmodified lines
4602 4603
4603 lock->wait_type_outer = outer;4604 lock->wait_type_outer = outer;
4604 lock->wait_type_inner = inner;4605 lock->wait_type_inner = inner;
4606 lock->lock_type = lock_type;
4605 4607
4606 /*4608 /*
4607 * No key, no joy, we need to hash something.4609 * No key, no joy, we need to hash something.
@@ -4636,7 +4638,7 @@ void lockdep_init_map_waits(struct lockdep_map *lock, const char *name, · 28 unmodified lines
4636 raw_local_irq_restore(flags);4638 raw_local_irq_restore(flags);
4637 }4639 }
4638}4640}
4639EXPORT_SYMBOL_GPL(lockdep_init_map_waits);4641EXPORT_SYMBOL_GPL(lockdep_init_map_type);
4640 4642
4641struct lock_class_key __lockdep_no_validate__;4643struct lock_class_key __lockdep_no_validate__;
4642EXPORT_SYMBOL_GPL(__lockdep_no_validate__);4644EXPORT_SYMBOL_GPL(__lockdep_no_validate__);