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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull locking fixes from Thomas Gleixner:
"A set of locking fixes:

- Address the fallout of the rwsem rework. Missing ACQUIREs and a
sanity check to prevent a use-after-free

- Add missing checks for unitialized mutexes when mutex debugging is
enabled.

- Remove the bogus code in the generic SMP variant of
arch_futex_atomic_op_inuser()

- Fixup the #ifdeffery in lockdep to prevent compile warnings"

* 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/mutex: Test for initialized mutex
locking/lockdep: Clean up #ifdef checks
locking/lockdep: Hide unused 'class' variable
locking/rwsem: Add ACQUIRE comments
tty/ldsem, locking/rwsem: Add missing ACQUIRE to read_failed sleep loop
lcoking/rwsem: Add missing ACQUIRE to read_slowpath sleep loop
locking/rwsem: Add missing ACQUIRE to read_slowpath exit when queue is empty
locking/rwsem: Don't call owner_on_cpu() on read-owner
futex: Cleanup generic SMP variant of arch_futex_atomic_op_inuser()

+43 -38
+2 -3
drivers/tty/tty_ldsem.c
··· 93 93 94 94 list_for_each_entry_safe(waiter, next, &sem->read_wait, list) { 95 95 tsk = waiter->task; 96 - smp_mb(); 97 - waiter->task = NULL; 96 + smp_store_release(&waiter->task, NULL); 98 97 wake_up_process(tsk); 99 98 put_task_struct(tsk); 100 99 } ··· 193 194 for (;;) { 194 195 set_current_state(TASK_UNINTERRUPTIBLE); 195 196 196 - if (!waiter.task) 197 + if (!smp_load_acquire(&waiter.task)) 197 198 break; 198 199 if (!timeout) 199 200 break;
+1 -20
include/asm-generic/futex.h
··· 118 118 static inline int 119 119 arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) 120 120 { 121 - int oldval = 0, ret; 122 - 123 - pagefault_disable(); 124 - 125 - switch (op) { 126 - case FUTEX_OP_SET: 127 - case FUTEX_OP_ADD: 128 - case FUTEX_OP_OR: 129 - case FUTEX_OP_ANDN: 130 - case FUTEX_OP_XOR: 131 - default: 132 - ret = -ENOSYS; 133 - } 134 - 135 - pagefault_enable(); 136 - 137 - if (!ret) 138 - *oval = oldval; 139 - 140 - return ret; 121 + return -ENOSYS; 141 122 } 142 123 143 124 static inline int
+6 -7
kernel/locking/lockdep.c
··· 448 448 449 449 unsigned long nr_stack_trace_entries; 450 450 451 - #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) 451 + #ifdef CONFIG_PROVE_LOCKING 452 452 /* 453 453 * Stack-trace: tightly packed array of stack backtrace 454 454 * addresses. Protected by the graph_lock. ··· 491 491 DEFINE_PER_CPU(struct lockdep_stats, lockdep_stats); 492 492 #endif 493 493 494 - #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) 494 + #ifdef CONFIG_PROVE_LOCKING 495 495 /* 496 496 * Locking printouts: 497 497 */ ··· 2969 2969 #endif 2970 2970 } 2971 2971 2972 - #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) 2972 + #ifdef CONFIG_PROVE_LOCKING 2973 2973 static int mark_lock(struct task_struct *curr, struct held_lock *this, 2974 2974 enum lock_usage_bit new_bit); 2975 2975 ··· 3608 3608 return ret; 3609 3609 } 3610 3610 3611 - #else /* defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) */ 3611 + #else /* CONFIG_PROVE_LOCKING */ 3612 3612 3613 3613 static inline int 3614 3614 mark_usage(struct task_struct *curr, struct held_lock *hlock, int check) ··· 3627 3627 return 0; 3628 3628 } 3629 3629 3630 - #endif /* defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) */ 3630 + #endif /* CONFIG_PROVE_LOCKING */ 3631 3631 3632 3632 /* 3633 3633 * Initialize a lock instance's lock-class mapping info: ··· 4321 4321 */ 4322 4322 static void check_flags(unsigned long flags) 4323 4323 { 4324 - #if defined(CONFIG_PROVE_LOCKING) && defined(CONFIG_DEBUG_LOCKDEP) && \ 4325 - defined(CONFIG_TRACE_IRQFLAGS) 4324 + #if defined(CONFIG_PROVE_LOCKING) && defined(CONFIG_DEBUG_LOCKDEP) 4326 4325 if (!debug_locks) 4327 4326 return; 4328 4327
+2 -1
kernel/locking/lockdep_proc.c
··· 200 200 201 201 static int lockdep_stats_show(struct seq_file *m, void *v) 202 202 { 203 - struct lock_class *class; 204 203 unsigned long nr_unused = 0, nr_uncategorized = 0, 205 204 nr_irq_safe = 0, nr_irq_unsafe = 0, 206 205 nr_softirq_safe = 0, nr_softirq_unsafe = 0, ··· 210 211 sum_forward_deps = 0; 211 212 212 213 #ifdef CONFIG_PROVE_LOCKING 214 + struct lock_class *class; 215 + 213 216 list_for_each_entry(class, &all_lock_classes, lock_entry) { 214 217 215 218 if (class->usage_mask == 0)
+10 -1
kernel/locking/mutex.c
··· 908 908 909 909 might_sleep(); 910 910 911 + #ifdef CONFIG_DEBUG_MUTEXES 912 + DEBUG_LOCKS_WARN_ON(lock->magic != lock); 913 + #endif 914 + 911 915 ww = container_of(lock, struct ww_mutex, base); 912 916 if (use_ww_ctx && ww_ctx) { 913 917 if (unlikely(ww_ctx == READ_ONCE(ww->ctx))) ··· 1383 1379 */ 1384 1380 int __sched mutex_trylock(struct mutex *lock) 1385 1381 { 1386 - bool locked = __mutex_trylock(lock); 1382 + bool locked; 1387 1383 1384 + #ifdef CONFIG_DEBUG_MUTEXES 1385 + DEBUG_LOCKS_WARN_ON(lock->magic != lock); 1386 + #endif 1387 + 1388 + locked = __mutex_trylock(lock); 1388 1389 if (locked) 1389 1390 mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); 1390 1391
+22 -6
kernel/locking/rwsem.c
··· 666 666 preempt_disable(); 667 667 rcu_read_lock(); 668 668 owner = rwsem_owner_flags(sem, &flags); 669 - if ((flags & nonspinnable) || (owner && !owner_on_cpu(owner))) 669 + /* 670 + * Don't check the read-owner as the entry may be stale. 671 + */ 672 + if ((flags & nonspinnable) || 673 + (owner && !(flags & RWSEM_READER_OWNED) && !owner_on_cpu(owner))) 670 674 ret = false; 671 675 rcu_read_unlock(); 672 676 preempt_enable(); ··· 1004 1000 atomic_long_add(-RWSEM_READER_BIAS, &sem->count); 1005 1001 adjustment = 0; 1006 1002 if (rwsem_optimistic_spin(sem, false)) { 1003 + /* rwsem_optimistic_spin() implies ACQUIRE on success */ 1007 1004 /* 1008 1005 * Wake up other readers in the wait list if the front 1009 1006 * waiter is a reader. ··· 1019 1014 } 1020 1015 return sem; 1021 1016 } else if (rwsem_reader_phase_trylock(sem, waiter.last_rowner)) { 1017 + /* rwsem_reader_phase_trylock() implies ACQUIRE on success */ 1022 1018 return sem; 1023 1019 } 1024 1020 ··· 1038 1032 */ 1039 1033 if (adjustment && !(atomic_long_read(&sem->count) & 1040 1034 (RWSEM_WRITER_MASK | RWSEM_FLAG_HANDOFF))) { 1035 + /* Provide lock ACQUIRE */ 1036 + smp_acquire__after_ctrl_dep(); 1041 1037 raw_spin_unlock_irq(&sem->wait_lock); 1042 1038 rwsem_set_reader_owned(sem); 1043 1039 lockevent_inc(rwsem_rlock_fast); ··· 1073 1065 wake_up_q(&wake_q); 1074 1066 1075 1067 /* wait to be given the lock */ 1076 - while (true) { 1068 + for (;;) { 1077 1069 set_current_state(state); 1078 - if (!waiter.task) 1070 + if (!smp_load_acquire(&waiter.task)) { 1071 + /* Matches rwsem_mark_wake()'s smp_store_release(). */ 1079 1072 break; 1073 + } 1080 1074 if (signal_pending_state(state, current)) { 1081 1075 raw_spin_lock_irq(&sem->wait_lock); 1082 1076 if (waiter.task) 1083 1077 goto out_nolock; 1084 1078 raw_spin_unlock_irq(&sem->wait_lock); 1079 + /* Ordered by sem->wait_lock against rwsem_mark_wake(). */ 1085 1080 break; 1086 1081 } 1087 1082 schedule(); ··· 1094 1083 __set_current_state(TASK_RUNNING); 1095 1084 lockevent_inc(rwsem_rlock); 1096 1085 return sem; 1086 + 1097 1087 out_nolock: 1098 1088 list_del(&waiter.list); 1099 1089 if (list_empty(&sem->wait_list)) { ··· 1135 1123 1136 1124 /* do optimistic spinning and steal lock if possible */ 1137 1125 if (rwsem_can_spin_on_owner(sem, RWSEM_WR_NONSPINNABLE) && 1138 - rwsem_optimistic_spin(sem, true)) 1126 + rwsem_optimistic_spin(sem, true)) { 1127 + /* rwsem_optimistic_spin() implies ACQUIRE on success */ 1139 1128 return sem; 1129 + } 1140 1130 1141 1131 /* 1142 1132 * Disable reader optimistic spinning for this rwsem after ··· 1198 1184 wait: 1199 1185 /* wait until we successfully acquire the lock */ 1200 1186 set_current_state(state); 1201 - while (true) { 1202 - if (rwsem_try_write_lock(sem, wstate)) 1187 + for (;;) { 1188 + if (rwsem_try_write_lock(sem, wstate)) { 1189 + /* rwsem_try_write_lock() implies ACQUIRE on success */ 1203 1190 break; 1191 + } 1204 1192 1205 1193 raw_spin_unlock_irq(&sem->wait_lock); 1206 1194