Hi,
You will find in this series updates to the rseq selftests, mainly bringing fixes from librseq project back into the RSEQ selftests.
Thanks,
Mathieu
Mathieu Desnoyers (4): selftests/rseq: Fix CID_ID typo in Makefile selftests/rseq: Implement rseq_unqual_scalar_typeof selftests/rseq: Fix arm64 buggy load-acquire/store-release macros selftests/rseq: Use rseq_unqual_scalar_typeof in macros
tools/testing/selftests/rseq/Makefile | 2 +- tools/testing/selftests/rseq/compiler.h | 26 ++++++++++ tools/testing/selftests/rseq/rseq-arm.h | 4 +- tools/testing/selftests/rseq/rseq-arm64.h | 58 ++++++++++++----------- tools/testing/selftests/rseq/rseq-mips.h | 4 +- tools/testing/selftests/rseq/rseq-ppc.h | 4 +- tools/testing/selftests/rseq/rseq-riscv.h | 6 +-- tools/testing/selftests/rseq/rseq-s390.h | 4 +- tools/testing/selftests/rseq/rseq-x86.h | 4 +- 9 files changed, 70 insertions(+), 42 deletions(-)
Ensure that the basic percpu ops tests are effectively built against mm_cid.
Signed-off-by: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Peter Zijlstra peterz@infradead.org --- tools/testing/selftests/rseq/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/rseq/Makefile b/tools/testing/selftests/rseq/Makefile index b357ba24af06..8f023b7cab60 100644 --- a/tools/testing/selftests/rseq/Makefile +++ b/tools/testing/selftests/rseq/Makefile @@ -31,7 +31,7 @@ $(OUTPUT)/%: %.c $(TEST_GEN_PROGS_EXTENDED) rseq.h rseq-*.h $(CC) $(CFLAGS) $< $(LDLIBS) -lrseq -o $@
$(OUTPUT)/basic_percpu_ops_mm_cid_test: basic_percpu_ops_test.c $(TEST_GEN_PROGS_EXTENDED) rseq.h rseq-*.h - $(CC) $(CFLAGS) -DBUILDOPT_RSEQ_PERCPU_MM_CID_ID $< $(LDLIBS) -lrseq -o $@ + $(CC) $(CFLAGS) -DBUILDOPT_RSEQ_PERCPU_MM_CID $< $(LDLIBS) -lrseq -o $@
$(OUTPUT)/param_test_benchmark: param_test.c $(TEST_GEN_PROGS_EXTENDED) \ rseq.h rseq-*.h
Allow defining variables and perform cast with a typeof which removes the volatile and const qualifiers.
This prevents declaring a stack variable with a volatile qualifier within a macro, which would generate sub-optimal assembler.
This is imported from the "librseq" project.
Signed-off-by: Mathieu Desnoyers mathieu.desnoyers@efficios.com --- tools/testing/selftests/rseq/compiler.h | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/tools/testing/selftests/rseq/compiler.h b/tools/testing/selftests/rseq/compiler.h index f47092bddeba..49d62fbd6dda 100644 --- a/tools/testing/selftests/rseq/compiler.h +++ b/tools/testing/selftests/rseq/compiler.h @@ -33,4 +33,30 @@ #define RSEQ_COMBINE_TOKENS(_tokena, _tokenb) \ RSEQ__COMBINE_TOKENS(_tokena, _tokenb)
+#ifdef __cplusplus +#define rseq_unqual_scalar_typeof(x) \ + std::remove_cv<std::remove_reference<decltype(x)>::type>::type +#else +#define rseq_scalar_type_to_expr(type) \ + unsigned type: (unsigned type)0, \ + signed type: (signed type)0 + +/* + * Use C11 _Generic to express unqualified type from expression. This removes + * volatile qualifier from expression type. + */ +#define rseq_unqual_scalar_typeof(x) \ + __typeof__( \ + _Generic((x), \ + char: (char)0, \ + rseq_scalar_type_to_expr(char), \ + rseq_scalar_type_to_expr(short), \ + rseq_scalar_type_to_expr(int), \ + rseq_scalar_type_to_expr(long), \ + rseq_scalar_type_to_expr(long long), \ + default: (x) \ + ) \ + ) +#endif + #endif /* RSEQ_COMPILER_H_ */
The arm64 load-acquire/store-release macros from the Linux kernel rseq selftests are buggy. Remplace them by a working implementation.
Signed-off-by: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Will Deacon will@kernel.org Cc: Peter Zijlstra peterz@infradead.org --- tools/testing/selftests/rseq/rseq-arm64.h | 58 ++++++++++++----------- 1 file changed, 30 insertions(+), 28 deletions(-)
diff --git a/tools/testing/selftests/rseq/rseq-arm64.h b/tools/testing/selftests/rseq/rseq-arm64.h index 85b90977e7e6..21e1626a7235 100644 --- a/tools/testing/selftests/rseq/rseq-arm64.h +++ b/tools/testing/selftests/rseq/rseq-arm64.h @@ -27,59 +27,61 @@
#define rseq_smp_load_acquire(p) \ __extension__ ({ \ - __typeof(*p) ____p1; \ - switch (sizeof(*p)) { \ + union { rseq_unqual_scalar_typeof(*(p)) __val; char __c[sizeof(*(p))]; } __u; \ + switch (sizeof(*(p))) { \ case 1: \ - asm volatile ("ldarb %w0, %1" \ - : "=r" (*(__u8 *)p) \ - : "Q" (*p) : "memory"); \ + __asm__ __volatile__ ("ldarb %w0, %1" \ + : "=r" (*(__u8 *)__u.__c) \ + : "Q" (*(p)) : "memory"); \ break; \ case 2: \ - asm volatile ("ldarh %w0, %1" \ - : "=r" (*(__u16 *)p) \ - : "Q" (*p) : "memory"); \ + __asm__ __volatile__ ("ldarh %w0, %1" \ + : "=r" (*(__u16 *)__u.__c) \ + : "Q" (*(p)) : "memory"); \ break; \ case 4: \ - asm volatile ("ldar %w0, %1" \ - : "=r" (*(__u32 *)p) \ - : "Q" (*p) : "memory"); \ + __asm__ __volatile__ ("ldar %w0, %1" \ + : "=r" (*(__u32 *)__u.__c) \ + : "Q" (*(p)) : "memory"); \ break; \ case 8: \ - asm volatile ("ldar %0, %1" \ - : "=r" (*(__u64 *)p) \ - : "Q" (*p) : "memory"); \ + __asm__ __volatile__ ("ldar %0, %1" \ + : "=r" (*(__u64 *)__u.__c) \ + : "Q" (*(p)) : "memory"); \ break; \ } \ - ____p1; \ + (rseq_unqual_scalar_typeof(*(p)))__u.__val; \ })
#define rseq_smp_acquire__after_ctrl_dep() rseq_smp_rmb()
#define rseq_smp_store_release(p, v) \ do { \ - switch (sizeof(*p)) { \ + union { rseq_unqual_scalar_typeof(*(p)) __val; char __c[sizeof(*(p))]; } __u = \ + { .__val = (rseq_unqual_scalar_typeof(*(p))) (v) }; \ + switch (sizeof(*(p))) { \ case 1: \ - asm volatile ("stlrb %w1, %0" \ - : "=Q" (*p) \ - : "r" ((__u8)v) \ + __asm__ __volatile__ ("stlrb %w1, %0" \ + : "=Q" (*(p)) \ + : "r" (*(__u8 *)__u.__c) \ : "memory"); \ break; \ case 2: \ - asm volatile ("stlrh %w1, %0" \ - : "=Q" (*p) \ - : "r" ((__u16)v) \ + __asm__ __volatile__ ("stlrh %w1, %0" \ + : "=Q" (*(p)) \ + : "r" (*(__u16 *)__u.__c) \ : "memory"); \ break; \ case 4: \ - asm volatile ("stlr %w1, %0" \ - : "=Q" (*p) \ - : "r" ((__u32)v) \ + __asm__ __volatile__ ("stlr %w1, %0" \ + : "=Q" (*(p)) \ + : "r" (*(__u32 *)__u.__c) \ : "memory"); \ break; \ case 8: \ - asm volatile ("stlr %1, %0" \ - : "=Q" (*p) \ - : "r" ((__u64)v) \ + __asm__ __volatile__ ("stlr %1, %0" \ + : "=Q" (*(p)) \ + : "r" (*(__u64 *)__u.__c) \ : "memory"); \ break; \ } \
Use rseq_unqual_scalar_typeof() rather than typeof() in macros to remove the volatile qualifier (if there is one in the input argument), thus generating better assembly code in those scenarios.
Also add extra brackets around the "p" parameter in RSEQ_READ_ONCE(), RSEQ_WRITE_ONCE(), and rseq_unqual_scalar_typeof() across architectures to preserve expectations of operator priority. Here is an example that shows how operator priority may be an issue with missing parentheses:
#define m(p) \ do { \ __typeof__(*p) v = 0; \ } while (0)
void fct(unsigned long long *p1) { m(p1 + 1); /* works */ m(1 + p1); /* broken */ }
Signed-off-by: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Peter Zijlstra peterz@infradead.org --- tools/testing/selftests/rseq/rseq-arm.h | 4 ++-- tools/testing/selftests/rseq/rseq-mips.h | 4 ++-- tools/testing/selftests/rseq/rseq-ppc.h | 4 ++-- tools/testing/selftests/rseq/rseq-riscv.h | 6 +++--- tools/testing/selftests/rseq/rseq-s390.h | 4 ++-- tools/testing/selftests/rseq/rseq-x86.h | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/rseq/rseq-arm.h b/tools/testing/selftests/rseq/rseq-arm.h index 8414fc3eac15..d887b3bbe257 100644 --- a/tools/testing/selftests/rseq/rseq-arm.h +++ b/tools/testing/selftests/rseq/rseq-arm.h @@ -66,7 +66,7 @@
#define rseq_smp_load_acquire(p) \ __extension__ ({ \ - __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p); \ + rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p)); \ rseq_smp_mb(); \ ____p1; \ }) @@ -76,7 +76,7 @@ __extension__ ({ \ #define rseq_smp_store_release(p, v) \ do { \ rseq_smp_mb(); \ - RSEQ_WRITE_ONCE(*p, v); \ + RSEQ_WRITE_ONCE(*(p), v); \ } while (0)
#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip, \ diff --git a/tools/testing/selftests/rseq/rseq-mips.h b/tools/testing/selftests/rseq/rseq-mips.h index 50b950cf9585..42ef8e946693 100644 --- a/tools/testing/selftests/rseq/rseq-mips.h +++ b/tools/testing/selftests/rseq/rseq-mips.h @@ -45,7 +45,7 @@
#define rseq_smp_load_acquire(p) \ __extension__ ({ \ - __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p); \ + rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p)); \ rseq_smp_mb(); \ ____p1; \ }) @@ -55,7 +55,7 @@ __extension__ ({ \ #define rseq_smp_store_release(p, v) \ do { \ rseq_smp_mb(); \ - RSEQ_WRITE_ONCE(*p, v); \ + RSEQ_WRITE_ONCE(*(p), v); \ } while (0)
#if _MIPS_SZLONG == 64 diff --git a/tools/testing/selftests/rseq/rseq-ppc.h b/tools/testing/selftests/rseq/rseq-ppc.h index dc9190facee9..57b160597189 100644 --- a/tools/testing/selftests/rseq/rseq-ppc.h +++ b/tools/testing/selftests/rseq/rseq-ppc.h @@ -23,7 +23,7 @@
#define rseq_smp_load_acquire(p) \ __extension__ ({ \ - __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p); \ + rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p)); \ rseq_smp_lwsync(); \ ____p1; \ }) @@ -33,7 +33,7 @@ __extension__ ({ \ #define rseq_smp_store_release(p, v) \ do { \ rseq_smp_lwsync(); \ - RSEQ_WRITE_ONCE(*p, v); \ + RSEQ_WRITE_ONCE(*(p), v); \ } while (0)
/* diff --git a/tools/testing/selftests/rseq/rseq-riscv.h b/tools/testing/selftests/rseq/rseq-riscv.h index 17932a79e066..37e598d0a365 100644 --- a/tools/testing/selftests/rseq/rseq-riscv.h +++ b/tools/testing/selftests/rseq/rseq-riscv.h @@ -36,8 +36,8 @@
#define rseq_smp_load_acquire(p) \ __extension__ ({ \ - __typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p)); \ - RISCV_FENCE(r, rw) \ + rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p)); \ + RISCV_FENCE(r, rw); \ ____p1; \ })
@@ -46,7 +46,7 @@ __extension__ ({ \ #define rseq_smp_store_release(p, v) \ do { \ RISCV_FENCE(rw, w); \ - RSEQ_WRITE_ONCE(*(p), v); \ + RSEQ_WRITE_ONCE(*(p), v); \ } while (0)
#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip, \ diff --git a/tools/testing/selftests/rseq/rseq-s390.h b/tools/testing/selftests/rseq/rseq-s390.h index 46c92598acc7..33baaa9f9997 100644 --- a/tools/testing/selftests/rseq/rseq-s390.h +++ b/tools/testing/selftests/rseq/rseq-s390.h @@ -15,7 +15,7 @@
#define rseq_smp_load_acquire(p) \ __extension__ ({ \ - __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p); \ + rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p)); \ rseq_barrier(); \ ____p1; \ }) @@ -25,7 +25,7 @@ __extension__ ({ \ #define rseq_smp_store_release(p, v) \ do { \ rseq_barrier(); \ - RSEQ_WRITE_ONCE(*p, v); \ + RSEQ_WRITE_ONCE(*(p), v); \ } while (0)
#ifdef __s390x__ diff --git a/tools/testing/selftests/rseq/rseq-x86.h b/tools/testing/selftests/rseq/rseq-x86.h index fb65ef54b0fb..a2aa428ba151 100644 --- a/tools/testing/selftests/rseq/rseq-x86.h +++ b/tools/testing/selftests/rseq/rseq-x86.h @@ -42,7 +42,7 @@
#define rseq_smp_load_acquire(p) \ __extension__ ({ \ - __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p); \ + rseq_unqual_scalar_typeof(*(p)) ____p1 = RSEQ_READ_ONCE(*(p)); \ rseq_barrier(); \ ____p1; \ }) @@ -52,7 +52,7 @@ __extension__ ({ \ #define rseq_smp_store_release(p, v) \ do { \ rseq_barrier(); \ - RSEQ_WRITE_ONCE(*p, v); \ + RSEQ_WRITE_ONCE(*(p), v); \ } while (0)
#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \
Hi Peter,
Can you queue those fixes through your tree ?
Thanks,
Mathieu
On 5/15/23 09:57, Mathieu Desnoyers wrote:
Hi,
You will find in this series updates to the rseq selftests, mainly bringing fixes from librseq project back into the RSEQ selftests.
Thanks,
Mathieu
Mathieu Desnoyers (4): selftests/rseq: Fix CID_ID typo in Makefile selftests/rseq: Implement rseq_unqual_scalar_typeof selftests/rseq: Fix arm64 buggy load-acquire/store-release macros selftests/rseq: Use rseq_unqual_scalar_typeof in macros
tools/testing/selftests/rseq/Makefile | 2 +- tools/testing/selftests/rseq/compiler.h | 26 ++++++++++ tools/testing/selftests/rseq/rseq-arm.h | 4 +- tools/testing/selftests/rseq/rseq-arm64.h | 58 ++++++++++++----------- tools/testing/selftests/rseq/rseq-mips.h | 4 +- tools/testing/selftests/rseq/rseq-ppc.h | 4 +- tools/testing/selftests/rseq/rseq-riscv.h | 6 +-- tools/testing/selftests/rseq/rseq-s390.h | 4 +- tools/testing/selftests/rseq/rseq-x86.h | 4 +- 9 files changed, 70 insertions(+), 42 deletions(-)
On 8/7/23 14:53, Shuah Khan wrote:
On 6/6/23 07:36, Mathieu Desnoyers wrote:
Hi Peter,
Can you queue those fixes through your tree ?
Peter, Mathieu,
Doesn't look like this series has been pickedup?
Not AFAIK. Peter, if you have this somewhere in your tip queue, please let us know.
I can take these in for 6.6-rc1 if there are no dependencies on other trees.
It should not have dependencies with other trees.
Thanks,
Mathieu
thanks, -- Shuah
On 8/7/23 13:38, Mathieu Desnoyers wrote:
On 8/7/23 14:53, Shuah Khan wrote:
On 6/6/23 07:36, Mathieu Desnoyers wrote:
Hi Peter,
Can you queue those fixes through your tree ?
Peter, Mathieu,
Doesn't look like this series has been pickedup?
Not AFAIK. Peter, if you have this somewhere in your tip queue, please let us know.
I can take these in for 6.6-rc1 if there are no dependencies on other trees.
It should not have dependencies with other trees.
Applied to linux-kselftest next for Linux 6.6-rc1.
thanks, -- Shuah
linux-kselftest-mirror@lists.linaro.org