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 fixes and updates for the locking code:

- Prevent lockdep from updating irq state within its own code and
thereby confusing itself.

- Buid fix for older GCCs which mistreat anonymous unions

- Add a missing lockdep annotation in down_read_non_onwer() which
causes up_read_non_owner() to emit a lockdep splat

- Remove the custom alpha dec_and_lock() implementation which is
incorrect in terms of ordering and use the generic one.

The remaining two commits are not strictly fixes. They provide irqsave
variants of atomic_dec_and_lock() and refcount_dec_and_lock(). These
are required to merge the relevant updates and cleanups into different
maintainer trees for 4.19, so routing them into mainline without
actual users is the sanest approach.

They should have been in -rc1, but last weekend I took the liberty to
just avoid computers in order to regain some mental sanity"

* 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/qspinlock: Fix build for anonymous union in older GCC compilers
locking/lockdep: Do not record IRQ state within lockdep code
locking/rwsem: Fix up_read_non_owner() warning with DEBUG_RWSEMS
locking/refcounts: Implement refcount_dec_and_lock_irqsave()
atomic: Add irqsave variant of atomic_dec_and_lock()
alpha: Remove custom dec_and_lock() implementation

+61 -64
-5
arch/alpha/Kconfig
··· 555 555 556 556 If you don't know what to do here, say N. 557 557 558 - config HAVE_DEC_LOCK 559 - bool 560 - depends on SMP 561 - default y 562 - 563 558 config NR_CPUS 564 559 int "Maximum number of CPUs (2-32)" 565 560 range 2 32
-2
arch/alpha/lib/Makefile
··· 35 35 callback_srm.o srm_puts.o srm_printk.o \ 36 36 fls.o 37 37 38 - lib-$(CONFIG_SMP) += dec_and_lock.o 39 - 40 38 # The division routines are built from single source, with different defines. 41 39 AFLAGS___divqu.o = -DDIV 42 40 AFLAGS___remqu.o = -DREM
-44
arch/alpha/lib/dec_and_lock.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * arch/alpha/lib/dec_and_lock.c 4 - * 5 - * ll/sc version of atomic_dec_and_lock() 6 - * 7 - */ 8 - 9 - #include <linux/spinlock.h> 10 - #include <linux/atomic.h> 11 - #include <linux/export.h> 12 - 13 - asm (".text \n\ 14 - .global _atomic_dec_and_lock \n\ 15 - .ent _atomic_dec_and_lock \n\ 16 - .align 4 \n\ 17 - _atomic_dec_and_lock: \n\ 18 - .prologue 0 \n\ 19 - 1: ldl_l $1, 0($16) \n\ 20 - subl $1, 1, $1 \n\ 21 - beq $1, 2f \n\ 22 - stl_c $1, 0($16) \n\ 23 - beq $1, 4f \n\ 24 - mb \n\ 25 - clr $0 \n\ 26 - ret \n\ 27 - 2: br $29, 3f \n\ 28 - 3: ldgp $29, 0($29) \n\ 29 - br $atomic_dec_and_lock_1..ng \n\ 30 - .subsection 2 \n\ 31 - 4: br 1b \n\ 32 - .previous \n\ 33 - .end _atomic_dec_and_lock"); 34 - 35 - static int __used atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock) 36 - { 37 - /* Slow path */ 38 - spin_lock(lock); 39 - if (atomic_dec_and_test(atomic)) 40 - return 1; 41 - spin_unlock(lock); 42 - return 0; 43 - } 44 - EXPORT_SYMBOL(_atomic_dec_and_lock);
+1 -1
include/asm-generic/qspinlock_types.h
··· 63 63 /* 64 64 * Initializier 65 65 */ 66 - #define __ARCH_SPIN_LOCK_UNLOCKED { .val = ATOMIC_INIT(0) } 66 + #define __ARCH_SPIN_LOCK_UNLOCKED { { .val = ATOMIC_INIT(0) } } 67 67 68 68 /* 69 69 * Bitfields in the atomic value:
+3 -1
include/linux/refcount.h
··· 98 98 extern __must_check bool refcount_dec_not_one(refcount_t *r); 99 99 extern __must_check bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock); 100 100 extern __must_check bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock); 101 - 101 + extern __must_check bool refcount_dec_and_lock_irqsave(refcount_t *r, 102 + spinlock_t *lock, 103 + unsigned long *flags); 102 104 #endif /* _LINUX_REFCOUNT_H */
+5
include/linux/spinlock.h
··· 427 427 #define atomic_dec_and_lock(atomic, lock) \ 428 428 __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) 429 429 430 + extern int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock, 431 + unsigned long *flags); 432 + #define atomic_dec_and_lock_irqsave(atomic, lock, flags) \ 433 + __cond_lock(lock, _atomic_dec_and_lock_irqsave(atomic, lock, &(flags))) 434 + 430 435 int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, 431 436 size_t max_size, unsigned int cpu_mult, 432 437 gfp_t gfp);
+6 -6
kernel/locking/lockdep.c
··· 1265 1265 this.parent = NULL; 1266 1266 this.class = class; 1267 1267 1268 - local_irq_save(flags); 1268 + raw_local_irq_save(flags); 1269 1269 arch_spin_lock(&lockdep_lock); 1270 1270 ret = __lockdep_count_forward_deps(&this); 1271 1271 arch_spin_unlock(&lockdep_lock); 1272 - local_irq_restore(flags); 1272 + raw_local_irq_restore(flags); 1273 1273 1274 1274 return ret; 1275 1275 } ··· 1292 1292 this.parent = NULL; 1293 1293 this.class = class; 1294 1294 1295 - local_irq_save(flags); 1295 + raw_local_irq_save(flags); 1296 1296 arch_spin_lock(&lockdep_lock); 1297 1297 ret = __lockdep_count_backward_deps(&this); 1298 1298 arch_spin_unlock(&lockdep_lock); 1299 - local_irq_restore(flags); 1299 + raw_local_irq_restore(flags); 1300 1300 1301 1301 return ret; 1302 1302 } ··· 4411 4411 if (unlikely(!debug_locks)) 4412 4412 return; 4413 4413 4414 - local_irq_save(flags); 4414 + raw_local_irq_save(flags); 4415 4415 for (i = 0; i < curr->lockdep_depth; i++) { 4416 4416 hlock = curr->held_locks + i; 4417 4417 ··· 4422 4422 print_freed_lock_bug(curr, mem_from, mem_from + mem_len, hlock); 4423 4423 break; 4424 4424 } 4425 - local_irq_restore(flags); 4425 + raw_local_irq_restore(flags); 4426 4426 } 4427 4427 EXPORT_SYMBOL_GPL(debug_check_no_locks_freed); 4428 4428
+1
kernel/locking/rwsem.c
··· 181 181 might_sleep(); 182 182 183 183 __down_read(sem); 184 + rwsem_set_reader_owned(sem); 184 185 } 185 186 186 187 EXPORT_SYMBOL(down_read_non_owner);
+1 -5
lib/Makefile
··· 23 23 sha1.o chacha20.o irq_regs.o argv_split.o \ 24 24 flex_proportions.o ratelimit.o show_mem.o \ 25 25 is_single_threaded.o plist.o decompress.o kobject_uevent.o \ 26 - earlycpio.o seq_buf.o siphash.o \ 26 + earlycpio.o seq_buf.o siphash.o dec_and_lock.o \ 27 27 nmi_backtrace.o nodemask.o win_minmax.o 28 28 29 29 lib-$(CONFIG_PRINTK) += dump_stack.o ··· 94 94 obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o 95 95 obj-$(CONFIG_DEBUG_LIST) += list_debug.o 96 96 obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o 97 - 98 - ifneq ($(CONFIG_HAVE_DEC_LOCK),y) 99 - lib-y += dec_and_lock.o 100 - endif 101 97 102 98 obj-$(CONFIG_BITREVERSE) += bitrev.o 103 99 obj-$(CONFIG_RATIONAL) += rational.o
+16
lib/dec_and_lock.c
··· 33 33 } 34 34 35 35 EXPORT_SYMBOL(_atomic_dec_and_lock); 36 + 37 + int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock, 38 + unsigned long *flags) 39 + { 40 + /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ 41 + if (atomic_add_unless(atomic, -1, 1)) 42 + return 0; 43 + 44 + /* Otherwise do it the slow way */ 45 + spin_lock_irqsave(lock, *flags); 46 + if (atomic_dec_and_test(atomic)) 47 + return 1; 48 + spin_unlock_irqrestore(lock, *flags); 49 + return 0; 50 + } 51 + EXPORT_SYMBOL(_atomic_dec_and_lock_irqsave);
+28
lib/refcount.c
··· 350 350 } 351 351 EXPORT_SYMBOL(refcount_dec_and_lock); 352 352 353 + /** 354 + * refcount_dec_and_lock_irqsave - return holding spinlock with disabled 355 + * interrupts if able to decrement refcount to 0 356 + * @r: the refcount 357 + * @lock: the spinlock to be locked 358 + * @flags: saved IRQ-flags if the is acquired 359 + * 360 + * Same as refcount_dec_and_lock() above except that the spinlock is acquired 361 + * with disabled interupts. 362 + * 363 + * Return: true and hold spinlock if able to decrement refcount to 0, false 364 + * otherwise 365 + */ 366 + bool refcount_dec_and_lock_irqsave(refcount_t *r, spinlock_t *lock, 367 + unsigned long *flags) 368 + { 369 + if (refcount_dec_not_one(r)) 370 + return false; 371 + 372 + spin_lock_irqsave(lock, *flags); 373 + if (!refcount_dec_and_test(r)) { 374 + spin_unlock_irqrestore(lock, *flags); 375 + return false; 376 + } 377 + 378 + return true; 379 + } 380 + EXPORT_SYMBOL(refcount_dec_and_lock_irqsave);