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.
Unified · Split
| @@ -18,6 +18,7 @@ typedef struct { · 17 unmodified lines | ||
| 18 | 18 | .dep_map = { \ |
| 19 | 19 | .name = #lockname, \ |
| 20 | 20 | .wait_type_inner = LD_WAIT_CONFIG, \ |
| 21 | + .lock_type = LD_LOCK_PERCPU, \ | |
| 21 | 22 | } |
| 22 | 23 | #else |
| 23 | 24 | # define LL_DEP_MAP_INIT(lockname) |
| @@ -30,7 +31,9 @@ do { \ · 6 unmodified lines | ||
| 30 | 31 | static struct lock_class_key __key; \ |
| 31 | 32 | \ |
| 32 | 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 | 37 | } while (0) |
| 35 | 38 | |
| 36 | 39 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| @@ -185,12 +185,19 @@ extern void lockdep_unregister_key(struct lock_class_key *key); · 184 unmodified lines | ||
| 185 | 185 | * to lockdep: |
| 186 | 186 | */ |
| 187 | 187 | |
| 188 | −extern void lockdep_init_map_waits(struct lockdep_map *lock, const char *name, | |
| 189 | − struct lock_class_key *key, int subclass, short inner, short outer); | |
| 188 | +extern void lockdep_init_map_type(struct lockdep_map *lock, const char *name, | |
| 189 | + struct lock_class_key *key, int subclass, u8 inner, u8 outer, u8 lock_type); | |
| 190 | + | |
| 191 | +static inline void | |
| 192 | +lockdep_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 | |
| 191 | 198 | static inline void |
| 192 | 199 | lockdep_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 | 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 | 347 | # define lock_set_class(l, n, k, s, i) do { } while (0) |
| 341 | 348 | # define lock_set_subclass(l, s, i) do { } while (0) |
| 342 | 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 | 352 | # define lockdep_init_map_waits(lock, name, key, sub, inner, outer) \ |
| 344 | 353 | do { (void)(name); (void)(key); } while (0) |
| 345 | 354 | # define lockdep_init_map_wait(lock, name, key, sub, inner) \ |
| @@ -30,6 +30,12 @@ enum lockdep_wait_type { · 29 unmodified lines | ||
| 30 | 30 | LD_WAIT_MAX, /* must be last */ |
| 31 | 31 | }; |
| 32 | 32 | |
| 33 | +enum lockdep_lock_type { | |
| 34 | + LD_LOCK_NORMAL = 0, /* normal, catch all */ | |
| 35 | + LD_LOCK_PERCPU, /* percpu */ | |
| 36 | + LD_LOCK_MAX, | |
| 37 | +}; | |
| 38 | + | |
| 33 | 39 | #ifdef CONFIG_LOCKDEP |
| 34 | 40 | |
| 35 | 41 | /* |
| @@ -119,8 +125,10 @@ struct lock_class { · 83 unmodified lines | ||
| 119 | 125 | int name_version; |
| 120 | 126 | const char *name; |
| 121 | 127 | |
| 122 | − short wait_type_inner; | |
| 123 | − short wait_type_outer; | |
| 128 | + u8 wait_type_inner; | |
| 129 | + u8 wait_type_outer; | |
| 130 | + u8 lock_type; | |
| 131 | + /* u8 hole; */ | |
| 124 | 132 | |
| 125 | 133 | #ifdef CONFIG_LOCK_STAT |
| 126 | 134 | unsigned long contention_point[LOCKSTAT_POINTS]; |
| @@ -169,8 +177,10 @@ struct lockdep_map { · 42 unmodified lines | ||
| 169 | 177 | struct lock_class_key *key; |
| 170 | 178 | struct lock_class *class_cache[NR_LOCKDEP_CACHING_CLASSES]; |
| 171 | 179 | const char *name; |
| 172 | − short wait_type_outer; /* can be taken in this context */ | |
| 173 | − short wait_type_inner; /* presents this context */ | |
| 180 | + u8 wait_type_outer; /* can be taken in this context */ | |
| 181 | + u8 wait_type_inner; /* presents this context */ | |
| 182 | + u8 lock_type; | |
| 183 | + /* u8 hole; */ | |
| 174 | 184 | #ifdef CONFIG_LOCK_STAT |
| 175 | 185 | int cpu; |
| 176 | 186 | unsigned long ip; |
| @@ -1290,6 +1290,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) · 1289 unmodified lines | ||
| 1290 | 1290 | class->name_version = count_matching_names(class); |
| 1291 | 1291 | class->wait_type_inner = lock->wait_type_inner; |
| 1292 | 1292 | class->wait_type_outer = lock->wait_type_outer; |
| 1293 | + class->lock_type = lock->lock_type; | |
| 1293 | 1294 | /* |
| 1294 | 1295 | * We use RCU's safe list-add method to make |
| 1295 | 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 | */ |
| 4504 | 4505 | static 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 | − short next_outer = hlock_class(next)->wait_type_outer; | |
| 4508 | − short curr_inner; | |
| 4507 | + u8 next_inner = hlock_class(next)->wait_type_inner; | |
| 4508 | + u8 next_outer = hlock_class(next)->wait_type_outer; | |
| 4509 | + u8 curr_inner; | |
| 4509 | 4510 | int depth; |
| 4510 | 4511 | |
| 4511 | 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 | 4530 | for (; depth < curr->lockdep_depth; depth++) { |
| 4530 | 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 | 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 | 4579 | * Initialize a lock instance's lock-class mapping info: |
| 4579 | 4580 | */ |
| 4580 | −void lockdep_init_map_waits(struct lockdep_map *lock, const char *name, | |
| 4581 | +void lockdep_init_map_type(struct lockdep_map *lock, const char *name, | |
| 4581 | 4582 | struct lock_class_key *key, int subclass, |
| 4582 | − short inner, short outer) | |
| 4583 | + u8 inner, u8 outer, u8 lock_type) | |
| 4583 | 4584 | { |
| 4584 | 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 | 4604 | lock->wait_type_outer = outer; |
| 4604 | 4605 | lock->wait_type_inner = inner; |
| 4606 | + lock->lock_type = lock_type; | |
| 4605 | 4607 | |
| 4606 | 4608 | /* |
| 4607 | 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 | 4638 | raw_local_irq_restore(flags); |
| 4637 | 4639 | } |
| 4638 | 4640 | } |
| 4639 | −EXPORT_SYMBOL_GPL(lockdep_init_map_waits); | |
| 4641 | +EXPORT_SYMBOL_GPL(lockdep_init_map_type); | |
| 4640 | 4642 | |
| 4641 | 4643 | struct lock_class_key __lockdep_no_validate__; |
| 4642 | 4644 | EXPORT_SYMBOL_GPL(__lockdep_no_validate__); |