Pull locking updates from Borislav Petkov: "Lots of cleanups and preparation. Highlights: - futex: Cleanup and remove runtime futex_cmpxchg detection - rtmutex: Some fixes for the PREEMPT_RT locking infrastructure - kcsan: Share owner_on_cpu() between mutex,rtmutex and rwsem and annotate the racy owner->on_cpu access *once*. - atomic64: Dead-Code-Elemination" [ Description above by Peter Zijlstra ] * tag 'locking_core_for_v5.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: locking/atomic: atomic64: Remove unusable atomic ops futex: Fix additional regressions locking: Allow to include asm/spinlock_types.h from linux/spinlock_types_raw.h x86/mm: Include spinlock_t definition in pgtable. locking: Mark racy reads of owner->on_cpu locking: Make owner_on_cpu() into <linux/sched.h> lockdep/selftests: Adapt ww-tests for PREEMPT_RT lockdep/selftests: Skip the softirq related tests on PREEMPT_RT lockdep/selftests: Unbalanced migrate_disable() & rcu_read_lock(). lockdep/selftests: Avoid using local_lock_{acquire|release}(). lockdep: Remove softirq accounting on PREEMPT_RT. locking/rtmutex: Add rt_mutex_lock_nest_lock() and rt_mutex_lock_killable(). locking/rtmutex: Squash self-deadlock check for ww_rt_mutex. locking: Remove rt_rwlock_is_contended(). sched: Trigger warning if ->migration_disabled counter underflows. futex: Fix sparc32/m68k/nds32 build regression futex: Remove futex_cmpxchg detection futex: Ensure futex_atomic_cmpxchg_inatomic() is present kernel/locking: Use a pointer in ww_mutex_trylock().
Unified · Split
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _ALPHA_SPINLOCK_TYPES_H |
| 3 | 3 | #define _ALPHA_SPINLOCK_TYPES_H |
| 4 | 4 | |
| 5 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 5 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 6 | 6 | # error "please don't include this file directly" |
| 7 | 7 | #endif |
| 8 | 8 | |
| @@ -32,7 +32,6 @@ config ARC · 31 unmodified lines | ||
| 32 | 32 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE if ARC_MMU_V4 |
| 33 | 33 | select HAVE_DEBUG_STACKOVERFLOW |
| 34 | 34 | select HAVE_DEBUG_KMEMLEAK |
| 35 | − select HAVE_FUTEX_CMPXCHG if FUTEX | |
| 36 | 35 | select HAVE_IOREMAP_PROT |
| 37 | 36 | select HAVE_KERNEL_GZIP |
| 38 | 37 | select HAVE_KERNEL_LZMA |
| @@ -93,7 +93,6 @@ config ARM · 92 unmodified lines | ||
| 93 | 93 | select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL |
| 94 | 94 | select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG |
| 95 | 95 | select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !(THUMB2_KERNEL && CC_IS_CLANG) |
| 96 | − select HAVE_FUTEX_CMPXCHG if FUTEX | |
| 97 | 96 | select HAVE_GCC_PLUGINS |
| 98 | 97 | select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) |
| 99 | 98 | select HAVE_IRQ_TIME_ACCOUNTING |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef __ASM_SPINLOCK_TYPES_H |
| 3 | 3 | #define __ASM_SPINLOCK_TYPES_H |
| 4 | 4 | |
| 5 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 5 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 6 | 6 | # error "please don't include this file directly" |
| 7 | 7 | #endif |
| 8 | 8 | |
| @@ -196,7 +196,6 @@ config ARM64 · 195 unmodified lines | ||
| 196 | 196 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 197 | 197 | select HAVE_POSIX_CPU_TIMERS_TASK_WORK |
| 198 | 198 | select HAVE_FUNCTION_ARG_ACCESS_API |
| 199 | − select HAVE_FUTEX_CMPXCHG if FUTEX | |
| 200 | 199 | select MMU_GATHER_RCU_TABLE_FREE |
| 201 | 200 | select HAVE_RSEQ |
| 202 | 201 | select HAVE_STACKPROTECTOR |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #ifndef __ASM_SPINLOCK_TYPES_H |
| 6 | 6 | #define __ASM_SPINLOCK_TYPES_H |
| 7 | 7 | |
| 8 | −#if !defined(__LINUX_SPINLOCK_TYPES_H) && !defined(__ASM_SPINLOCK_H) | |
| 8 | +#if !defined(__LINUX_SPINLOCK_TYPES_RAW_H) && !defined(__ASM_SPINLOCK_H) | |
| 9 | 9 | # error "please don't include this file directly" |
| 10 | 10 | #endif |
| 11 | 11 | |
| @@ -52,7 +52,6 @@ config CSKY · 51 unmodified lines | ||
| 52 | 52 | select HAVE_FUNCTION_TRACER |
| 53 | 53 | select HAVE_FUNCTION_GRAPH_TRACER |
| 54 | 54 | select HAVE_FUNCTION_ERROR_INJECTION |
| 55 | − select HAVE_FUTEX_CMPXCHG if FUTEX && SMP | |
| 56 | 55 | select HAVE_FTRACE_MCOUNT_RECORD |
| 57 | 56 | select HAVE_KERNEL_GZIP |
| 58 | 57 | select HAVE_KERNEL_LZO |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #ifndef __ASM_CSKY_SPINLOCK_TYPES_H |
| 4 | 4 | #define __ASM_CSKY_SPINLOCK_TYPES_H |
| 5 | 5 | |
| 6 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 6 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 7 | 7 | # error "please don't include this file directly" |
| 8 | 8 | #endif |
| 9 | 9 | |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #ifndef _ASM_SPINLOCK_TYPES_H |
| 9 | 9 | #define _ASM_SPINLOCK_TYPES_H |
| 10 | 10 | |
| 11 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 11 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 12 | 12 | # error "please don't include this file directly" |
| 13 | 13 | #endif |
| 14 | 14 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _ASM_IA64_SPINLOCK_TYPES_H |
| 3 | 3 | #define _ASM_IA64_SPINLOCK_TYPES_H |
| 4 | 4 | |
| 5 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 5 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 6 | 6 | # error "please don't include this file directly" |
| 7 | 7 | #endif |
| 8 | 8 | |
| @@ -21,7 +21,6 @@ config M68K · 20 unmodified lines | ||
| 21 | 21 | select HAVE_ASM_MODVERSIONS |
| 22 | 22 | select HAVE_DEBUG_BUGVERBOSE |
| 23 | 23 | select HAVE_EFFICIENT_UNALIGNED_ACCESS if !CPU_HAS_NO_UNALIGNED |
| 24 | − select HAVE_FUTEX_CMPXCHG if MMU && FUTEX | |
| 25 | 24 | select HAVE_MOD_ARCH_SPECIFIC |
| 26 | 25 | select HAVE_UID16 |
| 27 | 26 | select MMU_GATHER_NO_RANGE if MMU |
| @@ -19,7 +19,11 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <asm/sync.h> |
| 20 | 20 | #include <asm/war.h> |
| 21 | 21 | |
| 22 | −#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ | |
| 22 | +#define arch_futex_atomic_op_inuser arch_futex_atomic_op_inuser | |
| 23 | +#define futex_atomic_cmpxchg_inatomic futex_atomic_cmpxchg_inatomic | |
| 24 | +#include <asm-generic/futex.h> | |
| 25 | + | |
| 26 | +#define __futex_atomic_op(op, insn, ret, oldval, uaddr, oparg) \ | |
| 23 | 27 | { \ |
| 24 | 28 | if (cpu_has_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) { \ |
| 25 | 29 | __asm__ __volatile__( \ |
| @@ -80,8 +84,10 @@ · 54 unmodified lines | ||
| 80 | 84 | : "0" (0), GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oparg), \ |
| 81 | 85 | "i" (-EFAULT) \ |
| 82 | 86 | : "memory"); \ |
| 83 | − } else \ | |
| 84 | − ret = -ENOSYS; \ | |
| 87 | + } else { \ | |
| 88 | + /* fallback for non-SMP */ \ | |
| 89 | + ret = futex_atomic_op_inuser_local(op, oparg, oval, uaddr); \ | |
| 90 | + } \ | |
| 85 | 91 | } |
| 86 | 92 | |
| 87 | 93 | static inline int |
| @@ -94,23 +100,23 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) · 6 unmodified lines | ||
| 94 | 100 | |
| 95 | 101 | switch (op) { |
| 96 | 102 | case FUTEX_OP_SET: |
| 97 | − __futex_atomic_op("move $1, %z5", ret, oldval, uaddr, oparg); | |
| 103 | + __futex_atomic_op(op, "move $1, %z5", ret, oldval, uaddr, oparg); | |
| 98 | 104 | break; |
| 99 | 105 | |
| 100 | 106 | case FUTEX_OP_ADD: |
| 101 | − __futex_atomic_op("addu $1, %1, %z5", | |
| 107 | + __futex_atomic_op(op, "addu $1, %1, %z5", | |
| 102 | 108 | ret, oldval, uaddr, oparg); |
| 103 | 109 | break; |
| 104 | 110 | case FUTEX_OP_OR: |
| 105 | − __futex_atomic_op("or $1, %1, %z5", | |
| 111 | + __futex_atomic_op(op, "or $1, %1, %z5", | |
| 106 | 112 | ret, oldval, uaddr, oparg); |
| 107 | 113 | break; |
| 108 | 114 | case FUTEX_OP_ANDN: |
| 109 | − __futex_atomic_op("and $1, %1, %z5", | |
| 115 | + __futex_atomic_op(op, "and $1, %1, %z5", | |
| 110 | 116 | ret, oldval, uaddr, ~oparg); |
| 111 | 117 | break; |
| 112 | 118 | case FUTEX_OP_XOR: |
| 113 | − __futex_atomic_op("xor $1, %1, %z5", | |
| 119 | + __futex_atomic_op(op, "xor $1, %1, %z5", | |
| 114 | 120 | ret, oldval, uaddr, oparg); |
| 115 | 121 | break; |
| 116 | 122 | default: |
| @@ -193,8 +199,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, · 76 unmodified lines | ||
| 193 | 199 | : GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), |
| 194 | 200 | "i" (-EFAULT) |
| 195 | 201 | : "memory"); |
| 196 | − } else | |
| 197 | − return -ENOSYS; | |
| 202 | + } else { | |
| 203 | + return futex_atomic_cmpxchg_inatomic_local(uval, uaddr, oldval, newval); | |
| 204 | + } | |
| 198 | 205 | |
| 199 | 206 | *uval = val; |
| 200 | 207 | return ret; |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _ASM_POWERPC_SIMPLE_SPINLOCK_TYPES_H |
| 3 | 3 | #define _ASM_POWERPC_SIMPLE_SPINLOCK_TYPES_H |
| 4 | 4 | |
| 5 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 5 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 6 | 6 | # error "please don't include this file directly" |
| 7 | 7 | #endif |
| 8 | 8 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _ASM_POWERPC_SPINLOCK_TYPES_H |
| 3 | 3 | #define _ASM_POWERPC_SPINLOCK_TYPES_H |
| 4 | 4 | |
| 5 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 5 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 6 | 6 | # error "please don't include this file directly" |
| 7 | 7 | #endif |
| 8 | 8 | |
| @@ -83,7 +83,6 @@ config RISCV · 82 unmodified lines | ||
| 83 | 83 | select HAVE_DMA_CONTIGUOUS if MMU |
| 84 | 84 | select HAVE_EBPF_JIT if MMU |
| 85 | 85 | select HAVE_FUNCTION_ERROR_INJECTION |
| 86 | − select HAVE_FUTEX_CMPXCHG if FUTEX | |
| 87 | 86 | select HAVE_GCC_PLUGINS |
| 88 | 87 | select HAVE_GENERIC_VDSO if MMU && 64BIT |
| 89 | 88 | select HAVE_IRQ_TIME_ACCOUNTING |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #ifndef _ASM_RISCV_SPINLOCK_TYPES_H |
| 7 | 7 | #define _ASM_RISCV_SPINLOCK_TYPES_H |
| 8 | 8 | |
| 9 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 9 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 10 | 10 | # error "please don't include this file directly" |
| 11 | 11 | #endif |
| 12 | 12 | |
| @@ -165,7 +165,6 @@ config S390 · 164 unmodified lines | ||
| 165 | 165 | select HAVE_FUNCTION_ERROR_INJECTION |
| 166 | 166 | select HAVE_FUNCTION_GRAPH_TRACER |
| 167 | 167 | select HAVE_FUNCTION_TRACER |
| 168 | − select HAVE_FUTEX_CMPXCHG if FUTEX | |
| 169 | 168 | select HAVE_GCC_PLUGINS |
| 170 | 169 | select HAVE_GENERIC_VDSO |
| 171 | 170 | select HAVE_IOREMAP_PROT if PCI |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef __ASM_SPINLOCK_TYPES_H |
| 3 | 3 | #define __ASM_SPINLOCK_TYPES_H |
| 4 | 4 | |
| 5 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 5 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 6 | 6 | # error "please don't include this file directly" |
| 7 | 7 | #endif |
| 8 | 8 | |
| @@ -34,7 +34,6 @@ config SUPERH · 33 unmodified lines | ||
| 34 | 34 | select HAVE_FAST_GUP if MMU |
| 35 | 35 | select HAVE_FUNCTION_GRAPH_TRACER |
| 36 | 36 | select HAVE_FUNCTION_TRACER |
| 37 | − select HAVE_FUTEX_CMPXCHG if FUTEX | |
| 38 | 37 | select HAVE_FTRACE_MCOUNT_RECORD |
| 39 | 38 | select HAVE_HW_BREAKPOINT |
| 40 | 39 | select HAVE_IOREMAP_PROT if MMU && !X2TLB |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef __ASM_SH_SPINLOCK_TYPES_H |
| 3 | 3 | #define __ASM_SH_SPINLOCK_TYPES_H |
| 4 | 4 | |
| 5 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 5 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 6 | 6 | # error "please don't include this file directly" |
| 7 | 7 | #endif |
| 8 | 8 | |
| @@ -14,7 +14,6 @@ config UML · 13 unmodified lines | ||
| 14 | 14 | select HAVE_ARCH_SECCOMP_FILTER |
| 15 | 15 | select HAVE_ASM_MODVERSIONS |
| 16 | 16 | select HAVE_UID16 |
| 17 | − select HAVE_FUTEX_CMPXCHG if FUTEX | |
| 18 | 17 | select HAVE_DEBUG_KMEMLEAK |
| 19 | 18 | select HAVE_DEBUG_BUGVERBOSE |
| 20 | 19 | select NO_DMA if !UML_DMA_EMULATION |
| @@ -323,7 +323,6 @@ EXPORT_SYMBOL(arch_futex_atomic_op_inuser); · 322 unmodified lines | ||
| 323 | 323 | * 0 - On success |
| 324 | 324 | * -EFAULT - User access resulted in a page fault |
| 325 | 325 | * -EAGAIN - Atomic operation was unable to complete due to contention |
| 326 | − * -ENOSYS - Function not implemented (only if !HAVE_FUTEX_CMPXCHG) | |
| 327 | 326 | */ |
| 328 | 327 | |
| 329 | 328 | int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
| @@ -31,7 +31,6 @@ config XTENSA · 30 unmodified lines | ||
| 31 | 31 | select HAVE_DMA_CONTIGUOUS |
| 32 | 32 | select HAVE_EXIT_THREAD |
| 33 | 33 | select HAVE_FUNCTION_TRACER |
| 34 | − select HAVE_FUTEX_CMPXCHG if !MMU && FUTEX | |
| 35 | 34 | select HAVE_HW_BREAKPOINT if PERF_EVENTS |
| 36 | 35 | select HAVE_IRQ_TIME_ACCOUNTING |
| 37 | 36 | select HAVE_PCI |
| @@ -16,6 +16,10 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/uaccess.h> |
| 17 | 17 | #include <linux/errno.h> |
| 18 | 18 | |
| 19 | +#define arch_futex_atomic_op_inuser arch_futex_atomic_op_inuser | |
| 20 | +#define futex_atomic_cmpxchg_inatomic futex_atomic_cmpxchg_inatomic | |
| 21 | +#include <asm-generic/futex.h> | |
| 22 | + | |
| 19 | 23 | #if XCHAL_HAVE_EXCLUSIVE |
| 20 | 24 | #define __futex_atomic_op(insn, ret, old, uaddr, arg) \ |
| 21 | 25 | __asm__ __volatile( \ |
| @@ -105,7 +109,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, · 83 unmodified lines | ||
| 105 | 109 | |
| 106 | 110 | return ret; |
| 107 | 111 | #else |
| 108 | − return -ENOSYS; | |
| 112 | + return futex_atomic_op_inuser_local(op, oparg, oval, uaddr); | |
| 109 | 113 | #endif |
| 110 | 114 | } |
| 111 | 115 | |
| @@ -156,7 +160,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, · 44 unmodified lines | ||
| 156 | 160 | |
| 157 | 161 | return ret; |
| 158 | 162 | #else |
| 159 | − return -ENOSYS; | |
| 163 | + return futex_atomic_cmpxchg_inatomic_local(uval, uaddr, oldval, newval); | |
| 160 | 164 | #endif |
| 161 | 165 | } |
| 162 | 166 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef __ASM_SPINLOCK_TYPES_H |
| 3 | 3 | #define __ASM_SPINLOCK_TYPES_H |
| 4 | 4 | |
| 5 | −#if !defined(__LINUX_SPINLOCK_TYPES_H) && !defined(__ASM_SPINLOCK_H) | |
| 5 | +#if !defined(__LINUX_SPINLOCK_TYPES_RAW_H) && !defined(__ASM_SPINLOCK_H) | |
| 6 | 6 | # error "please don't include this file directly" |
| 7 | 7 | #endif |
| 8 | 8 | |
| @@ -6,15 +6,22 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/uaccess.h> |
| 7 | 7 | #include <asm/errno.h> |
| 8 | 8 | |
| 9 | +#ifndef futex_atomic_cmpxchg_inatomic | |
| 9 | 10 | #ifndef CONFIG_SMP |
| 10 | 11 | /* |
| 11 | 12 | * The following implementation only for uniprocessor machines. |
| 12 | 13 | * It relies on preempt_disable() ensuring mutual exclusion. |
| 13 | 14 | * |
| 14 | 15 | */ |
| 16 | +#define futex_atomic_cmpxchg_inatomic(uval, uaddr, oldval, newval) \ | |
| 17 | + futex_atomic_cmpxchg_inatomic_local(uval, uaddr, oldval, newval) | |
| 18 | +#define arch_futex_atomic_op_inuser(op, oparg, oval, uaddr) \ | |
| 19 | + futex_atomic_op_inuser_local(op, oparg, oval, uaddr) | |
| 20 | +#endif /* CONFIG_SMP */ | |
| 21 | +#endif | |
| 15 | 22 | |
| 16 | 23 | /** |
| 17 | − * arch_futex_atomic_op_inuser() - Atomic arithmetic operation with constant | |
| 24 | + * futex_atomic_op_inuser_local() - Atomic arithmetic operation with constant | |
| 18 | 25 | * argument and comparison of the previous |
| 19 | 26 | * futex value with another constant. |
| 20 | 27 | * |
| @@ -28,7 +35,7 @@ · 7 unmodified lines | ||
| 28 | 35 | * -ENOSYS - Operation not supported |
| 29 | 36 | */ |
| 30 | 37 | static inline int |
| 31 | −arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) | |
| 38 | +futex_atomic_op_inuser_local(int op, u32 oparg, int *oval, u32 __user *uaddr) | |
| 32 | 39 | { |
| 33 | 40 | int oldval, ret; |
| 34 | 41 | u32 tmp; |
| @@ -75,7 +82,7 @@ out_pagefault_enable: · 40 unmodified lines | ||
| 75 | 82 | } |
| 76 | 83 | |
| 77 | 84 | /** |
| 78 | − * futex_atomic_cmpxchg_inatomic() - Compare and exchange the content of the | |
| 85 | + * futex_atomic_cmpxchg_inatomic_local() - Compare and exchange the content of the | |
| 79 | 86 | * uaddr with newval if the current value is |
| 80 | 87 | * oldval. |
| 81 | 88 | * @uval: pointer to store content of @uaddr |
| @@ -87,10 +94,9 @@ out_pagefault_enable: · 5 unmodified lines | ||
| 87 | 94 | * 0 - On success |
| 88 | 95 | * -EFAULT - User access resulted in a page fault |
| 89 | 96 | * -EAGAIN - Atomic operation was unable to complete due to contention |
| 90 | − * -ENOSYS - Function not implemented (only if !HAVE_FUTEX_CMPXCHG) | |
| 91 | 97 | */ |
| 92 | 98 | static inline int |
| 93 | −futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |
| 99 | +futex_atomic_cmpxchg_inatomic_local(u32 *uval, u32 __user *uaddr, | |
| 94 | 100 | u32 oldval, u32 newval) |
| 95 | 101 | { |
| 96 | 102 | u32 val; |
| @@ -112,19 +118,4 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, · 15 unmodified lines | ||
| 112 | 118 | return 0; |
| 113 | 119 | } |
| 114 | 120 | |
| 115 | −#else | |
| 116 | −static inline int | |
| 117 | −arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) | |
| 118 | −{ | |
| 119 | − return -ENOSYS; | |
| 120 | −} | |
| 121 | − | |
| 122 | −static inline int | |
| 123 | −futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |
| 124 | − u32 oldval, u32 newval) | |
| 125 | −{ | |
| 126 | − return -ENOSYS; | |
| 127 | −} | |
| 128 | − | |
| 129 | −#endif /* CONFIG_SMP */ | |
| 130 | 121 | #endif |
| @@ -71,14 +71,6 @@ do { \ · 70 unmodified lines | ||
| 71 | 71 | do { \ |
| 72 | 72 | __this_cpu_dec(hardirq_context); \ |
| 73 | 73 | } while (0) |
| 74 | −# define lockdep_softirq_enter() \ | |
| 75 | −do { \ | |
| 76 | − current->softirq_context++; \ | |
| 77 | −} while (0) | |
| 78 | −# define lockdep_softirq_exit() \ | |
| 79 | −do { \ | |
| 80 | − current->softirq_context--; \ | |
| 81 | −} while (0) | |
| 82 | 74 | |
| 83 | 75 | # define lockdep_hrtimer_enter(__hrtimer) \ |
| 84 | 76 | ({ \ |
| @@ -140,6 +132,21 @@ do { \ · 55 unmodified lines | ||
| 140 | 132 | # define lockdep_irq_work_exit(__work) do { } while (0) |
| 141 | 133 | #endif |
| 142 | 134 | |
| 135 | +#if defined(CONFIG_TRACE_IRQFLAGS) && !defined(CONFIG_PREEMPT_RT) | |
| 136 | +# define lockdep_softirq_enter() \ | |
| 137 | +do { \ | |
| 138 | + current->softirq_context++; \ | |
| 139 | +} while (0) | |
| 140 | +# define lockdep_softirq_exit() \ | |
| 141 | +do { \ | |
| 142 | + current->softirq_context--; \ | |
| 143 | +} while (0) | |
| 144 | + | |
| 145 | +#else | |
| 146 | +# define lockdep_softirq_enter() do { } while (0) | |
| 147 | +# define lockdep_softirq_exit() do { } while (0) | |
| 148 | +#endif | |
| 149 | + | |
| 143 | 150 | #if defined(CONFIG_IRQSOFF_TRACER) || \ |
| 144 | 151 | defined(CONFIG_PREEMPT_TRACER) |
| 145 | 152 | extern void stop_critical_timings(void); |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #include <linux/bits.h> |
| 6 | 6 | #include <linux/param.h> |
| 7 | −#include <linux/spinlock_types.h> | |
| 7 | +#include <linux/spinlock_types_raw.h> | |
| 8 | 8 | |
| 9 | 9 | #define DEFAULT_RATELIMIT_INTERVAL (5 * HZ) |
| 10 | 10 | #define DEFAULT_RATELIMIT_BURST 10 |
| @@ -99,13 +99,22 @@ extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock · 98 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 101 | 101 | extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass); |
| 102 | +extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock); | |
| 102 | 103 | #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0) |
| 104 | +#define rt_mutex_lock_nest_lock(lock, nest_lock) \ | |
| 105 | + do { \ | |
| 106 | + typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ | |
| 107 | + _rt_mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \ | |
| 108 | + } while (0) | |
| 109 | + | |
| 103 | 110 | #else |
| 104 | 111 | extern void rt_mutex_lock(struct rt_mutex *lock); |
| 105 | 112 | #define rt_mutex_lock_nested(lock, subclass) rt_mutex_lock(lock) |
| 113 | +#define rt_mutex_lock_nest_lock(lock, nest_lock) rt_mutex_lock(lock) | |
| 106 | 114 | #endif |
| 107 | 115 | |
| 108 | 116 | extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); |
| 117 | +extern int rt_mutex_lock_killable(struct rt_mutex *lock); | |
| 109 | 118 | extern int rt_mutex_trylock(struct rt_mutex *lock); |
| 110 | 119 | |
| 111 | 120 | extern void rt_mutex_unlock(struct rt_mutex *lock); |
| @@ -2178,6 +2178,15 @@ extern long sched_getaffinity(pid_t pid, struct cpumask *mask); · 2177 unmodified lines | ||
| 2178 | 2178 | #endif |
| 2179 | 2179 | |
| 2180 | 2180 | #ifdef CONFIG_SMP |
| 2181 | +static inline bool owner_on_cpu(struct task_struct *owner) | |
| 2182 | +{ | |
| 2183 | + /* | |
| 2184 | + * As lock holder preemption issue, we both skip spinning if | |
| 2185 | + * task is not on cpu or its cpu is preempted | |
| 2186 | + */ | |
| 2187 | + return READ_ONCE(owner->on_cpu) && !vcpu_is_preempted(task_cpu(owner)); | |
| 2188 | +} | |
| 2189 | + | |
| 2181 | 2190 | /* Returns effective CPU energy utilization, as seen by the scheduler */ |
| 2182 | 2191 | unsigned long sched_cpu_util(int cpu, unsigned long max); |
| 2183 | 2192 | #endif /* CONFIG_SMP */ |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | #ifndef __LINUX_SPINLOCK_TYPES_UP_H |
| 2 | 2 | #define __LINUX_SPINLOCK_TYPES_UP_H |
| 3 | 3 | |
| 4 | −#ifndef __LINUX_SPINLOCK_TYPES_H | |
| 4 | +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H | |
| 5 | 5 | # error "please don't include this file directly" |
| 6 | 6 | #endif |
| 7 | 7 | |
| @@ -1579,6 +1579,7 @@ config BASE_FULL · 1578 unmodified lines | ||
| 1579 | 1579 | |
| 1580 | 1580 | config FUTEX |
| 1581 | 1581 | bool "Enable futex support" if EXPERT |
| 1582 | + depends on !(SPARC32 && SMP) | |
| 1582 | 1583 | default y |
| 1583 | 1584 | imply RT_MUTEXES |
| 1584 | 1585 | help |
| @@ -1591,14 +1592,6 @@ config FUTEX_PI · 6 unmodified lines | ||
| 1591 | 1592 | depends on FUTEX && RT_MUTEXES |
| 1592 | 1593 | default y |
| 1593 | 1594 | |
| 1594 | −config HAVE_FUTEX_CMPXCHG | |
| 1595 | − bool | |
| 1596 | − depends on FUTEX | |
| 1597 | − help | |
| 1598 | − Architectures should select this if futex_atomic_cmpxchg_inatomic() | |
| 1599 | − is implemented and always working. This removes a couple of runtime | |
| 1600 | − checks. | |
| 1601 | − | |
| 1602 | 1595 | config EPOLL |
| 1603 | 1596 | bool "Enable eventpoll support" if EXPERT |
| 1604 | 1597 | default y |
| @@ -41,11 +41,6 @@ · 40 unmodified lines | ||
| 41 | 41 | #include "futex.h" |
| 42 | 42 | #include "../locking/rtmutex_common.h" |
| 43 | 43 | |
| 44 | −#ifndef CONFIG_HAVE_FUTEX_CMPXCHG | |
| 45 | −int __read_mostly futex_cmpxchg_enabled; | |
| 46 | −#endif | |
| 47 | − | |
| 48 | − | |
| 49 | 44 | /* |
| 50 | 45 | * The base of the bucket array and its size are always used together |
| 51 | 46 | * (after initialization only in futex_hash()), so ensure that they |
| @@ -776,9 +771,6 @@ static void exit_robust_list(struct task_struct *curr) · 724 unmodified lines | ||
| 776 | 771 | unsigned long futex_offset; |
| 777 | 772 | int rc; |
| 778 | 773 | |
| 779 | − if (!futex_cmpxchg_enabled) | |
| 780 | − return; | |
| 781 | − | |
| 782 | 774 | /* |
| 783 | 775 | * Fetch the list head (which was registered earlier, via |
| 784 | 776 | * sys_set_robust_list()): |
| @@ -874,9 +866,6 @@ static void compat_exit_robust_list(struct task_struct *curr) · 89 unmodified lines | ||
| 874 | 866 | compat_long_t futex_offset; |
| 875 | 867 | int rc; |
| 876 | 868 | |
| 877 | − if (!futex_cmpxchg_enabled) | |
| 878 | − return; | |
| 879 | − | |
| 880 | 869 | /* |
| 881 | 870 | * Fetch the list head (which was registered earlier, via |
| 882 | 871 | * sys_set_robust_list()): |
| @@ -950,8 +939,6 @@ static void exit_pi_state_list(struct task_struct *curr) · 67 unmodified lines | ||
| 950 | 939 | struct futex_hash_bucket *hb; |
| 951 | 940 | union futex_key key = FUTEX_KEY_INIT; |
| 952 | 941 | |
| 953 | − if (!futex_cmpxchg_enabled) | |
| 954 | − return; | |
| 955 | 942 | /* |
| 956 | 943 | * We are a ZOMBIE and nobody can enqueue itself on |
| 957 | 944 | * pi_state_list anymore, but we have to be careful |
| @@ -1125,26 +1112,6 @@ void futex_exit_release(struct task_struct *tsk) · 167 unmodified lines | ||
| 1125 | 1112 | futex_cleanup_end(tsk, FUTEX_STATE_DEAD); |
| 1126 | 1113 | } |
| 1127 | 1114 | |
| 1128 | −static void __init futex_detect_cmpxchg(void) | |
| 1129 | −{ | |
| 1130 | −#ifndef CONFIG_HAVE_FUTEX_CMPXCHG | |
| 1131 | − u32 curval; | |
| 1132 | − | |
| 1133 | − /* | |
| 1134 | − * This will fail and we want it. Some arch implementations do | |
| 1135 | − * runtime detection of the futex_atomic_cmpxchg_inatomic() | |
| 1136 | − * functionality. We want to know that before we call in any | |
| 1137 | − * of the complex code paths. Also we want to prevent | |
| 1138 | − * registration of robust lists in that case. NULL is | |
| 1139 | − * guaranteed to fault and we get -EFAULT on functional | |
| 1140 | − * implementation, the non-functional ones will return | |
| 1141 | − * -ENOSYS. | |
| 1142 | − */ | |
| 1143 | − if (futex_cmpxchg_value_locked(&curval, NULL, 0, 0) == -EFAULT) | |
| 1144 | − futex_cmpxchg_enabled = 1; | |
| 1145 | −#endif | |
| 1146 | −} | |
| 1147 | − | |
| 1148 | 1115 | static int __init futex_init(void) |
| 1149 | 1116 | { |
| 1150 | 1117 | unsigned int futex_shift; |
| @@ -1163,8 +1130,6 @@ static int __init futex_init(void) · 12 unmodified lines | ||
| 1163 | 1130 | futex_hashsize, futex_hashsize); |
| 1164 | 1131 | futex_hashsize = 1UL << futex_shift; |
| 1165 | 1132 | |
| 1166 | − futex_detect_cmpxchg(); | |
| 1167 | − | |
| 1168 | 1133 | for (i = 0; i < futex_hashsize; i++) { |
| 1169 | 1134 | atomic_set(&futex_queues[i].waiters, 0); |
| 1170 | 1135 | plist_head_init(&futex_queues[i].chain); |
| @@ -27,12 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | #define FLAGS_CLOCKRT 0x02 |
| 28 | 28 | #define FLAGS_HAS_TIMEOUT 0x04 |
| 29 | 29 | |
| 30 | −#ifdef CONFIG_HAVE_FUTEX_CMPXCHG | |
| 31 | −#define futex_cmpxchg_enabled 1 | |
| 32 | −#else | |
| 33 | −extern int __read_mostly futex_cmpxchg_enabled; | |
| 34 | −#endif | |
| 35 | − | |
| 36 | 30 | #ifdef CONFIG_FAIL_FUTEX |
| 37 | 31 | extern bool should_fail_futex(bool fshared); |
| 38 | 32 | #else |
| @@ -29,8 +29,6 @@ · 28 unmodified lines | ||
| 29 | 29 | SYSCALL_DEFINE2(set_robust_list, struct robust_list_head __user *, head, |
| 30 | 30 | size_t, len) |
| 31 | 31 | { |
| 32 | − if (!futex_cmpxchg_enabled) | |
| 33 | − return -ENOSYS; | |
| 34 | 32 | /* |
| 35 | 33 | * The kernel knows only one size for now: |
| 36 | 34 | */ |
| @@ -56,9 +54,6 @@ SYSCALL_DEFINE3(get_robust_list, int, pid, · 19 unmodified lines | ||
| 56 | 54 | unsigned long ret; |
| 57 | 55 | struct task_struct *p; |
| 58 | 56 | |
| 59 | − if (!futex_cmpxchg_enabled) | |
| 60 | − return -ENOSYS; | |
| 61 | − | |
| 62 | 57 | rcu_read_lock(); |
| 63 | 58 | |
| 64 | 59 | ret = -ESRCH; |
| @@ -103,17 +98,6 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, · 38 unmodified lines | ||
| 103 | 98 | return -ENOSYS; |
| 104 | 99 | } |
| 105 | 100 | |
| 106 | − switch (cmd) { | |
| 107 | − case FUTEX_LOCK_PI: | |
| 108 | − case FUTEX_LOCK_PI2: | |
| 109 | − case FUTEX_UNLOCK_PI: | |
| 110 | − case FUTEX_TRYLOCK_PI: | |
| 111 | − case FUTEX_WAIT_REQUEUE_PI: | |
| 112 | − case FUTEX_CMP_REQUEUE_PI: | |
| 113 | − if (!futex_cmpxchg_enabled) | |
| 114 | − return -ENOSYS; | |
| 115 | − } | |
| 116 | − | |
| 117 | 101 | switch (cmd) { |
| 118 | 102 | case FUTEX_WAIT: |
| 119 | 103 | val3 = FUTEX_BITSET_MATCH_ANY; |
| @@ -323,9 +307,6 @@ COMPAT_SYSCALL_DEFINE2(set_robust_list, · 203 unmodified lines | ||
| 323 | 307 | struct compat_robust_list_head __user *, head, |
| 324 | 308 | compat_size_t, len) |
| 325 | 309 | { |
| 326 | − if (!futex_cmpxchg_enabled) | |
| 327 | − return -ENOSYS; | |
| 328 | − | |
| 329 | 310 | if (unlikely(len != sizeof(*head))) |
| 330 | 311 | return -EINVAL; |
| 331 | 312 | |
| @@ -342,9 +323,6 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid, · 10 unmodified lines | ||
| 342 | 323 | unsigned long ret; |
| 343 | 324 | struct task_struct *p; |
| 344 | 325 | |
| 345 | − if (!futex_cmpxchg_enabled) | |
| 346 | − return -ENOSYS; | |
| 347 | − | |
| 348 | 326 | rcu_read_lock(); |
| 349 | 327 | |
| 350 | 328 | ret = -ESRCH; |
| @@ -5485,6 +5485,7 @@ static noinstr void check_flags(unsigned long flags) · 5484 unmodified lines | ||
| 5485 | 5485 | } |
| 5486 | 5486 | } |
| 5487 | 5487 | |
| 5488 | +#ifndef CONFIG_PREEMPT_RT | |
| 5488 | 5489 | /* |
| 5489 | 5490 | * We dont accurately track softirq state in e.g. |
| 5490 | 5491 | * hardirq contexts (such as on 4KSTACKS), so only |
| @@ -5499,6 +5500,7 @@ static noinstr void check_flags(unsigned long flags) · 8 unmodified lines | ||
| 5499 | 5500 | DEBUG_LOCKS_WARN_ON(!current->softirqs_enabled); |
| 5500 | 5501 | } |
| 5501 | 5502 | } |
| 5503 | +#endif | |
| 5502 | 5504 | |
| 5503 | 5505 | if (!debug_locks) |
| 5504 | 5506 | print_irqtrace_events(current); |
| @@ -367,8 +367,7 @@ bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner, · 366 unmodified lines | ||
| 367 | 367 | /* |
| 368 | 368 | * Use vcpu_is_preempted to detect lock holder preemption issue. |
| 369 | 369 | */ |
| 370 | − if (!owner->on_cpu || need_resched() || | |
| 371 | − vcpu_is_preempted(task_cpu(owner))) { | |
| 370 | + if (!owner_on_cpu(owner) || need_resched()) { | |
| 372 | 371 | ret = false; |
| 373 | 372 | break; |
| 374 | 373 | } |
| @@ -403,14 +402,8 @@ static inline int mutex_can_spin_on_owner(struct mutex *lock) · 28 unmodified lines | ||
| 403 | 402 | * structure won't go away during the spinning period. |
| 404 | 403 | */ |
| 405 | 404 | owner = __mutex_owner(lock); |
| 406 | − | |
| 407 | − /* | |
| 408 | − * As lock holder preemption issue, we both skip spinning if task is not | |
| 409 | − * on cpu or its cpu is preempted | |
| 410 | − */ | |
| 411 | − | |
| 412 | 405 | if (owner) |
| 413 | − retval = owner->on_cpu && !vcpu_is_preempted(task_cpu(owner)); | |
| 406 | + retval = owner_on_cpu(owner); | |
| 414 | 407 | |
| 415 | 408 | /* |
| 416 | 409 | * If lock->owner is not set, the mutex has been released. Return true |
| @@ -1103,8 +1103,11 @@ static int __sched task_blocks_on_rt_mutex(struct rt_mutex_base *lock, · 1102 unmodified lines | ||
| 1103 | 1103 | * the other will detect the deadlock and return -EDEADLOCK, |
| 1104 | 1104 | * which is wrong, as the other waiter is not in a deadlock |
| 1105 | 1105 | * situation. |
| 1106 | + * | |
| 1107 | + * Except for ww_mutex, in that case the chain walk must already deal | |
| 1108 | + * with spurious cycles, see the comments at [3] and [6]. | |
| 1106 | 1109 | */ |
| 1107 | − if (owner == task) | |
| 1110 | + if (owner == task && !(build_ww_mutex() && ww_ctx)) | |
| 1108 | 1111 | return -EDEADLK; |
| 1109 | 1112 | |
| 1110 | 1113 | raw_spin_lock(&task->pi_lock); |
| @@ -1379,9 +1382,8 @@ static bool rtmutex_spin_on_owner(struct rt_mutex_base *lock, · 268 unmodified lines | ||
| 1379 | 1382 | * for CONFIG_PREEMPT_RCU=y) |
| 1380 | 1383 | * - the VCPU on which owner runs is preempted |
| 1381 | 1384 | */ |
| 1382 | − if (!owner->on_cpu || need_resched() || | |
| 1383 | − !rt_mutex_waiter_is_top_waiter(lock, waiter) || | |
| 1384 | − vcpu_is_preempted(task_cpu(owner))) { | |
| 1385 | + if (!owner_on_cpu(owner) || need_resched() || | |
| 1386 | + !rt_mutex_waiter_is_top_waiter(lock, waiter)) { | |
| 1385 | 1387 | res = false; |
| 1386 | 1388 | break; |
| 1387 | 1389 | } |
| @@ -21,12 +21,13 @@ int max_lock_depth = 1024; · 20 unmodified lines | ||
| 21 | 21 | */ |
| 22 | 22 | static __always_inline int __rt_mutex_lock_common(struct rt_mutex *lock, |
| 23 | 23 | unsigned int state, |
| 24 | + struct lockdep_map *nest_lock, | |
| 24 | 25 | unsigned int subclass) |
| 25 | 26 | { |
| 26 | 27 | int ret; |
| 27 | 28 | |
| 28 | 29 | might_sleep(); |
| 29 | − mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_); | |
| 30 | + mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, _RET_IP_); | |
| 30 | 31 | ret = __rt_mutex_lock(&lock->rtmutex, state); |
| 31 | 32 | if (ret) |
| 32 | 33 | mutex_release(&lock->dep_map, _RET_IP_); |
| @@ -48,10 +49,16 @@ EXPORT_SYMBOL(rt_mutex_base_init); · 15 unmodified lines | ||
| 48 | 49 | */ |
| 49 | 50 | void __sched rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass) |
| 50 | 51 | { |
| 51 | − __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass); | |
| 52 | + __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, NULL, subclass); | |
| 52 | 53 | } |
| 53 | 54 | EXPORT_SYMBOL_GPL(rt_mutex_lock_nested); |
| 54 | 55 | |
| 56 | +void __sched _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock) | |
| 57 | +{ | |
| 58 | + __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, nest_lock, 0); | |
| 59 | +} | |
| 60 | +EXPORT_SYMBOL_GPL(_rt_mutex_lock_nest_lock); | |
| 61 | + | |
| 55 | 62 | #else /* !CONFIG_DEBUG_LOCK_ALLOC */ |
| 56 | 63 | |
| 57 | 64 | /** |
| @@ -61,7 +68,7 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock_nested); · 3 unmodified lines | ||
| 61 | 68 | */ |
| 62 | 69 | void __sched rt_mutex_lock(struct rt_mutex *lock) |
| 63 | 70 | { |
| 64 | − __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0); | |
| 71 | + __rt_mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, NULL, 0); | |
| 65 | 72 | } |
| 66 | 73 | EXPORT_SYMBOL_GPL(rt_mutex_lock); |
| 67 | 74 | #endif |
| @@ -77,10 +84,25 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock); · 9 unmodified lines | ||
| 77 | 84 | */ |
| 78 | 85 | int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock) |
| 79 | 86 | { |
| 80 | − return __rt_mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0); | |
| 87 | + return __rt_mutex_lock_common(lock, TASK_INTERRUPTIBLE, NULL, 0); | |
| 81 | 88 | } |
| 82 | 89 | EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible); |
| 83 | 90 | |
| 91 | +/** | |
| 92 | + * rt_mutex_lock_killable - lock a rt_mutex killable | |
| 93 | + * | |
| 94 | + * @lock: the rt_mutex to be locked | |
| 95 | + * | |
| 96 | + * Returns: | |
| 97 | + * 0 on success | |
| 98 | + * -EINTR when interrupted by a signal | |
| 99 | + */ | |
| 100 | +int __sched rt_mutex_lock_killable(struct rt_mutex *lock) | |
| 101 | +{ | |
| 102 | + return __rt_mutex_lock_common(lock, TASK_KILLABLE, NULL, 0); | |
| 103 | +} | |
| 104 | +EXPORT_SYMBOL_GPL(rt_mutex_lock_killable); | |
| 105 | + | |
| 84 | 106 | /** |
| 85 | 107 | * rt_mutex_trylock - try to lock a rt_mutex |
| 86 | 108 | * |
| @@ -658,15 +658,6 @@ static inline bool rwsem_try_write_lock_unqueued(struct rw_semaphore *sem) · 657 unmodified lines | ||
| 658 | 658 | return false; |
| 659 | 659 | } |
| 660 | 660 | |
| 661 | −static inline bool owner_on_cpu(struct task_struct *owner) | |
| 662 | −{ | |
| 663 | − /* | |
| 664 | − * As lock holder preemption issue, we both skip spinning if | |
| 665 | − * task is not on cpu or its cpu is preempted | |
| 666 | − */ | |
| 667 | − return owner->on_cpu && !vcpu_is_preempted(task_cpu(owner)); | |
| 668 | −} | |
| 669 | − | |
| 670 | 661 | static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem) |
| 671 | 662 | { |
| 672 | 663 | struct task_struct *owner; |
| @@ -257,12 +257,6 @@ void __sched rt_write_unlock(rwlock_t *rwlock) · 256 unmodified lines | ||
| 257 | 257 | } |
| 258 | 258 | EXPORT_SYMBOL(rt_write_unlock); |
| 259 | 259 | |
| 260 | −int __sched rt_rwlock_is_contended(rwlock_t *rwlock) | |
| 261 | −{ | |
| 262 | − return rw_base_is_contended(&rwlock->rwbase); | |
| 263 | −} | |
| 264 | −EXPORT_SYMBOL(rt_rwlock_is_contended); | |
| 265 | − | |
| 266 | 260 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 267 | 261 | void __rt_rwlock_init(rwlock_t *rwlock, const char *name, |
| 268 | 262 | struct lock_class_key *key) |
| @@ -26,7 +26,7 @@ int ww_mutex_trylock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx) · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | if (__rt_mutex_trylock(&rtm->rtmutex)) { |
| 28 | 28 | ww_mutex_set_context_fastpath(lock, ww_ctx); |
| 29 | − mutex_acquire_nest(&rtm->dep_map, 0, 1, ww_ctx->dep_map, _RET_IP_); | |
| 29 | + mutex_acquire_nest(&rtm->dep_map, 0, 1, &ww_ctx->dep_map, _RET_IP_); | |
| 30 | 30 | return 1; |
| 31 | 31 | } |
| 32 | 32 | |
| @@ -2184,6 +2184,9 @@ void migrate_enable(void) · 2183 unmodified lines | ||
| 2184 | 2184 | return; |
| 2185 | 2185 | } |
| 2186 | 2186 | |
| 2187 | + if (WARN_ON_ONCE(!p->migration_disabled)) | |
| 2188 | + return; | |
| 2189 | + | |
| 2187 | 2190 | /* |
| 2188 | 2191 | * Ensure stop_task runs either before or after this, and that |
| 2189 | 2192 | * __set_cpus_allowed_ptr(SCA_MIGRATE_ENABLE) doesn't schedule(). |
| @@ -118,7 +118,6 @@ ATOMIC64_OPS(sub, -=) · 117 unmodified lines | ||
| 118 | 118 | #undef ATOMIC64_OPS |
| 119 | 119 | #define ATOMIC64_OPS(op, c_op) \ |
| 120 | 120 | ATOMIC64_OP(op, c_op) \ |
| 121 | − ATOMIC64_OP_RETURN(op, c_op) \ | |
| 122 | 121 | ATOMIC64_FETCH_OP(op, c_op) |
| 123 | 122 | |
| 124 | 123 | ATOMIC64_OPS(and, &=) |
| @@ -127,7 +126,6 @@ ATOMIC64_OPS(xor, ^=) · 2 unmodified lines | ||
| 127 | 126 | |
| 128 | 127 | #undef ATOMIC64_OPS |
| 129 | 128 | #undef ATOMIC64_FETCH_OP |
| 130 | −#undef ATOMIC64_OP_RETURN | |
| 131 | 129 | #undef ATOMIC64_OP |
| 132 | 130 | |
| 133 | 131 | s64 generic_atomic64_dec_if_positive(atomic64_t *v) |
| @@ -26,6 +26,12 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/rtmutex.h> |
| 27 | 27 | #include <linux/local_lock.h> |
| 28 | 28 | |
| 29 | +#ifdef CONFIG_PREEMPT_RT | |
| 30 | +# define NON_RT(...) | |
| 31 | +#else | |
| 32 | +# define NON_RT(...) __VA_ARGS__ | |
| 33 | +#endif | |
| 34 | + | |
| 29 | 35 | /* |
| 30 | 36 | * Change this to 1 if you want to see the failure printouts: |
| 31 | 37 | */ |
| @@ -139,7 +145,7 @@ static DEFINE_RT_MUTEX(rtmutex_Z2); · 107 unmodified lines | ||
| 139 | 145 | |
| 140 | 146 | #endif |
| 141 | 147 | |
| 142 | −static local_lock_t local_A = INIT_LOCAL_LOCK(local_A); | |
| 148 | +static DEFINE_PER_CPU(local_lock_t, local_A); | |
| 143 | 149 | |
| 144 | 150 | /* |
| 145 | 151 | * non-inlined runtime initializers, to let separate locks share |
| @@ -712,12 +718,18 @@ GENERATE_TESTCASE(ABCDBCDA_rtmutex); · 566 unmodified lines | ||
| 712 | 718 | |
| 713 | 719 | #undef E |
| 714 | 720 | |
| 721 | +#ifdef CONFIG_PREEMPT_RT | |
| 722 | +# define RT_PREPARE_DBL_UNLOCK() { migrate_disable(); rcu_read_lock(); } | |
| 723 | +#else | |
| 724 | +# define RT_PREPARE_DBL_UNLOCK() | |
| 725 | +#endif | |
| 715 | 726 | /* |
| 716 | 727 | * Double unlock: |
| 717 | 728 | */ |
| 718 | 729 | #define E() \ |
| 719 | 730 | \ |
| 720 | 731 | LOCK(A); \ |
| 732 | + RT_PREPARE_DBL_UNLOCK(); \ | |
| 721 | 733 | UNLOCK(A); \ |
| 722 | 734 | UNLOCK(A); /* fail */ |
| 723 | 735 | |
| @@ -802,6 +814,7 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock) · 78 unmodified lines | ||
| 802 | 814 | #include "locking-selftest-wlock-hardirq.h" |
| 803 | 815 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock) |
| 804 | 816 | |
| 817 | +#ifndef CONFIG_PREEMPT_RT | |
| 805 | 818 | #include "locking-selftest-spin-softirq.h" |
| 806 | 819 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin) |
| 807 | 820 | |
| @@ -810,10 +823,12 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock) · 2 unmodified lines | ||
| 810 | 823 | |
| 811 | 824 | #include "locking-selftest-wlock-softirq.h" |
| 812 | 825 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock) |
| 826 | +#endif | |
| 813 | 827 | |
| 814 | 828 | #undef E1 |
| 815 | 829 | #undef E2 |
| 816 | 830 | |
| 831 | +#ifndef CONFIG_PREEMPT_RT | |
| 817 | 832 | /* |
| 818 | 833 | * Enabling hardirqs with a softirq-safe lock held: |
| 819 | 834 | */ |
| @@ -846,6 +861,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock) · 26 unmodified lines | ||
| 846 | 861 | #undef E1 |
| 847 | 862 | #undef E2 |
| 848 | 863 | |
| 864 | +#endif | |
| 865 | + | |
| 849 | 866 | /* |
| 850 | 867 | * Enabling irqs with an irq-safe lock held: |
| 851 | 868 | */ |
| @@ -875,6 +892,7 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock) · 23 unmodified lines | ||
| 875 | 892 | #include "locking-selftest-wlock-hardirq.h" |
| 876 | 893 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock) |
| 877 | 894 | |
| 895 | +#ifndef CONFIG_PREEMPT_RT | |
| 878 | 896 | #include "locking-selftest-spin-softirq.h" |
| 879 | 897 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin) |
| 880 | 898 | |
| @@ -883,6 +901,7 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock) · 2 unmodified lines | ||
| 883 | 901 | |
| 884 | 902 | #include "locking-selftest-wlock-softirq.h" |
| 885 | 903 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock) |
| 904 | +#endif | |
| 886 | 905 | |
| 887 | 906 | #undef E1 |
| 888 | 907 | #undef E2 |
| @@ -921,6 +940,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock) · 32 unmodified lines | ||
| 921 | 940 | #include "locking-selftest-wlock-hardirq.h" |
| 922 | 941 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock) |
| 923 | 942 | |
| 943 | +#ifndef CONFIG_PREEMPT_RT | |
| 924 | 944 | #include "locking-selftest-spin-softirq.h" |
| 925 | 945 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin) |
| 926 | 946 | |
| @@ -929,6 +949,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock) · 2 unmodified lines | ||
| 929 | 949 | |
| 930 | 950 | #include "locking-selftest-wlock-softirq.h" |
| 931 | 951 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock) |
| 952 | +#endif | |
| 932 | 953 | |
| 933 | 954 | #undef E1 |
| 934 | 955 | #undef E2 |
| @@ -969,6 +990,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock) · 34 unmodified lines | ||
| 969 | 990 | #include "locking-selftest-wlock-hardirq.h" |
| 970 | 991 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock) |
| 971 | 992 | |
| 993 | +#ifndef CONFIG_PREEMPT_RT | |
| 972 | 994 | #include "locking-selftest-spin-softirq.h" |
| 973 | 995 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin) |
| 974 | 996 | |
| @@ -977,6 +999,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock) · 2 unmodified lines | ||
| 977 | 999 | |
| 978 | 1000 | #include "locking-selftest-wlock-softirq.h" |
| 979 | 1001 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock) |
| 1002 | +#endif | |
| 980 | 1003 | |
| 981 | 1004 | #undef E1 |
| 982 | 1005 | #undef E2 |
| @@ -1031,6 +1054,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock) · 48 unmodified lines | ||
| 1031 | 1054 | #include "locking-selftest-wlock-hardirq.h" |
| 1032 | 1055 | GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock) |
| 1033 | 1056 | |
| 1057 | +#ifndef CONFIG_PREEMPT_RT | |
| 1034 | 1058 | #include "locking-selftest-spin-softirq.h" |
| 1035 | 1059 | GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin) |
| 1036 | 1060 | |
| @@ -1039,6 +1063,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock) · 2 unmodified lines | ||
| 1039 | 1063 | |
| 1040 | 1064 | #include "locking-selftest-wlock-softirq.h" |
| 1041 | 1065 | GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock) |
| 1066 | +#endif | |
| 1042 | 1067 | |
| 1043 | 1068 | #undef E1 |
| 1044 | 1069 | #undef E2 |
| @@ -1206,12 +1231,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_rlock) · 161 unmodified lines | ||
| 1206 | 1231 | #include "locking-selftest-wlock.h" |
| 1207 | 1232 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_wlock) |
| 1208 | 1233 | |
| 1234 | +#ifndef CONFIG_PREEMPT_RT | |
| 1209 | 1235 | #include "locking-selftest-softirq.h" |
| 1210 | 1236 | #include "locking-selftest-rlock.h" |
| 1211 | 1237 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_rlock) |
| 1212 | 1238 | |
| 1213 | 1239 | #include "locking-selftest-wlock.h" |
| 1214 | 1240 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_wlock) |
| 1241 | +#endif | |
| 1215 | 1242 | |
| 1216 | 1243 | #undef E1 |
| 1217 | 1244 | #undef E2 |
| @@ -1252,12 +1279,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_rlock) · 34 unmodified lines | ||
| 1252 | 1279 | #include "locking-selftest-wlock.h" |
| 1253 | 1280 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_wlock) |
| 1254 | 1281 | |
| 1282 | +#ifndef CONFIG_PREEMPT_RT | |
| 1255 | 1283 | #include "locking-selftest-softirq.h" |
| 1256 | 1284 | #include "locking-selftest-rlock.h" |
| 1257 | 1285 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_rlock) |
| 1258 | 1286 | |
| 1259 | 1287 | #include "locking-selftest-wlock.h" |
| 1260 | 1288 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_wlock) |
| 1289 | +#endif | |
| 1261 | 1290 | |
| 1262 | 1291 | #undef E1 |
| 1263 | 1292 | #undef E2 |
| @@ -1306,12 +1335,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_rlock) · 42 unmodified lines | ||
| 1306 | 1335 | #include "locking-selftest-wlock.h" |
| 1307 | 1336 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_wlock) |
| 1308 | 1337 | |
| 1338 | +#ifndef CONFIG_PREEMPT_RT | |
| 1309 | 1339 | #include "locking-selftest-softirq.h" |
| 1310 | 1340 | #include "locking-selftest-rlock.h" |
| 1311 | 1341 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_rlock) |
| 1312 | 1342 | |
| 1313 | 1343 | #include "locking-selftest-wlock.h" |
| 1314 | 1344 | GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_wlock) |
| 1345 | +#endif | |
| 1315 | 1346 | |
| 1316 | 1347 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 1317 | 1348 | # define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map) |
| @@ -1320,7 +1351,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_wlock) · 2 unmodified lines | ||
| 1320 | 1351 | # define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map) |
| 1321 | 1352 | # define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map) |
| 1322 | 1353 | # define I_WW(x) lockdep_reset_lock(&x.dep_map) |
| 1323 | −# define I_LOCAL_LOCK(x) lockdep_reset_lock(&local_##x.dep_map) | |
| 1354 | +# define I_LOCAL_LOCK(x) lockdep_reset_lock(this_cpu_ptr(&local_##x.dep_map)) | |
| 1324 | 1355 | #ifdef CONFIG_RT_MUTEXES |
| 1325 | 1356 | # define I_RTMUTEX(x) lockdep_reset_lock(&rtmutex_##x.dep_map) |
| 1326 | 1357 | #endif |
| @@ -1380,7 +1411,7 @@ static void reset_locks(void) · 53 unmodified lines | ||
| 1380 | 1411 | init_shared_classes(); |
| 1381 | 1412 | raw_spin_lock_init(&raw_lock_A); |
| 1382 | 1413 | raw_spin_lock_init(&raw_lock_B); |
| 1383 | − local_lock_init(&local_A); | |
| 1414 | + local_lock_init(this_cpu_ptr(&local_A)); | |
| 1384 | 1415 | |
| 1385 | 1416 | ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep); |
| 1386 | 1417 | memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2)); |
| @@ -1398,7 +1429,13 @@ static int unexpected_testcase_failures; · 11 unmodified lines | ||
| 1398 | 1429 | |
| 1399 | 1430 | static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) |
| 1400 | 1431 | { |
| 1401 | − unsigned long saved_preempt_count = preempt_count(); | |
| 1432 | + int saved_preempt_count = preempt_count(); | |
| 1433 | +#ifdef CONFIG_PREEMPT_RT | |
| 1434 | +#ifdef CONFIG_SMP | |
| 1435 | + int saved_mgd_count = current->migration_disabled; | |
| 1436 | +#endif | |
| 1437 | + int saved_rcu_count = current->rcu_read_lock_nesting; | |
| 1438 | +#endif | |
| 1402 | 1439 | |
| 1403 | 1440 | WARN_ON(irqs_disabled()); |
| 1404 | 1441 | |
| @@ -1432,6 +1469,18 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) · 27 unmodified lines | ||
| 1432 | 1469 | * count, so restore it: |
| 1433 | 1470 | */ |
| 1434 | 1471 | preempt_count_set(saved_preempt_count); |
| 1472 | + | |
| 1473 | +#ifdef CONFIG_PREEMPT_RT | |
| 1474 | +#ifdef CONFIG_SMP | |
| 1475 | + while (current->migration_disabled > saved_mgd_count) | |
| 1476 | + migrate_enable(); | |
| 1477 | +#endif | |
| 1478 | + | |
| 1479 | + while (current->rcu_read_lock_nesting > saved_rcu_count) | |
| 1480 | + rcu_read_unlock(); | |
| 1481 | + WARN_ON_ONCE(current->rcu_read_lock_nesting < saved_rcu_count); | |
| 1482 | +#endif | |
| 1483 | + | |
| 1435 | 1484 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 1436 | 1485 | if (softirq_count()) |
| 1437 | 1486 | current->softirqs_enabled = 0; |
| @@ -1499,7 +1548,7 @@ static inline void print_testname(const char *testname) · 61 unmodified lines | ||
| 1499 | 1548 | |
| 1500 | 1549 | #define DO_TESTCASE_2x2RW(desc, name, nr) \ |
| 1501 | 1550 | DO_TESTCASE_2RW("hard-"desc, name##_hard, nr) \ |
| 1502 | − DO_TESTCASE_2RW("soft-"desc, name##_soft, nr) \ | |
| 1551 | + NON_RT(DO_TESTCASE_2RW("soft-"desc, name##_soft, nr)) \ | |
| 1503 | 1552 | |
| 1504 | 1553 | #define DO_TESTCASE_6x2x2RW(desc, name) \ |
| 1505 | 1554 | DO_TESTCASE_2x2RW(desc, name, 123); \ |
| @@ -1547,19 +1596,19 @@ static inline void print_testname(const char *testname) · 41 unmodified lines | ||
| 1547 | 1596 | |
| 1548 | 1597 | #define DO_TESTCASE_2I(desc, name, nr) \ |
| 1549 | 1598 | DO_TESTCASE_1("hard-"desc, name##_hard, nr); \ |
| 1550 | − DO_TESTCASE_1("soft-"desc, name##_soft, nr); | |
| 1599 | + NON_RT(DO_TESTCASE_1("soft-"desc, name##_soft, nr)); | |
| 1551 | 1600 | |
| 1552 | 1601 | #define DO_TESTCASE_2IB(desc, name, nr) \ |
| 1553 | 1602 | DO_TESTCASE_1B("hard-"desc, name##_hard, nr); \ |
| 1554 | − DO_TESTCASE_1B("soft-"desc, name##_soft, nr); | |
| 1603 | + NON_RT(DO_TESTCASE_1B("soft-"desc, name##_soft, nr)); | |
| 1555 | 1604 | |
| 1556 | 1605 | #define DO_TESTCASE_6I(desc, name, nr) \ |
| 1557 | 1606 | DO_TESTCASE_3("hard-"desc, name##_hard, nr); \ |
| 1558 | − DO_TESTCASE_3("soft-"desc, name##_soft, nr); | |
| 1607 | + NON_RT(DO_TESTCASE_3("soft-"desc, name##_soft, nr)); | |
| 1559 | 1608 | |
| 1560 | 1609 | #define DO_TESTCASE_6IRW(desc, name, nr) \ |
| 1561 | 1610 | DO_TESTCASE_3RW("hard-"desc, name##_hard, nr); \ |
| 1562 | − DO_TESTCASE_3RW("soft-"desc, name##_soft, nr); | |
| 1611 | + NON_RT(DO_TESTCASE_3RW("soft-"desc, name##_soft, nr)); | |
| 1563 | 1612 | |
| 1564 | 1613 | #define DO_TESTCASE_2x3(desc, name) \ |
| 1565 | 1614 | DO_TESTCASE_3(desc, name, 12); \ |
| @@ -1651,6 +1700,22 @@ static void ww_test_fail_acquire(void) · 85 unmodified lines | ||
| 1651 | 1700 | #endif |
| 1652 | 1701 | } |
| 1653 | 1702 | |
| 1703 | +#ifdef CONFIG_PREEMPT_RT | |
| 1704 | +#define ww_mutex_base_lock(b) rt_mutex_lock(b) | |
| 1705 | +#define ww_mutex_base_trylock(b) rt_mutex_trylock(b) | |
| 1706 | +#define ww_mutex_base_lock_nest_lock(b, b2) rt_mutex_lock_nest_lock(b, b2) | |
| 1707 | +#define ww_mutex_base_lock_interruptible(b) rt_mutex_lock_interruptible(b) | |
| 1708 | +#define ww_mutex_base_lock_killable(b) rt_mutex_lock_killable(b) | |
| 1709 | +#define ww_mutex_base_unlock(b) rt_mutex_unlock(b) | |
| 1710 | +#else | |
| 1711 | +#define ww_mutex_base_lock(b) mutex_lock(b) | |
| 1712 | +#define ww_mutex_base_trylock(b) mutex_trylock(b) | |
| 1713 | +#define ww_mutex_base_lock_nest_lock(b, b2) mutex_lock_nest_lock(b, b2) | |
| 1714 | +#define ww_mutex_base_lock_interruptible(b) mutex_lock_interruptible(b) | |
| 1715 | +#define ww_mutex_base_lock_killable(b) mutex_lock_killable(b) | |
| 1716 | +#define ww_mutex_base_unlock(b) mutex_unlock(b) | |
| 1717 | +#endif | |
| 1718 | + | |
| 1654 | 1719 | static void ww_test_normal(void) |
| 1655 | 1720 | { |
| 1656 | 1721 | int ret; |
| @@ -1665,50 +1730,50 @@ static void ww_test_normal(void) · 8 unmodified lines | ||
| 1665 | 1730 | |
| 1666 | 1731 | /* mutex_lock (and indirectly, mutex_lock_nested) */ |
| 1667 | 1732 | o.ctx = (void *)~0UL; |
| 1668 | − mutex_lock(&o.base); | |
| 1669 | − mutex_unlock(&o.base); | |
| 1733 | + ww_mutex_base_lock(&o.base); | |
| 1734 | + ww_mutex_base_unlock(&o.base); | |
| 1670 | 1735 | WARN_ON(o.ctx != (void *)~0UL); |
| 1671 | 1736 | |
| 1672 | 1737 | /* mutex_lock_interruptible (and *_nested) */ |
| 1673 | 1738 | o.ctx = (void *)~0UL; |
| 1674 | − ret = mutex_lock_interruptible(&o.base); | |
| 1739 | + ret = ww_mutex_base_lock_interruptible(&o.base); | |
| 1675 | 1740 | if (!ret) |
| 1676 | − mutex_unlock(&o.base); | |
| 1741 | + ww_mutex_base_unlock(&o.base); | |
| 1677 | 1742 | else |
| 1678 | 1743 | WARN_ON(1); |
| 1679 | 1744 | WARN_ON(o.ctx != (void *)~0UL); |
| 1680 | 1745 | |
| 1681 | 1746 | /* mutex_lock_killable (and *_nested) */ |
| 1682 | 1747 | o.ctx = (void *)~0UL; |
| 1683 | − ret = mutex_lock_killable(&o.base); | |
| 1748 | + ret = ww_mutex_base_lock_killable(&o.base); | |
| 1684 | 1749 | if (!ret) |
| 1685 | − mutex_unlock(&o.base); | |
| 1750 | + ww_mutex_base_unlock(&o.base); | |
| 1686 | 1751 | else |
| 1687 | 1752 | WARN_ON(1); |
| 1688 | 1753 | WARN_ON(o.ctx != (void *)~0UL); |
| 1689 | 1754 | |
| 1690 | 1755 | /* trylock, succeeding */ |
| 1691 | 1756 | o.ctx = (void *)~0UL; |
| 1692 | − ret = mutex_trylock(&o.base); | |
| 1757 | + ret = ww_mutex_base_trylock(&o.base); | |
| 1693 | 1758 | WARN_ON(!ret); |
| 1694 | 1759 | if (ret) |
| 1695 | − mutex_unlock(&o.base); | |
| 1760 | + ww_mutex_base_unlock(&o.base); | |
| 1696 | 1761 | else |
| 1697 | 1762 | WARN_ON(1); |
| 1698 | 1763 | WARN_ON(o.ctx != (void *)~0UL); |
| 1699 | 1764 | |
| 1700 | 1765 | /* trylock, failing */ |
| 1701 | 1766 | o.ctx = (void *)~0UL; |
| 1702 | − mutex_lock(&o.base); | |
| 1703 | − ret = mutex_trylock(&o.base); | |
| 1767 | + ww_mutex_base_lock(&o.base); | |
| 1768 | + ret = ww_mutex_base_trylock(&o.base); | |
| 1704 | 1769 | WARN_ON(ret); |
| 1705 | − mutex_unlock(&o.base); | |
| 1770 | + ww_mutex_base_unlock(&o.base); | |
| 1706 | 1771 | WARN_ON(o.ctx != (void *)~0UL); |
| 1707 | 1772 | |
| 1708 | 1773 | /* nest_lock */ |
| 1709 | 1774 | o.ctx = (void *)~0UL; |
| 1710 | − mutex_lock_nest_lock(&o.base, &t); | |
| 1711 | − mutex_unlock(&o.base); | |
| 1775 | + ww_mutex_base_lock_nest_lock(&o.base, &t); | |
| 1776 | + ww_mutex_base_unlock(&o.base); | |
| 1712 | 1777 | WARN_ON(o.ctx != (void *)~0UL); |
| 1713 | 1778 | } |
| 1714 | 1779 | |
| @@ -1721,7 +1786,7 @@ static void ww_test_two_contexts(void) · 6 unmodified lines | ||
| 1721 | 1786 | static void ww_test_diff_class(void) |
| 1722 | 1787 | { |
| 1723 | 1788 | WWAI(&t); |
| 1724 | −#ifdef CONFIG_DEBUG_MUTEXES | |
| 1789 | +#ifdef DEBUG_WW_MUTEXES | |
| 1725 | 1790 | t.ww_class = NULL; |
| 1726 | 1791 | #endif |
| 1727 | 1792 | WWL(&o, &t); |
| @@ -1785,7 +1850,7 @@ static void ww_test_edeadlk_normal(void) · 57 unmodified lines | ||
| 1785 | 1850 | { |
| 1786 | 1851 | int ret; |
| 1787 | 1852 | |
| 1788 | − mutex_lock(&o2.base); | |
| 1853 | + ww_mutex_base_lock(&o2.base); | |
| 1789 | 1854 | o2.ctx = &t2; |
| 1790 | 1855 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1791 | 1856 | |
| @@ -1801,7 +1866,7 @@ static void ww_test_edeadlk_normal(void) · 9 unmodified lines | ||
| 1801 | 1866 | |
| 1802 | 1867 | o2.ctx = NULL; |
| 1803 | 1868 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); |
| 1804 | − mutex_unlock(&o2.base); | |
| 1869 | + ww_mutex_base_unlock(&o2.base); | |
| 1805 | 1870 | WWU(&o); |
| 1806 | 1871 | |
| 1807 | 1872 | WWL(&o2, &t); |
| @@ -1811,7 +1876,7 @@ static void ww_test_edeadlk_normal_slow(void) · 3 unmodified lines | ||
| 1811 | 1876 | { |
| 1812 | 1877 | int ret; |
| 1813 | 1878 | |
| 1814 | − mutex_lock(&o2.base); | |
| 1879 | + ww_mutex_base_lock(&o2.base); | |
| 1815 | 1880 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1816 | 1881 | o2.ctx = &t2; |
| 1817 | 1882 | |
| @@ -1827,7 +1892,7 @@ static void ww_test_edeadlk_normal_slow(void) · 9 unmodified lines | ||
| 1827 | 1892 | |
| 1828 | 1893 | o2.ctx = NULL; |
| 1829 | 1894 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); |
| 1830 | − mutex_unlock(&o2.base); | |
| 1895 | + ww_mutex_base_unlock(&o2.base); | |
| 1831 | 1896 | WWU(&o); |
| 1832 | 1897 | |
| 1833 | 1898 | ww_mutex_lock_slow(&o2, &t); |
| @@ -1837,7 +1902,7 @@ static void ww_test_edeadlk_no_unlock(void) · 3 unmodified lines | ||
| 1837 | 1902 | { |
| 1838 | 1903 | int ret; |
| 1839 | 1904 | |
| 1840 | − mutex_lock(&o2.base); | |
| 1905 | + ww_mutex_base_lock(&o2.base); | |
| 1841 | 1906 | o2.ctx = &t2; |
| 1842 | 1907 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1843 | 1908 | |
| @@ -1853,7 +1918,7 @@ static void ww_test_edeadlk_no_unlock(void) · 9 unmodified lines | ||
| 1853 | 1918 | |
| 1854 | 1919 | o2.ctx = NULL; |
| 1855 | 1920 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); |
| 1856 | − mutex_unlock(&o2.base); | |
| 1921 | + ww_mutex_base_unlock(&o2.base); | |
| 1857 | 1922 | |
| 1858 | 1923 | WWL(&o2, &t); |
| 1859 | 1924 | } |
| @@ -1862,7 +1927,7 @@ static void ww_test_edeadlk_no_unlock_slow(void) · 2 unmodified lines | ||
| 1862 | 1927 | { |
| 1863 | 1928 | int ret; |
| 1864 | 1929 | |
| 1865 | − mutex_lock(&o2.base); | |
| 1930 | + ww_mutex_base_lock(&o2.base); | |
| 1866 | 1931 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1867 | 1932 | o2.ctx = &t2; |
| 1868 | 1933 | |
| @@ -1878,7 +1943,7 @@ static void ww_test_edeadlk_no_unlock_slow(void) · 9 unmodified lines | ||
| 1878 | 1943 | |
| 1879 | 1944 | o2.ctx = NULL; |
| 1880 | 1945 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); |
| 1881 | − mutex_unlock(&o2.base); | |
| 1946 | + ww_mutex_base_unlock(&o2.base); | |
| 1882 | 1947 | |
| 1883 | 1948 | ww_mutex_lock_slow(&o2, &t); |
| 1884 | 1949 | } |
| @@ -1887,7 +1952,7 @@ static void ww_test_edeadlk_acquire_more(void) · 2 unmodified lines | ||
| 1887 | 1952 | { |
| 1888 | 1953 | int ret; |
| 1889 | 1954 | |
| 1890 | − mutex_lock(&o2.base); | |
| 1955 | + ww_mutex_base_lock(&o2.base); | |
| 1891 | 1956 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1892 | 1957 | o2.ctx = &t2; |
| 1893 | 1958 | |
| @@ -1908,7 +1973,7 @@ static void ww_test_edeadlk_acquire_more_slow(void) · 14 unmodified lines | ||
| 1908 | 1973 | { |
| 1909 | 1974 | int ret; |
| 1910 | 1975 | |
| 1911 | − mutex_lock(&o2.base); | |
| 1976 | + ww_mutex_base_lock(&o2.base); | |
| 1912 | 1977 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1913 | 1978 | o2.ctx = &t2; |
| 1914 | 1979 | |
| @@ -1929,11 +1994,11 @@ static void ww_test_edeadlk_acquire_more_edeadlk(void) · 14 unmodified lines | ||
| 1929 | 1994 | { |
| 1930 | 1995 | int ret; |
| 1931 | 1996 | |
| 1932 | − mutex_lock(&o2.base); | |
| 1997 | + ww_mutex_base_lock(&o2.base); | |
| 1933 | 1998 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1934 | 1999 | o2.ctx = &t2; |
| 1935 | 2000 | |
| 1936 | − mutex_lock(&o3.base); | |
| 2001 | + ww_mutex_base_lock(&o3.base); | |
| 1937 | 2002 | mutex_release(&o3.base.dep_map, _THIS_IP_); |
| 1938 | 2003 | o3.ctx = &t2; |
| 1939 | 2004 | |
| @@ -1955,11 +2020,11 @@ static void ww_test_edeadlk_acquire_more_edeadlk_slow(void) · 15 unmodified lines | ||
| 1955 | 2020 | { |
| 1956 | 2021 | int ret; |
| 1957 | 2022 | |
| 1958 | − mutex_lock(&o2.base); | |
| 2023 | + ww_mutex_base_lock(&o2.base); | |
| 1959 | 2024 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1960 | 2025 | o2.ctx = &t2; |
| 1961 | 2026 | |
| 1962 | − mutex_lock(&o3.base); | |
| 2027 | + ww_mutex_base_lock(&o3.base); | |
| 1963 | 2028 | mutex_release(&o3.base.dep_map, _THIS_IP_); |
| 1964 | 2029 | o3.ctx = &t2; |
| 1965 | 2030 | |
| @@ -1980,7 +2045,7 @@ static void ww_test_edeadlk_acquire_wrong(void) · 14 unmodified lines | ||
| 1980 | 2045 | { |
| 1981 | 2046 | int ret; |
| 1982 | 2047 | |
| 1983 | − mutex_lock(&o2.base); | |
| 2048 | + ww_mutex_base_lock(&o2.base); | |
| 1984 | 2049 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 1985 | 2050 | o2.ctx = &t2; |
| 1986 | 2051 | |
| @@ -2005,7 +2070,7 @@ static void ww_test_edeadlk_acquire_wrong_slow(void) · 18 unmodified lines | ||
| 2005 | 2070 | { |
| 2006 | 2071 | int ret; |
| 2007 | 2072 | |
| 2008 | − mutex_lock(&o2.base); | |
| 2073 | + ww_mutex_base_lock(&o2.base); | |
| 2009 | 2074 | mutex_release(&o2.base.dep_map, _THIS_IP_); |
| 2010 | 2075 | o2.ctx = &t2; |
| 2011 | 2076 | |
| @@ -2646,8 +2711,8 @@ static void wait_context_tests(void) · 634 unmodified lines | ||
| 2646 | 2711 | |
| 2647 | 2712 | static void local_lock_2(void) |
| 2648 | 2713 | { |
| 2649 | − local_lock_acquire(&local_A); /* IRQ-ON */ | |
| 2650 | − local_lock_release(&local_A); | |
| 2714 | + local_lock(&local_A); /* IRQ-ON */ | |
| 2715 | + local_unlock(&local_A); | |
| 2651 | 2716 | |
| 2652 | 2717 | HARDIRQ_ENTER(); |
| 2653 | 2718 | spin_lock(&lock_A); /* IN-IRQ */ |
| @@ -2656,18 +2721,18 @@ static void local_lock_2(void) · 2 unmodified lines | ||
| 2656 | 2721 | |
| 2657 | 2722 | HARDIRQ_DISABLE(); |
| 2658 | 2723 | spin_lock(&lock_A); |
| 2659 | − local_lock_acquire(&local_A); /* IN-IRQ <-> IRQ-ON cycle, false */ | |
| 2660 | − local_lock_release(&local_A); | |
| 2724 | + local_lock(&local_A); /* IN-IRQ <-> IRQ-ON cycle, false */ | |
| 2725 | + local_unlock(&local_A); | |
| 2661 | 2726 | spin_unlock(&lock_A); |
| 2662 | 2727 | HARDIRQ_ENABLE(); |
| 2663 | 2728 | } |
| 2664 | 2729 | |
| 2665 | 2730 | static void local_lock_3A(void) |
| 2666 | 2731 | { |
| 2667 | − local_lock_acquire(&local_A); /* IRQ-ON */ | |
| 2732 | + local_lock(&local_A); /* IRQ-ON */ | |
| 2668 | 2733 | spin_lock(&lock_B); /* IRQ-ON */ |
| 2669 | 2734 | spin_unlock(&lock_B); |
| 2670 | − local_lock_release(&local_A); | |
| 2735 | + local_unlock(&local_A); | |
| 2671 | 2736 | |
| 2672 | 2737 | HARDIRQ_ENTER(); |
| 2673 | 2738 | spin_lock(&lock_A); /* IN-IRQ */ |
| @@ -2676,18 +2741,18 @@ static void local_lock_3A(void) · 2 unmodified lines | ||
| 2676 | 2741 | |
| 2677 | 2742 | HARDIRQ_DISABLE(); |
| 2678 | 2743 | spin_lock(&lock_A); |
| 2679 | − local_lock_acquire(&local_A); /* IN-IRQ <-> IRQ-ON cycle only if we count local_lock(), false */ | |
| 2680 | − local_lock_release(&local_A); | |
| 2744 | + local_lock(&local_A); /* IN-IRQ <-> IRQ-ON cycle only if we count local_lock(), false */ | |
| 2745 | + local_unlock(&local_A); | |
| 2681 | 2746 | spin_unlock(&lock_A); |
| 2682 | 2747 | HARDIRQ_ENABLE(); |
| 2683 | 2748 | } |
| 2684 | 2749 | |
| 2685 | 2750 | static void local_lock_3B(void) |
| 2686 | 2751 | { |
| 2687 | − local_lock_acquire(&local_A); /* IRQ-ON */ | |
| 2752 | + local_lock(&local_A); /* IRQ-ON */ | |
| 2688 | 2753 | spin_lock(&lock_B); /* IRQ-ON */ |
| 2689 | 2754 | spin_unlock(&lock_B); |
| 2690 | − local_lock_release(&local_A); | |
| 2755 | + local_unlock(&local_A); | |
| 2691 | 2756 | |
| 2692 | 2757 | HARDIRQ_ENTER(); |
| 2693 | 2758 | spin_lock(&lock_A); /* IN-IRQ */ |
| @@ -2696,8 +2761,8 @@ static void local_lock_3B(void) · 2 unmodified lines | ||
| 2696 | 2761 | |
| 2697 | 2762 | HARDIRQ_DISABLE(); |
| 2698 | 2763 | spin_lock(&lock_A); |
| 2699 | − local_lock_acquire(&local_A); /* IN-IRQ <-> IRQ-ON cycle only if we count local_lock(), false */ | |
| 2700 | − local_lock_release(&local_A); | |
| 2764 | + local_lock(&local_A); /* IN-IRQ <-> IRQ-ON cycle only if we count local_lock(), false */ | |
| 2765 | + local_unlock(&local_A); | |
| 2701 | 2766 | spin_unlock(&lock_A); |
| 2702 | 2767 | HARDIRQ_ENABLE(); |
| 2703 | 2768 | |
| @@ -2812,7 +2877,7 @@ void locking_selftest(void) · 108 unmodified lines | ||
| 2812 | 2877 | printk("------------------------\n"); |
| 2813 | 2878 | printk("| Locking API testsuite:\n"); |
| 2814 | 2879 | printk("----------------------------------------------------------------------------\n"); |
| 2815 | − printk(" | spin |wlock |rlock |mutex | wsem | rsem |\n"); | |
| 2880 | + printk(" | spin |wlock |rlock |mutex | wsem | rsem |rtmutex\n"); | |
| 2816 | 2881 | printk(" --------------------------------------------------------------------------\n"); |
| 2817 | 2882 | |
| 2818 | 2883 | init_shared_classes(); |
| @@ -2885,12 +2950,11 @@ void locking_selftest(void) · 66 unmodified lines | ||
| 2885 | 2950 | DO_TESTCASE_6x1RR("rlock W1R2/R2R3/W3W1", W1R2_R2R3_W3W1); |
| 2886 | 2951 | |
| 2887 | 2952 | printk(" --------------------------------------------------------------------------\n"); |
| 2888 | − | |
| 2889 | 2953 | /* |
| 2890 | 2954 | * irq-context testcases: |
| 2891 | 2955 | */ |
| 2892 | 2956 | DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1); |
| 2893 | − DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A); | |
| 2957 | + NON_RT(DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A)); | |
| 2894 | 2958 | DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B); |
| 2895 | 2959 | DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3); |
| 2896 | 2960 | DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4); |