Skip to content

Commit e01cc1e

Browse files
ubizjakingomolnar
authored andcommitted
locking/atomic: Add generic support for sync_try_cmpxchg() and its fallback
Provide the generic sync_try_cmpxchg() function from the raw_ prefixed version, also adding explicit instrumentation. The patch amends existing scripts to generate sync_try_cmpxchg() locking primitive and its raw_sync_try_cmpxchg() fallback, while leaving existing macros from the try_cmpxchg() family unchanged. The target can define its own arch_sync_try_cmpxchg() to override the generic version of raw_sync_try_cmpxchg(). This allows the target to generate more optimal assembly than the generic version. Additionally, the patch renames two scripts to better reflect whet they really do. Signed-off-by: Uros Bizjak <ubizjak@gmail.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: Will Deacon <will@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: linux-kernel@vger.kernel.org
1 parent fdb8b7a commit e01cc1e

4 files changed

Lines changed: 43 additions & 18 deletions

File tree

include/linux/atomic/atomic-arch-fallback.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,19 @@ extern void raw_cmpxchg128_relaxed_not_implemented(void);
428428

429429
#define raw_sync_cmpxchg arch_sync_cmpxchg
430430

431+
#ifdef arch_sync_try_cmpxchg
432+
#define raw_sync_try_cmpxchg arch_sync_try_cmpxchg
433+
#else
434+
#define raw_sync_try_cmpxchg(_ptr, _oldp, _new) \
435+
({ \
436+
typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \
437+
___r = raw_sync_cmpxchg((_ptr), ___o, (_new)); \
438+
if (unlikely(___r != ___o)) \
439+
*___op = ___r; \
440+
likely(___r == ___o); \
441+
})
442+
#endif
443+
431444
/**
432445
* raw_atomic_read() - atomic load with relaxed ordering
433446
* @v: pointer to atomic_t
@@ -4649,4 +4662,4 @@ raw_atomic64_dec_if_positive(atomic64_t *v)
46494662
}
46504663

46514664
#endif /* _LINUX_ATOMIC_FALLBACK_H */
4652-
// 2fdd6702823fa842f9cea57a002e6e4476ae780c
4665+
// eec048affea735b8464f58e6d96992101f8f85f1

include/linux/atomic/atomic-instrumented.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4998,6 +4998,14 @@ atomic_long_dec_if_positive(atomic_long_t *v)
49984998
raw_try_cmpxchg128_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \
49994999
})
50005000

5001+
#define sync_try_cmpxchg(ptr, ...) \
5002+
({ \
5003+
typeof(ptr) __ai_ptr = (ptr); \
5004+
kcsan_mb(); \
5005+
instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \
5006+
raw_sync_try_cmpxchg(__ai_ptr, __VA_ARGS__); \
5007+
})
5008+
50015009

50025010
#endif /* _LINUX_ATOMIC_INSTRUMENTED_H */
5003-
// 1568f875fef72097413caab8339120c065a39aa4
5011+
// 2cc4bc990fef44d3836ec108f11b610f3f438184

scripts/atomic/gen-atomic-fallback.sh

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,15 @@ gen_xchg_fallbacks()
223223

224224
gen_try_cmpxchg_fallback()
225225
{
226+
local prefix="$1"; shift
226227
local cmpxchg="$1"; shift;
227-
local order="$1"; shift;
228+
local suffix="$1"; shift;
228229

229230
cat <<EOF
230-
#define raw_try_${cmpxchg}${order}(_ptr, _oldp, _new) \\
231+
#define raw_${prefix}try_${cmpxchg}${suffix}(_ptr, _oldp, _new) \\
231232
({ \\
232233
typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \\
233-
___r = raw_${cmpxchg}${order}((_ptr), ___o, (_new)); \\
234+
___r = raw_${prefix}${cmpxchg}${suffix}((_ptr), ___o, (_new)); \\
234235
if (unlikely(___r != ___o)) \\
235236
*___op = ___r; \\
236237
likely(___r == ___o); \\
@@ -259,11 +260,11 @@ gen_try_cmpxchg_order_fallback()
259260
fi
260261

261262
printf "#else\n"
262-
gen_try_cmpxchg_fallback "${cmpxchg}" "${order}"
263+
gen_try_cmpxchg_fallback "" "${cmpxchg}" "${order}"
263264
printf "#endif\n\n"
264265
}
265266

266-
gen_try_cmpxchg_fallbacks()
267+
gen_try_cmpxchg_order_fallbacks()
267268
{
268269
local cmpxchg="$1"; shift;
269270

@@ -272,15 +273,17 @@ gen_try_cmpxchg_fallbacks()
272273
done
273274
}
274275

275-
gen_cmpxchg_local_fallbacks()
276+
gen_def_and_try_cmpxchg_fallback()
276277
{
278+
local prefix="$1"; shift
277279
local cmpxchg="$1"; shift
280+
local suffix="$1"; shift
278281

279-
printf "#define raw_${cmpxchg} arch_${cmpxchg}\n\n"
280-
printf "#ifdef arch_try_${cmpxchg}\n"
281-
printf "#define raw_try_${cmpxchg} arch_try_${cmpxchg}\n"
282+
printf "#define raw_${prefix}${cmpxchg}${suffix} arch_${prefix}${cmpxchg}${suffix}\n\n"
283+
printf "#ifdef arch_${prefix}try_${cmpxchg}${suffix}\n"
284+
printf "#define raw_${prefix}try_${cmpxchg}${suffix} arch_${prefix}try_${cmpxchg}${suffix}\n"
282285
printf "#else\n"
283-
gen_try_cmpxchg_fallback "${cmpxchg}" ""
286+
gen_try_cmpxchg_fallback "${prefix}" "${cmpxchg}" "${suffix}"
284287
printf "#endif\n\n"
285288
}
286289

@@ -302,15 +305,15 @@ for xchg in "xchg" "cmpxchg" "cmpxchg64" "cmpxchg128"; do
302305
done
303306

304307
for cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do
305-
gen_try_cmpxchg_fallbacks "${cmpxchg}"
308+
gen_try_cmpxchg_order_fallbacks "${cmpxchg}"
306309
done
307310

308-
for cmpxchg in "cmpxchg_local" "cmpxchg64_local" "cmpxchg128_local"; do
309-
gen_cmpxchg_local_fallbacks "${cmpxchg}" ""
311+
for cmpxchg in "cmpxchg" "cmpxchg64" "cmpxchg128"; do
312+
gen_def_and_try_cmpxchg_fallback "" "${cmpxchg}" "_local"
310313
done
311314

312-
for cmpxchg in "sync_cmpxchg"; do
313-
printf "#define raw_${cmpxchg} arch_${cmpxchg}\n\n"
315+
for cmpxchg in "cmpxchg"; do
316+
gen_def_and_try_cmpxchg_fallback "sync_" "${cmpxchg}" ""
314317
done
315318

316319
grep '^[a-z]' "$1" | while read name meta args; do

scripts/atomic/gen-atomic-instrumented.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ for xchg in "xchg" "cmpxchg" "cmpxchg64" "cmpxchg128" "try_cmpxchg" "try_cmpxchg
169169
done
170170
done
171171

172-
for xchg in "cmpxchg_local" "cmpxchg64_local" "cmpxchg128_local" "sync_cmpxchg" "try_cmpxchg_local" "try_cmpxchg64_local" "try_cmpxchg128_local"; do
172+
for xchg in "cmpxchg_local" "cmpxchg64_local" "cmpxchg128_local" "sync_cmpxchg" \
173+
"try_cmpxchg_local" "try_cmpxchg64_local" "try_cmpxchg128_local" "sync_try_cmpxchg"; do
173174
gen_xchg "${xchg}" ""
174175
printf "\n"
175176
done

0 commit comments

Comments
 (0)