Re: [kvm-unit-tests PATCH v8 08/10] arm/barrier-litmus-tests: add simple mp and sal litmus tests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 18, 2021 at 06:46:48PM +0000, Alex Bennée wrote:
> This adds a framework for adding simple barrier litmus tests against
> ARM. The litmus tests aren't as comprehensive as the academic exercises
> which will attempt to do all sorts of things to keep racing CPUs synced
> up. These tests do honour the "sync" parameter to do a poor-mans
> equivalent.
> 
> The two litmus tests are:
>   - message passing
>   - store-after-load
> 
> They both have case that should fail (although won't on single-threaded
> TCG setups). If barriers aren't working properly the store-after-load
> test will fail even on an x86 backend as x86 allows re-ording of non
> aliased stores.
> 
> I've imported a few more of the barrier primatives from the Linux source
> tree so we consistently use macros.
> 
> The arm64 barrier primitives trip up on -Wstrict-aliasing so this is
> disabled in the Makefile.
> 
> Signed-off-by: Alex Bennée <alex.bennee@xxxxxxxxxx>
> CC: Will Deacon <will@xxxxxxxxxx>
> 
> ---
> v8
>   - move to mttcgtests.cfg
>   - fix checkpatch issues
>   - fix report usage
> v7
>   - merge in store-after-load
>   - clean-up sync-up code
>   - use new counter api
>   - fix xfail for sal test
> v6
>   - add a unittest.cfg
>   - -fno-strict-aliasing
> ---
>  arm/Makefile.common       |   1 +
>  lib/arm/asm/barrier.h     |  61 ++++++
>  lib/arm64/asm/barrier.h   |  50 +++++
>  arm/barrier-litmus-test.c | 450 ++++++++++++++++++++++++++++++++++++++
>  arm/mttcgtests.cfg        |  33 +++
>  5 files changed, 595 insertions(+)
>  create mode 100644 arm/barrier-litmus-test.c
> 
> diff --git a/arm/Makefile.common b/arm/Makefile.common
> index f905971..861e5c7 100644
> --- a/arm/Makefile.common
> +++ b/arm/Makefile.common
> @@ -13,6 +13,7 @@ tests-common += $(TEST_DIR)/sieve.flat
>  tests-common += $(TEST_DIR)/pl031.flat
>  tests-common += $(TEST_DIR)/tlbflush-code.flat
>  tests-common += $(TEST_DIR)/locking-test.flat
> +tests-common += $(TEST_DIR)/barrier-litmus-test.flat
>  
>  tests-all = $(tests-common) $(tests)
>  all: directories $(tests-all)
> diff --git a/lib/arm/asm/barrier.h b/lib/arm/asm/barrier.h
> index 7f86831..2870080 100644
> --- a/lib/arm/asm/barrier.h
> +++ b/lib/arm/asm/barrier.h
> @@ -8,6 +8,8 @@
>   * This work is licensed under the terms of the GNU GPL, version 2.
>   */
>  
> +#include <stdint.h>
> +
>  #define sev()		asm volatile("sev" : : : "memory")
>  #define wfe()		asm volatile("wfe" : : : "memory")
>  #define wfi()		asm volatile("wfi" : : : "memory")
> @@ -25,4 +27,63 @@
>  #define smp_rmb()	smp_mb()
>  #define smp_wmb()	dmb(ishst)
>  
> +extern void abort(void);
> +
> +static inline void __write_once_size(volatile void *p, void *res, int size)
> +{
> +	switch (size) {
> +	case 1: *(volatile uint8_t *)p = *(uint8_t *)res; break;
> +	case 2: *(volatile uint16_t *)p = *(uint16_t *)res; break;
> +	case 4: *(volatile uint32_t *)p = *(uint32_t *)res; break;
> +	case 8: *(volatile uint64_t *)p = *(uint64_t *)res; break;
> +	default:
> +		/* unhandled case */
> +		abort();
> +	}
> +}
> +
> +#define WRITE_ONCE(x, val) \
> +({							\
> +	union { typeof(x) __val; char __c[1]; } __u =	\
> +		{ .__val = (typeof(x)) (val) }; \
> +	__write_once_size(&(x), __u.__c, sizeof(x));	\
> +	__u.__val;					\
> +})
> +
> +#define smp_store_release(p, v)						\
> +do {									\
> +	smp_mb();							\
> +	WRITE_ONCE(*p, v);						\
> +} while (0)
> +
> +
> +static inline
> +void __read_once_size(const volatile void *p, void *res, int size)
> +{
> +	switch (size) {
> +	case 1: *(uint8_t *)res = *(volatile uint8_t *)p; break;
> +	case 2: *(uint16_t *)res = *(volatile uint16_t *)p; break;
> +	case 4: *(uint32_t *)res = *(volatile uint32_t *)p; break;
> +	case 8: *(uint64_t *)res = *(volatile uint64_t *)p; break;
> +	default:
> +		/* unhandled case */
> +		abort();
> +	}
> +}
> +
> +#define READ_ONCE(x)							\
> +({									\
> +	union { typeof(x) __val; char __c[1]; } __u;			\
> +	__read_once_size(&(x), __u.__c, sizeof(x));			\
> +	__u.__val;							\
> +})


WRITE_ONCE and READ_ONCE are already defined in lib/linux/compiler.h

Thanks,
drew




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux