Pull locking updates from Ingo Molnar: - improve rwsem scalability - add uninitialized rwsem debugging check - reduce lockdep's stacktrace memory usage and add diagnostics - misc cleanups, code consolidation and constification * 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: mutex: Fix up mutex_waiter usage locking/mutex: Use mutex flags macro instead of hard code locking/mutex: Make __mutex_owner static to mutex.c locking/qspinlock,x86: Clarify virt_spin_lock_key locking/rwsem: Check for operations on an uninitialized rwsem locking/rwsem: Make handoff writer optimistically spin on owner locking/lockdep: Report more stack trace statistics locking/lockdep: Reduce space occupied by stack traces stacktrace: Constify 'entries' arguments locking/lockdep: Make it clear that what lock_class::key points at is not modified
Showing the changes to include/linux (4 of 11 files). Show all
Unified · Split
| @@ -66,10 +66,7 @@ struct lock_class_key { · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | extern struct lock_class_key __lockdep_no_validate__; |
| 68 | 68 | |
| 69 | −struct lock_trace { | |
| 70 | − unsigned int nr_entries; | |
| 71 | − unsigned int offset; | |
| 72 | −}; | |
| 69 | +struct lock_trace; | |
| 73 | 70 | |
| 74 | 71 | #define LOCKSTAT_POINTS 4 |
| 75 | 72 | |
| @@ -97,7 +94,7 @@ struct lock_class { · 21 unmodified lines | ||
| 97 | 94 | */ |
| 98 | 95 | struct list_head locks_after, locks_before; |
| 99 | 96 | |
| 100 | − struct lockdep_subclass_key *key; | |
| 97 | + const struct lockdep_subclass_key *key; | |
| 101 | 98 | unsigned int subclass; |
| 102 | 99 | unsigned int dep_gen_id; |
| 103 | 100 | |
| @@ -105,7 +102,7 @@ struct lock_class { · 1 unmodified line | ||
| 105 | 102 | * IRQ/softirq usage tracking bits: |
| 106 | 103 | */ |
| 107 | 104 | unsigned long usage_mask; |
| 108 | − struct lock_trace usage_traces[XXX_LOCK_USAGE_STATES]; | |
| 105 | + const struct lock_trace *usage_traces[XXX_LOCK_USAGE_STATES]; | |
| 109 | 106 | |
| 110 | 107 | /* |
| 111 | 108 | * Generation counter, when doing certain classes of graph walking, |
| @@ -193,7 +190,7 @@ struct lock_list { · 81 unmodified lines | ||
| 193 | 190 | struct list_head entry; |
| 194 | 191 | struct lock_class *class; |
| 195 | 192 | struct lock_class *links_to; |
| 196 | − struct lock_trace trace; | |
| 193 | + const struct lock_trace *trace; | |
| 197 | 194 | int distance; |
| 198 | 195 | |
| 199 | 196 | /* |
| @@ -65,16 +65,6 @@ struct mutex { · 64 unmodified lines | ||
| 65 | 65 | #endif |
| 66 | 66 | }; |
| 67 | 67 | |
| 68 | −/* | |
| 69 | − * Internal helper function; C doesn't allow us to hide it :/ | |
| 70 | − * | |
| 71 | − * DO NOT USE (outside of mutex code). | |
| 72 | − */ | |
| 73 | −static inline struct task_struct *__mutex_owner(struct mutex *lock) | |
| 74 | −{ | |
| 75 | − return (struct task_struct *)(atomic_long_read(&lock->owner) & ~0x07); | |
| 76 | −} | |
| 77 | − | |
| 78 | 68 | /* |
| 79 | 69 | * This is the control structure for tasks blocked on mutex, |
| 80 | 70 | * which resides on the blocked task's kernel stack: |
| @@ -144,10 +134,7 @@ extern void __mutex_init(struct mutex *lock, const char *name, · 63 unmodified lines | ||
| 144 | 134 | * |
| 145 | 135 | * Returns true if the mutex is locked, false if unlocked. |
| 146 | 136 | */ |
| 147 | −static inline bool mutex_is_locked(struct mutex *lock) | |
| 148 | −{ | |
| 149 | − return __mutex_owner(lock) != NULL; | |
| 150 | −} | |
| 137 | +extern bool mutex_is_locked(struct mutex *lock); | |
| 151 | 138 | |
| 152 | 139 | /* |
| 153 | 140 | * See kernel/locking/mutex.c for detailed documentation of these APIs. |
| @@ -220,13 +207,7 @@ enum mutex_trylock_recursive_enum { · 66 unmodified lines | ||
| 220 | 207 | * - MUTEX_TRYLOCK_SUCCESS - lock acquired, |
| 221 | 208 | * - MUTEX_TRYLOCK_RECURSIVE - we already owned the lock. |
| 222 | 209 | */ |
| 223 | −static inline /* __deprecated */ __must_check enum mutex_trylock_recursive_enum | |
| 224 | −mutex_trylock_recursive(struct mutex *lock) | |
| 225 | −{ | |
| 226 | − if (unlikely(__mutex_owner(lock) == current)) | |
| 227 | − return MUTEX_TRYLOCK_RECURSIVE; | |
| 228 | − | |
| 229 | − return mutex_trylock(lock); | |
| 230 | −} | |
| 210 | +extern /* __deprecated */ __must_check enum mutex_trylock_recursive_enum | |
| 211 | +mutex_trylock_recursive(struct mutex *lock); | |
| 231 | 212 | |
| 232 | 213 | #endif /* __LINUX_MUTEX_H */ |
| @@ -45,6 +45,9 @@ struct rw_semaphore { · 44 unmodified lines | ||
| 45 | 45 | #endif |
| 46 | 46 | raw_spinlock_t wait_lock; |
| 47 | 47 | struct list_head wait_list; |
| 48 | +#ifdef CONFIG_DEBUG_RWSEMS | |
| 49 | + void *magic; | |
| 50 | +#endif | |
| 48 | 51 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 49 | 52 | struct lockdep_map dep_map; |
| 50 | 53 | #endif |
| @@ -73,6 +76,12 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem) · 22 unmodified lines | ||
| 73 | 76 | # define __RWSEM_DEP_MAP_INIT(lockname) |
| 74 | 77 | #endif |
| 75 | 78 | |
| 79 | +#ifdef CONFIG_DEBUG_RWSEMS | |
| 80 | +# define __DEBUG_RWSEM_INITIALIZER(lockname) , .magic = &lockname | |
| 81 | +#else | |
| 82 | +# define __DEBUG_RWSEM_INITIALIZER(lockname) | |
| 83 | +#endif | |
| 84 | + | |
| 76 | 85 | #ifdef CONFIG_RWSEM_SPIN_ON_OWNER |
| 77 | 86 | #define __RWSEM_OPT_INIT(lockname) , .osq = OSQ_LOCK_UNLOCKED |
| 78 | 87 | #else |
| @@ -85,6 +94,7 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem) · 6 unmodified lines | ||
| 85 | 94 | .wait_list = LIST_HEAD_INIT((name).wait_list), \ |
| 86 | 95 | .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) \ |
| 87 | 96 | __RWSEM_OPT_INIT(name) \ |
| 97 | + __DEBUG_RWSEM_INITIALIZER(name) \ | |
| 88 | 98 | __RWSEM_DEP_MAP_INIT(name) } |
| 89 | 99 | |
| 90 | 100 | #define DECLARE_RWSEM(name) \ |
| @@ -9,9 +9,9 @@ struct task_struct; · 8 unmodified lines | ||
| 9 | 9 | struct pt_regs; |
| 10 | 10 | |
| 11 | 11 | #ifdef CONFIG_STACKTRACE |
| 12 | −void stack_trace_print(unsigned long *trace, unsigned int nr_entries, | |
| 12 | +void stack_trace_print(const unsigned long *trace, unsigned int nr_entries, | |
| 13 | 13 | int spaces); |
| 14 | −int stack_trace_snprint(char *buf, size_t size, unsigned long *entries, | |
| 14 | +int stack_trace_snprint(char *buf, size_t size, const unsigned long *entries, | |
| 15 | 15 | unsigned int nr_entries, int spaces); |
| 16 | 16 | unsigned int stack_trace_save(unsigned long *store, unsigned int size, |
| 17 | 17 | unsigned int skipnr); |