Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

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

+241 -84
+15
arch/x86/include/asm/qspinlock.h
··· 63 63 #endif 64 64 65 65 #ifdef CONFIG_PARAVIRT 66 + /* 67 + * virt_spin_lock_key - enables (by default) the virt_spin_lock() hijack. 68 + * 69 + * Native (and PV wanting native due to vCPU pinning) should disable this key. 70 + * It is done in this backwards fashion to only have a single direction change, 71 + * which removes ordering between native_pv_spin_init() and HV setup. 72 + */ 66 73 DECLARE_STATIC_KEY_TRUE(virt_spin_lock_key); 67 74 68 75 void native_pv_lock_init(void) __init; 69 76 77 + /* 78 + * Shortcut for the queued_spin_lock_slowpath() function that allows 79 + * virt to hijack it. 80 + * 81 + * Returns: 82 + * true - lock has been negotiated, all done; 83 + * false - queued_spin_lock_slowpath() will do its thing. 84 + */ 70 85 #define virt_spin_lock virt_spin_lock 71 86 static inline bool virt_spin_lock(struct qspinlock *lock) 72 87 {
+4 -7
include/linux/lockdep.h
··· 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 ··· 94 97 */ 95 98 struct list_head locks_after, locks_before; 96 99 97 - struct lockdep_subclass_key *key; 100 + const struct lockdep_subclass_key *key; 98 101 unsigned int subclass; 99 102 unsigned int dep_gen_id; 100 103 ··· 102 105 * IRQ/softirq usage tracking bits: 103 106 */ 104 107 unsigned long usage_mask; 105 - struct lock_trace usage_traces[XXX_LOCK_USAGE_STATES]; 108 + const struct lock_trace *usage_traces[XXX_LOCK_USAGE_STATES]; 106 109 107 110 /* 108 111 * Generation counter, when doing certain classes of graph walking, ··· 190 193 struct list_head entry; 191 194 struct lock_class *class; 192 195 struct lock_class *links_to; 193 - struct lock_trace trace; 196 + const struct lock_trace *trace; 194 197 int distance; 195 198 196 199 /*
+3 -22
include/linux/mutex.h
··· 66 66 }; 67 67 68 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 - /* 79 69 * This is the control structure for tasks blocked on mutex, 80 70 * which resides on the blocked task's kernel stack: 81 71 */ ··· 134 144 * 135 145 * Returns true if the mutex is locked, false if unlocked. 136 146 */ 137 - static inline bool mutex_is_locked(struct mutex *lock) 138 - { 139 - return __mutex_owner(lock) != NULL; 140 - } 147 + extern bool mutex_is_locked(struct mutex *lock); 141 148 142 149 /* 143 150 * See kernel/locking/mutex.c for detailed documentation of these APIs. ··· 207 220 * - MUTEX_TRYLOCK_SUCCESS - lock acquired, 208 221 * - MUTEX_TRYLOCK_RECURSIVE - we already owned the lock. 209 222 */ 210 - static inline /* __deprecated */ __must_check enum mutex_trylock_recursive_enum 211 - mutex_trylock_recursive(struct mutex *lock) 212 - { 213 - if (unlikely(__mutex_owner(lock) == current)) 214 - return MUTEX_TRYLOCK_RECURSIVE; 215 - 216 - return mutex_trylock(lock); 217 - } 223 + extern /* __deprecated */ __must_check enum mutex_trylock_recursive_enum 224 + mutex_trylock_recursive(struct mutex *lock); 218 225 219 226 #endif /* __LINUX_MUTEX_H */
+10
include/linux/rwsem.h
··· 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 ··· 76 73 # define __RWSEM_DEP_MAP_INIT(lockname) 77 74 #endif 78 75 76 + #ifdef CONFIG_DEBUG_RWSEMS 77 + # define __DEBUG_RWSEM_INITIALIZER(lockname) , .magic = &lockname 78 + #else 79 + # define __DEBUG_RWSEM_INITIALIZER(lockname) 80 + #endif 81 + 79 82 #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 80 83 #define __RWSEM_OPT_INIT(lockname) , .osq = OSQ_LOCK_UNLOCKED 81 84 #else ··· 94 85 .wait_list = LIST_HEAD_INIT((name).wait_list), \ 95 86 .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) \ 96 87 __RWSEM_OPT_INIT(name) \ 88 + __DEBUG_RWSEM_INITIALIZER(name) \ 97 89 __RWSEM_DEP_MAP_INIT(name) } 98 90 99 91 #define DECLARE_RWSEM(name) \
+2 -2
include/linux/stacktrace.h
··· 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);
+120 -39
kernel/locking/lockdep.c
··· 449 449 unsigned long nr_stack_trace_entries; 450 450 451 451 #ifdef CONFIG_PROVE_LOCKING 452 + /** 453 + * struct lock_trace - single stack backtrace 454 + * @hash_entry: Entry in a stack_trace_hash[] list. 455 + * @hash: jhash() of @entries. 456 + * @nr_entries: Number of entries in @entries. 457 + * @entries: Actual stack backtrace. 458 + */ 459 + struct lock_trace { 460 + struct hlist_node hash_entry; 461 + u32 hash; 462 + u32 nr_entries; 463 + unsigned long entries[0] __aligned(sizeof(unsigned long)); 464 + }; 465 + #define LOCK_TRACE_SIZE_IN_LONGS \ 466 + (sizeof(struct lock_trace) / sizeof(unsigned long)) 452 467 /* 453 - * Stack-trace: tightly packed array of stack backtrace 454 - * addresses. Protected by the graph_lock. 468 + * Stack-trace: sequence of lock_trace structures. Protected by the graph_lock. 455 469 */ 456 470 static unsigned long stack_trace[MAX_STACK_TRACE_ENTRIES]; 471 + static struct hlist_head stack_trace_hash[STACK_TRACE_HASH_SIZE]; 457 472 458 - static int save_trace(struct lock_trace *trace) 473 + static bool traces_identical(struct lock_trace *t1, struct lock_trace *t2) 459 474 { 460 - unsigned long *entries = stack_trace + nr_stack_trace_entries; 475 + return t1->hash == t2->hash && t1->nr_entries == t2->nr_entries && 476 + memcmp(t1->entries, t2->entries, 477 + t1->nr_entries * sizeof(t1->entries[0])) == 0; 478 + } 479 + 480 + static struct lock_trace *save_trace(void) 481 + { 482 + struct lock_trace *trace, *t2; 483 + struct hlist_head *hash_head; 484 + u32 hash; 461 485 unsigned int max_entries; 462 486 463 - trace->offset = nr_stack_trace_entries; 464 - max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries; 465 - trace->nr_entries = stack_trace_save(entries, max_entries, 3); 466 - nr_stack_trace_entries += trace->nr_entries; 487 + BUILD_BUG_ON_NOT_POWER_OF_2(STACK_TRACE_HASH_SIZE); 488 + BUILD_BUG_ON(LOCK_TRACE_SIZE_IN_LONGS >= MAX_STACK_TRACE_ENTRIES); 467 489 468 - if (nr_stack_trace_entries >= MAX_STACK_TRACE_ENTRIES-1) { 490 + trace = (struct lock_trace *)(stack_trace + nr_stack_trace_entries); 491 + max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries - 492 + LOCK_TRACE_SIZE_IN_LONGS; 493 + trace->nr_entries = stack_trace_save(trace->entries, max_entries, 3); 494 + 495 + if (nr_stack_trace_entries >= MAX_STACK_TRACE_ENTRIES - 496 + LOCK_TRACE_SIZE_IN_LONGS - 1) { 469 497 if (!debug_locks_off_graph_unlock()) 470 - return 0; 498 + return NULL; 471 499 472 500 print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!"); 473 501 dump_stack(); 474 502 475 - return 0; 503 + return NULL; 476 504 } 477 505 478 - return 1; 506 + hash = jhash(trace->entries, trace->nr_entries * 507 + sizeof(trace->entries[0]), 0); 508 + trace->hash = hash; 509 + hash_head = stack_trace_hash + (hash & (STACK_TRACE_HASH_SIZE - 1)); 510 + hlist_for_each_entry(t2, hash_head, hash_entry) { 511 + if (traces_identical(trace, t2)) 512 + return t2; 513 + } 514 + nr_stack_trace_entries += LOCK_TRACE_SIZE_IN_LONGS + trace->nr_entries; 515 + hlist_add_head(&trace->hash_entry, hash_head); 516 + 517 + return trace; 518 + } 519 + 520 + /* Return the number of stack traces in the stack_trace[] array. */ 521 + u64 lockdep_stack_trace_count(void) 522 + { 523 + struct lock_trace *trace; 524 + u64 c = 0; 525 + int i; 526 + 527 + for (i = 0; i < ARRAY_SIZE(stack_trace_hash); i++) { 528 + hlist_for_each_entry(trace, &stack_trace_hash[i], hash_entry) { 529 + c++; 530 + } 531 + } 532 + 533 + return c; 534 + } 535 + 536 + /* Return the number of stack hash chains that have at least one stack trace. */ 537 + u64 lockdep_stack_hash_count(void) 538 + { 539 + u64 c = 0; 540 + int i; 541 + 542 + for (i = 0; i < ARRAY_SIZE(stack_trace_hash); i++) 543 + if (!hlist_empty(&stack_trace_hash[i])) 544 + c++; 545 + 546 + return c; 479 547 } 480 548 #endif 481 549 ··· 579 511 }; 580 512 #endif 581 513 582 - const char * __get_key_name(struct lockdep_subclass_key *key, char *str) 514 + const char *__get_key_name(const struct lockdep_subclass_key *key, char *str) 583 515 { 584 516 return kallsyms_lookup((unsigned long)key, NULL, NULL, NULL, str); 585 517 } ··· 1303 1235 static int add_lock_to_list(struct lock_class *this, 1304 1236 struct lock_class *links_to, struct list_head *head, 1305 1237 unsigned long ip, int distance, 1306 - struct lock_trace *trace) 1238 + const struct lock_trace *trace) 1307 1239 { 1308 1240 struct lock_list *entry; 1309 1241 /* ··· 1317 1249 entry->class = this; 1318 1250 entry->links_to = links_to; 1319 1251 entry->distance = distance; 1320 - entry->trace = *trace; 1252 + entry->trace = trace; 1321 1253 /* 1322 1254 * Both allocation and removal are done under the graph lock; but 1323 1255 * iteration is under RCU-sched; see look_up_lock_class() and ··· 1538 1470 1539 1471 } 1540 1472 1541 - static void print_lock_trace(struct lock_trace *trace, unsigned int spaces) 1473 + static void print_lock_trace(const struct lock_trace *trace, 1474 + unsigned int spaces) 1542 1475 { 1543 - unsigned long *entries = stack_trace + trace->offset; 1544 - 1545 - stack_trace_print(entries, trace->nr_entries, spaces); 1476 + stack_trace_print(trace->entries, trace->nr_entries, spaces); 1546 1477 } 1547 1478 1548 1479 /* ··· 1556 1489 printk("\n-> #%u", depth); 1557 1490 print_lock_name(target->class); 1558 1491 printk(KERN_CONT ":\n"); 1559 - print_lock_trace(&target->trace, 6); 1492 + print_lock_trace(target->trace, 6); 1560 1493 } 1561 1494 1562 1495 static void ··· 1659 1592 if (!debug_locks_off_graph_unlock() || debug_locks_silent) 1660 1593 return; 1661 1594 1662 - if (!save_trace(&this->trace)) 1595 + this->trace = save_trace(); 1596 + if (!this->trace) 1663 1597 return; 1664 1598 1665 1599 depth = get_lock_depth(target); ··· 1783 1715 */ 1784 1716 static noinline int 1785 1717 check_noncircular(struct held_lock *src, struct held_lock *target, 1786 - struct lock_trace *trace) 1718 + struct lock_trace **const trace) 1787 1719 { 1788 1720 int ret; 1789 1721 struct lock_list *uninitialized_var(target_entry); ··· 1797 1729 ret = check_path(hlock_class(target), &src_entry, &target_entry); 1798 1730 1799 1731 if (unlikely(!ret)) { 1800 - if (!trace->nr_entries) { 1732 + if (!*trace) { 1801 1733 /* 1802 1734 * If save_trace fails here, the printing might 1803 1735 * trigger a WARN but because of the !nr_entries it 1804 1736 * should not do bad things. 1805 1737 */ 1806 - save_trace(trace); 1738 + *trace = save_trace(); 1807 1739 } 1808 1740 1809 1741 print_circular_bug(&src_entry, target_entry, src, target); ··· 1927 1859 1928 1860 len += printk("%*s %s", depth, "", usage_str[bit]); 1929 1861 len += printk(KERN_CONT " at:\n"); 1930 - print_lock_trace(class->usage_traces + bit, len); 1862 + print_lock_trace(class->usage_traces[bit], len); 1931 1863 } 1932 1864 } 1933 1865 printk("%*s }\n", depth, ""); ··· 1952 1884 do { 1953 1885 print_lock_class_header(entry->class, depth); 1954 1886 printk("%*s ... acquired at:\n", depth, ""); 1955 - print_lock_trace(&entry->trace, 2); 1887 + print_lock_trace(entry->trace, 2); 1956 1888 printk("\n"); 1957 1889 1958 1890 if (depth == 0 && (entry != root)) { ··· 2063 1995 print_lock_name(backwards_entry->class); 2064 1996 pr_warn("\n... which became %s-irq-safe at:\n", irqclass); 2065 1997 2066 - print_lock_trace(backwards_entry->class->usage_traces + bit1, 1); 1998 + print_lock_trace(backwards_entry->class->usage_traces[bit1], 1); 2067 1999 2068 2000 pr_warn("\nto a %s-irq-unsafe lock:\n", irqclass); 2069 2001 print_lock_name(forwards_entry->class); 2070 2002 pr_warn("\n... which became %s-irq-unsafe at:\n", irqclass); 2071 2003 pr_warn("..."); 2072 2004 2073 - print_lock_trace(forwards_entry->class->usage_traces + bit2, 1); 2005 + print_lock_trace(forwards_entry->class->usage_traces[bit2], 1); 2074 2006 2075 2007 pr_warn("\nother info that might help us debug this:\n\n"); 2076 2008 print_irq_lock_scenario(backwards_entry, forwards_entry, ··· 2079 2011 lockdep_print_held_locks(curr); 2080 2012 2081 2013 pr_warn("\nthe dependencies between %s-irq-safe lock and the holding lock:\n", irqclass); 2082 - if (!save_trace(&prev_root->trace)) 2014 + prev_root->trace = save_trace(); 2015 + if (!prev_root->trace) 2083 2016 return; 2084 2017 print_shortest_lock_dependencies(backwards_entry, prev_root); 2085 2018 2086 2019 pr_warn("\nthe dependencies between the lock to be acquired"); 2087 2020 pr_warn(" and %s-irq-unsafe lock:\n", irqclass); 2088 - if (!save_trace(&next_root->trace)) 2021 + next_root->trace = save_trace(); 2022 + if (!next_root->trace) 2089 2023 return; 2090 2024 print_shortest_lock_dependencies(forwards_entry, next_root); 2091 2025 ··· 2439 2369 */ 2440 2370 static int 2441 2371 check_prev_add(struct task_struct *curr, struct held_lock *prev, 2442 - struct held_lock *next, int distance, struct lock_trace *trace) 2372 + struct held_lock *next, int distance, 2373 + struct lock_trace **const trace) 2443 2374 { 2444 2375 struct lock_list *entry; 2445 2376 int ret; ··· 2515 2444 return ret; 2516 2445 #endif 2517 2446 2518 - if (!trace->nr_entries && !save_trace(trace)) 2519 - return 0; 2447 + if (!*trace) { 2448 + *trace = save_trace(); 2449 + if (!*trace) 2450 + return 0; 2451 + } 2520 2452 2521 2453 /* 2522 2454 * Ok, all validations passed, add the new lock ··· 2527 2453 */ 2528 2454 ret = add_lock_to_list(hlock_class(next), hlock_class(prev), 2529 2455 &hlock_class(prev)->locks_after, 2530 - next->acquire_ip, distance, trace); 2456 + next->acquire_ip, distance, *trace); 2531 2457 2532 2458 if (!ret) 2533 2459 return 0; 2534 2460 2535 2461 ret = add_lock_to_list(hlock_class(prev), hlock_class(next), 2536 2462 &hlock_class(next)->locks_before, 2537 - next->acquire_ip, distance, trace); 2463 + next->acquire_ip, distance, *trace); 2538 2464 if (!ret) 2539 2465 return 0; 2540 2466 ··· 2550 2476 static int 2551 2477 check_prevs_add(struct task_struct *curr, struct held_lock *next) 2552 2478 { 2553 - struct lock_trace trace = { .nr_entries = 0 }; 2479 + struct lock_trace *trace = NULL; 2554 2480 int depth = curr->lockdep_depth; 2555 2481 struct held_lock *hlock; 2556 2482 ··· 3089 3015 print_lock(this); 3090 3016 3091 3017 pr_warn("{%s} state was registered at:\n", usage_str[prev_bit]); 3092 - print_lock_trace(hlock_class(this)->usage_traces + prev_bit, 1); 3018 + print_lock_trace(hlock_class(this)->usage_traces[prev_bit], 1); 3093 3019 3094 3020 print_irqtrace_events(curr); 3095 3021 pr_warn("\nother info that might help us debug this:\n"); ··· 3170 3096 lockdep_print_held_locks(curr); 3171 3097 3172 3098 pr_warn("\nthe shortest dependencies between 2nd lock and 1st lock:\n"); 3173 - if (!save_trace(&root->trace)) 3099 + root->trace = save_trace(); 3100 + if (!root->trace) 3174 3101 return; 3175 3102 print_shortest_lock_dependencies(other, root); 3176 3103 ··· 3655 3580 3656 3581 hlock_class(this)->usage_mask |= new_mask; 3657 3582 3658 - if (!save_trace(hlock_class(this)->usage_traces + new_bit)) 3583 + if (!(hlock_class(this)->usage_traces[new_bit] = save_trace())) 3659 3584 return 0; 3660 3585 3661 3586 switch (new_bit) { ··· 5231 5156 #endif 5232 5157 ) / 1024 5233 5158 ); 5159 + 5160 + #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) 5161 + printk(" memory used for stack traces: %zu kB\n", 5162 + (sizeof(stack_trace) + sizeof(stack_trace_hash)) / 1024 5163 + ); 5164 + #endif 5234 5165 5235 5166 printk(" per task-struct memory footprint: %zu bytes\n", 5236 5167 sizeof(((struct task_struct *)NULL)->held_locks));
+8 -1
kernel/locking/lockdep_internals.h
··· 92 92 #define MAX_LOCKDEP_ENTRIES 16384UL 93 93 #define MAX_LOCKDEP_CHAINS_BITS 15 94 94 #define MAX_STACK_TRACE_ENTRIES 262144UL 95 + #define STACK_TRACE_HASH_SIZE 8192 95 96 #else 96 97 #define MAX_LOCKDEP_ENTRIES 32768UL 97 98 ··· 103 102 * addresses. Protected by the hash_lock. 104 103 */ 105 104 #define MAX_STACK_TRACE_ENTRIES 524288UL 105 + #define STACK_TRACE_HASH_SIZE 16384 106 106 #endif 107 107 108 108 #define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS) ··· 118 116 extern void get_usage_chars(struct lock_class *class, 119 117 char usage[LOCK_USAGE_CHARS]); 120 118 121 - extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str); 119 + extern const char *__get_key_name(const struct lockdep_subclass_key *key, 120 + char *str); 122 121 123 122 struct lock_class *lock_chain_get_class(struct lock_chain *chain, int i); 124 123 ··· 140 137 #ifdef CONFIG_PROVE_LOCKING 141 138 extern unsigned long lockdep_count_forward_deps(struct lock_class *); 142 139 extern unsigned long lockdep_count_backward_deps(struct lock_class *); 140 + #ifdef CONFIG_TRACE_IRQFLAGS 141 + u64 lockdep_stack_trace_count(void); 142 + u64 lockdep_stack_hash_count(void); 143 + #endif 143 144 #else 144 145 static inline unsigned long 145 146 lockdep_count_forward_deps(struct lock_class *class)
+7 -1
kernel/locking/lockdep_proc.c
··· 285 285 nr_process_chains); 286 286 seq_printf(m, " stack-trace entries: %11lu [max: %lu]\n", 287 287 nr_stack_trace_entries, MAX_STACK_TRACE_ENTRIES); 288 + #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) 289 + seq_printf(m, " number of stack traces: %llu\n", 290 + lockdep_stack_trace_count()); 291 + seq_printf(m, " number of stack hash chains: %llu\n", 292 + lockdep_stack_hash_count()); 293 + #endif 288 294 seq_printf(m, " combined max dependencies: %11u\n", 289 295 (nr_hardirq_chains + 1) * 290 296 (nr_softirq_chains + 1) * ··· 405 399 406 400 static void seq_stats(struct seq_file *m, struct lock_stat_data *data) 407 401 { 408 - struct lockdep_subclass_key *ckey; 402 + const struct lockdep_subclass_key *ckey; 409 403 struct lock_class_stats *stats; 410 404 struct lock_class *class; 411 405 const char *cname;
+26
kernel/locking/mutex.c
··· 65 65 66 66 #define MUTEX_FLAGS 0x07 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) & ~MUTEX_FLAGS); 76 + } 77 + 68 78 static inline struct task_struct *__owner_task(unsigned long owner) 69 79 { 70 80 return (struct task_struct *)(owner & ~MUTEX_FLAGS); 71 81 } 82 + 83 + bool mutex_is_locked(struct mutex *lock) 84 + { 85 + return __mutex_owner(lock) != NULL; 86 + } 87 + EXPORT_SYMBOL(mutex_is_locked); 88 + 89 + __must_check enum mutex_trylock_recursive_enum 90 + mutex_trylock_recursive(struct mutex *lock) 91 + { 92 + if (unlikely(__mutex_owner(lock) == current)) 93 + return MUTEX_TRYLOCK_RECURSIVE; 94 + 95 + return mutex_trylock(lock); 96 + } 97 + EXPORT_SYMBOL(mutex_trylock_recursive); 72 98 73 99 static inline unsigned long __owner_flags(unsigned long owner) 74 100 {
+44 -10
kernel/locking/rwsem.c
··· 105 105 #ifdef CONFIG_DEBUG_RWSEMS 106 106 # define DEBUG_RWSEMS_WARN_ON(c, sem) do { \ 107 107 if (!debug_locks_silent && \ 108 - WARN_ONCE(c, "DEBUG_RWSEMS_WARN_ON(%s): count = 0x%lx, owner = 0x%lx, curr 0x%lx, list %sempty\n",\ 108 + WARN_ONCE(c, "DEBUG_RWSEMS_WARN_ON(%s): count = 0x%lx, magic = 0x%lx, owner = 0x%lx, curr 0x%lx, list %sempty\n",\ 109 109 #c, atomic_long_read(&(sem)->count), \ 110 + (unsigned long) sem->magic, \ 110 111 atomic_long_read(&(sem)->owner), (long)current, \ 111 112 list_empty(&(sem)->wait_list) ? "" : "not ")) \ 112 113 debug_locks_off(); \ ··· 330 329 */ 331 330 debug_check_no_locks_freed((void *)sem, sizeof(*sem)); 332 331 lockdep_init_map(&sem->dep_map, name, key, 0); 332 + #endif 333 + #ifdef CONFIG_DEBUG_RWSEMS 334 + sem->magic = sem; 333 335 #endif 334 336 atomic_long_set(&sem->count, RWSEM_UNLOCKED_VALUE); 335 337 raw_spin_lock_init(&sem->wait_lock); ··· 728 724 729 725 rcu_read_lock(); 730 726 for (;;) { 731 - if (atomic_long_read(&sem->count) & RWSEM_FLAG_HANDOFF) { 732 - state = OWNER_NONSPINNABLE; 733 - break; 734 - } 735 - 727 + /* 728 + * When a waiting writer set the handoff flag, it may spin 729 + * on the owner as well. Once that writer acquires the lock, 730 + * we can spin on it. So we don't need to quit even when the 731 + * handoff bit is set. 732 + */ 736 733 new = rwsem_owner_flags(sem, &new_flags); 737 734 if ((new != owner) || (new_flags != flags)) { 738 735 state = rwsem_owner_state(new, new_flags, nonspinnable); ··· 979 974 { 980 975 return false; 981 976 } 977 + 978 + static inline int 979 + rwsem_spin_on_owner(struct rw_semaphore *sem, unsigned long nonspinnable) 980 + { 981 + return 0; 982 + } 983 + #define OWNER_NULL 1 982 984 #endif 983 985 984 986 /* ··· 1218 1206 1219 1207 raw_spin_unlock_irq(&sem->wait_lock); 1220 1208 1209 + /* 1210 + * After setting the handoff bit and failing to acquire 1211 + * the lock, attempt to spin on owner to accelerate lock 1212 + * transfer. If the previous owner is a on-cpu writer and it 1213 + * has just released the lock, OWNER_NULL will be returned. 1214 + * In this case, we attempt to acquire the lock again 1215 + * without sleeping. 1216 + */ 1217 + if ((wstate == WRITER_HANDOFF) && 1218 + (rwsem_spin_on_owner(sem, 0) == OWNER_NULL)) 1219 + goto trylock_again; 1220 + 1221 1221 /* Block until there are no active lockers. */ 1222 1222 for (;;) { 1223 1223 if (signal_pending_state(state, current)) ··· 1264 1240 break; 1265 1241 } 1266 1242 } 1267 - 1243 + trylock_again: 1268 1244 raw_spin_lock_irq(&sem->wait_lock); 1269 1245 } 1270 1246 __set_current_state(TASK_RUNNING); ··· 1362 1338 1363 1339 static inline int __down_read_trylock(struct rw_semaphore *sem) 1364 1340 { 1341 + long tmp; 1342 + 1343 + DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem); 1344 + 1365 1345 /* 1366 1346 * Optimize for the case when the rwsem is not locked at all. 1367 1347 */ 1368 - long tmp = RWSEM_UNLOCKED_VALUE; 1369 - 1348 + tmp = RWSEM_UNLOCKED_VALUE; 1370 1349 do { 1371 1350 if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, 1372 1351 tmp + RWSEM_READER_BIAS)) { ··· 1410 1383 1411 1384 static inline int __down_write_trylock(struct rw_semaphore *sem) 1412 1385 { 1413 - long tmp = RWSEM_UNLOCKED_VALUE; 1386 + long tmp; 1414 1387 1388 + DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem); 1389 + 1390 + tmp = RWSEM_UNLOCKED_VALUE; 1415 1391 if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, 1416 1392 RWSEM_WRITER_LOCKED)) { 1417 1393 rwsem_set_owner(sem); ··· 1430 1400 { 1431 1401 long tmp; 1432 1402 1403 + DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem); 1433 1404 DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); 1405 + 1434 1406 rwsem_clear_reader_owned(sem); 1435 1407 tmp = atomic_long_add_return_release(-RWSEM_READER_BIAS, &sem->count); 1436 1408 DEBUG_RWSEMS_WARN_ON(tmp < 0, sem); ··· 1450 1418 { 1451 1419 long tmp; 1452 1420 1421 + DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem); 1453 1422 /* 1454 1423 * sem->owner may differ from current if the ownership is transferred 1455 1424 * to an anonymous writer by setting the RWSEM_NONSPINNABLE bits. 1456 1425 */ 1457 1426 DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) && 1458 1427 !rwsem_test_oflags(sem, RWSEM_NONSPINNABLE), sem); 1428 + 1459 1429 rwsem_clear_owner(sem); 1460 1430 tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count); 1461 1431 if (unlikely(tmp & RWSEM_FLAG_WAITERS))
+2 -2
kernel/stacktrace.c
··· 20 20 * @nr_entries: Number of entries in the storage array 21 21 * @spaces: Number of leading spaces to print 22 22 */ 23 - void stack_trace_print(unsigned long *entries, unsigned int nr_entries, 23 + void stack_trace_print(const unsigned long *entries, unsigned int nr_entries, 24 24 int spaces) 25 25 { 26 26 unsigned int i; ··· 43 43 * 44 44 * Return: Number of bytes printed. 45 45 */ 46 - int stack_trace_snprint(char *buf, size_t size, unsigned long *entries, 46 + int stack_trace_snprint(char *buf, size_t size, const unsigned long *entries, 47 47 unsigned int nr_entries, int spaces) 48 48 { 49 49 unsigned int generated, i, total = 0;