* [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant @ 2024-05-02 14:21 Daniel Gregory 2024-05-02 16:20 ` Stephen Hemminger ` (4 more replies) 0 siblings, 5 replies; 24+ messages in thread From: Daniel Gregory @ 2024-05-02 14:21 UTC (permalink / raw) To: Ruifeng Wang; +Cc: dev, Punit Agrawal, Liang Ma, Daniel Gregory The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check memorder, which is not constant. This causes compile errors when it is enabled with RTE_ARM_USE_WFE. eg. ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) | ^~~~~~~~~~~~ ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && | ^~~~~~~~~~~~~~~~ This has been the case since the switch to C11 assert (537caad2). Fix the compile errors by replacing the check with an RTE_ASSERT. Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> --- lib/eal/arm/include/rte_pause_64.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h index 5cb8b59056..98e10e91c4 100644 --- a/lib/eal/arm/include/rte_pause_64.h +++ b/lib/eal/arm/include/rte_pause_64.h @@ -11,6 +11,7 @@ extern "C" { #endif #include <rte_common.h> +#include <rte_debug.h> #ifdef RTE_ARM_USE_WFE #define RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED @@ -153,7 +154,7 @@ rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, { uint16_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && + RTE_ASSERT(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); __RTE_ARM_LOAD_EXC_16(addr, value, memorder) @@ -172,7 +173,7 @@ rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, { uint32_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && + RTE_ASSERT(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); __RTE_ARM_LOAD_EXC_32(addr, value, memorder) @@ -191,7 +192,7 @@ rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, { uint64_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && + RTE_ASSERT(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); __RTE_ARM_LOAD_EXC_64(addr, value, memorder) -- 2.39.2 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 14:21 [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant Daniel Gregory @ 2024-05-02 16:20 ` Stephen Hemminger 2024-05-02 17:44 ` Daniel Gregory 2024-05-03 13:32 ` David Marchand ` (3 subsequent siblings) 4 siblings, 1 reply; 24+ messages in thread From: Stephen Hemminger @ 2024-05-02 16:20 UTC (permalink / raw) To: Daniel Gregory; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Thu, 2 May 2024 15:21:16 +0100 Daniel Gregory <daniel.gregory@bytedance.com> wrote: > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > memorder, which is not constant. This causes compile errors when it is > enabled with RTE_ARM_USE_WFE. eg. > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > | ^~~~~~~~~~~~ > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > | ^~~~~~~~~~~~~~~~ > > This has been the case since the switch to C11 assert (537caad2). Fix > the compile errors by replacing the check with an RTE_ASSERT. > > Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> The memory order passed to those routines must be constant. Why not: diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h index 5cb8b59056..81987de771 100644 --- a/lib/eal/arm/include/rte_pause_64.h +++ b/lib/eal/arm/include/rte_pause_64.h @@ -172,6 +172,8 @@ rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, { uint32_t value; + static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); + RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); @@ -191,6 +193,8 @@ rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, { uint64_t value; + static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); + RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 16:20 ` Stephen Hemminger @ 2024-05-02 17:44 ` Daniel Gregory 2024-05-02 18:27 ` Stephen Hemminger 2024-05-02 21:48 ` Stephen Hemminger 0 siblings, 2 replies; 24+ messages in thread From: Daniel Gregory @ 2024-05-02 17:44 UTC (permalink / raw) To: Stephen Hemminger; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Thu, May 02, 2024 at 09:20:45AM -0700, Stephen Hemminger wrote: > Why not: > diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h > index 5cb8b59056..81987de771 100644 > --- a/lib/eal/arm/include/rte_pause_64.h > +++ b/lib/eal/arm/include/rte_pause_64.h > @@ -172,6 +172,8 @@ rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, > { > uint32_t value; > > + static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); > + > RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > memorder != rte_memory_order_relaxed); > > @@ -191,6 +193,8 @@ rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, > { > uint64_t value; > > + static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); > + > RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > memorder != rte_memory_order_relaxed); > What toolchain are you using? With your change I still get errors about the expression not being constant: In file included from ../lib/eal/arm/include/rte_pause.h:13, from ../lib/eal/include/generic/rte_spinlock.h:25, from ../lib/eal/arm/include/rte_spinlock.h:17, from ../lib/telemetry/telemetry.c:20: ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: ../lib/eal/arm/include/rte_pause_64.h:156:23: error: expression in static assertion is not constant 156 | static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I'm cross-compiling with GCC v12.2 using the config/arm/arm64_armv8_linux_gcc cross-file, and enabling RTE_ARM_USE_WFE by uncommenting it in config/arm/meson.build and setting its value to true. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 17:44 ` Daniel Gregory @ 2024-05-02 18:27 ` Stephen Hemminger 2024-05-02 21:48 ` Stephen Hemminger 1 sibling, 0 replies; 24+ messages in thread From: Stephen Hemminger @ 2024-05-02 18:27 UTC (permalink / raw) To: Daniel Gregory; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Thu, 2 May 2024 18:44:20 +0100 Daniel Gregory <daniel.gregory@bytedance.com> wrote: > What toolchain are you using? With your change I still get errors about > the expression not being constant: > > In file included from ../lib/eal/arm/include/rte_pause.h:13, > from ../lib/eal/include/generic/rte_spinlock.h:25, > from ../lib/eal/arm/include/rte_spinlock.h:17, > from ../lib/telemetry/telemetry.c:20: > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/arm/include/rte_pause_64.h:156:23: error: expression in static assertion is not constant > 156 | static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > I'm cross-compiling with GCC v12.2 using the > config/arm/arm64_armv8_linux_gcc cross-file, and enabling > RTE_ARM_USE_WFE by uncommenting it in config/arm/meson.build and setting > its value to true. The problem with your patch is that checking at runtime generates additional instructions in the critical path. Looks like more of a compiler bug. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 17:44 ` Daniel Gregory 2024-05-02 18:27 ` Stephen Hemminger @ 2024-05-02 21:48 ` Stephen Hemminger 2024-05-03 9:46 ` Daniel Gregory 1 sibling, 1 reply; 24+ messages in thread From: Stephen Hemminger @ 2024-05-02 21:48 UTC (permalink / raw) To: Daniel Gregory; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Thu, 2 May 2024 18:44:20 +0100 Daniel Gregory <daniel.gregory@bytedance.com> wrote: > On Thu, May 02, 2024 at 09:20:45AM -0700, Stephen Hemminger wrote: > > Why not: > > diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h > > index 5cb8b59056..81987de771 100644 > > --- a/lib/eal/arm/include/rte_pause_64.h > > +++ b/lib/eal/arm/include/rte_pause_64.h > > @@ -172,6 +172,8 @@ rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, > > { > > uint32_t value; > > > > + static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); > > + > > RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > > memorder != rte_memory_order_relaxed); > > > > @@ -191,6 +193,8 @@ rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, > > { > > uint64_t value; > > > > + static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); > > + > > RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > > memorder != rte_memory_order_relaxed); > > > > What toolchain are you using? With your change I still get errors about > the expression not being constant: > > In file included from ../lib/eal/arm/include/rte_pause.h:13, > from ../lib/eal/include/generic/rte_spinlock.h:25, > from ../lib/eal/arm/include/rte_spinlock.h:17, > from ../lib/telemetry/telemetry.c:20: > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/arm/include/rte_pause_64.h:156:23: error: expression in static assertion is not constant > 156 | static_assert(__builtin_constant_p(memorder), "memory order is not a constant"); > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > I'm cross-compiling with GCC v12.2 using the > config/arm/arm64_armv8_linux_gcc cross-file, and enabling > RTE_ARM_USE_WFE by uncommenting it in config/arm/meson.build and setting > its value to true. I don't do ARM any more, suppose could build on Raspberry Pi but havent. There are already constant checks like this elsewhere in the file. Why not this: diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h index 5cb8b59056..4f54f5dac3 100644 --- a/lib/eal/arm/include/rte_pause_64.h +++ b/lib/eal/arm/include/rte_pause_64.h @@ -153,6 +153,7 @@ rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, { uint16_t value; + RTE_BUILD_BUG_ON(!__builtin_constant_p(memorder)); RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); @@ -172,6 +173,7 @@ rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, { uint32_t value; + RTE_BUILD_BUG_ON(!__builtin_constant_p(memorder)); RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); @@ -191,6 +193,7 @@ rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, { uint64_t value; + RTE_BUILD_BUG_ON(!__builtin_constant_p(memorder)); RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 21:48 ` Stephen Hemminger @ 2024-05-03 9:46 ` Daniel Gregory 2024-05-04 0:56 ` Stephen Hemminger 0 siblings, 1 reply; 24+ messages in thread From: Daniel Gregory @ 2024-05-03 9:46 UTC (permalink / raw) To: Stephen Hemminger; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Thu, May 02, 2024 at 02:48:26PM -0700, Stephen Hemminger wrote: > There are already constant checks like this elsewhere in the file. Yes, but they're in macros, rather than inlined functions, so my understanding was that at compile time, macro expansion has put the memorder constant in the _Static_assert call as opposed to still being a function parameter in the inline definition. This is also the same approach used by the generic implementation (lib/eal/include/generic/rte_pause.h), the inline functions use assert and the macros use RTE_BUILD_BUG_ON. To give a minimal example, the following inline function doesn't compile (Godbolt demo here https://godbolt.org/z/aPqTf3v4o ): static inline __attribute__((always_inline)) void add(int *dst, int val) { _Static_assert(val != 0, "adding zero does nothing"); *dst += val; } But as a macro it does ( https://godbolt.org/z/x4a8fTf8h ): #define add(dst, val) do { \ _Static_assert(val != 0, "adding zero does nothing"); \ *(dst) += (val); \ } while(0); I don't believe this is a compiler bug as both GCC and Clang produce the same error message. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-03 9:46 ` Daniel Gregory @ 2024-05-04 0:56 ` Stephen Hemminger 2024-05-09 11:02 ` Daniel Gregory 0 siblings, 1 reply; 24+ messages in thread From: Stephen Hemminger @ 2024-05-04 0:56 UTC (permalink / raw) To: Daniel Gregory; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Fri, 3 May 2024 10:46:05 +0100 Daniel Gregory <daniel.gregory@bytedance.com> wrote: > On Thu, May 02, 2024 at 02:48:26PM -0700, Stephen Hemminger wrote: > > There are already constant checks like this elsewhere in the file. > > Yes, but they're in macros, rather than inlined functions, so my > understanding was that at compile time, macro expansion has put the > memorder constant in the _Static_assert call as opposed to still being > a function parameter in the inline definition. Gcc and clang are smart enough that it is possible to use the internal __builtin_constant_p() in the function. Some examples in DPDK: static __rte_always_inline int rte_mempool_do_generic_get(struct rte_mempool *mp, void **obj_table, unsigned int n, struct rte_mempool_cache *cache) { int ret; unsigned int remaining; uint32_t index, len; void **cache_objs; /* No cache provided */ if (unlikely(cache == NULL)) { remaining = n; goto driver_dequeue; } /* The cache is a stack, so copy will be in reverse order. */ cache_objs = &cache->objs[cache->len]; if (__extension__(__builtin_constant_p(n)) && n <= cache->len) { It should be possible to use RTE_BUILD_BUG_ON() or static_assert here. Changing a compile time check into a runtime check means that buggy programs blow up much later and in a confusing manner. And it impacts all code that is doing a spin lock, certainly one of the hottest paths in DPDK. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-04 0:56 ` Stephen Hemminger @ 2024-05-09 11:02 ` Daniel Gregory 0 siblings, 0 replies; 24+ messages in thread From: Daniel Gregory @ 2024-05-09 11:02 UTC (permalink / raw) To: Stephen Hemminger; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Fri, May 03, 2024 at 05:56:24PM -0700, Stephen Hemminger wrote: > On Fri, 3 May 2024 10:46:05 +0100 > Daniel Gregory <daniel.gregory@bytedance.com> wrote: > > > On Thu, May 02, 2024 at 02:48:26PM -0700, Stephen Hemminger wrote: > > > There are already constant checks like this elsewhere in the file. > > > > Yes, but they're in macros, rather than inlined functions, so my > > understanding was that at compile time, macro expansion has put the > > memorder constant in the _Static_assert call as opposed to still being > > a function parameter in the inline definition. > > Gcc and clang are smart enough that it is possible to use the internal > __builtin_constant_p() in the function. Some examples in DPDK: > > static __rte_always_inline int > rte_mempool_do_generic_get(struct rte_mempool *mp, void **obj_table, > unsigned int n, struct rte_mempool_cache *cache) > { > int ret; > unsigned int remaining; > uint32_t index, len; > void **cache_objs; > > /* No cache provided */ > if (unlikely(cache == NULL)) { > remaining = n; > goto driver_dequeue; > } > > /* The cache is a stack, so copy will be in reverse order. */ > cache_objs = &cache->objs[cache->len]; > > if (__extension__(__builtin_constant_p(n)) && n <= cache->len) { > > It should be possible to use RTE_BUILD_BUG_ON() or static_assert here. Yes, it's possible to use RTE_BUILD_BUG_ON(!__builtin_constant_p(n)) on Clang, I am simply not seeing it succeed. In fact, the opposite check, that the memorder is not constant, builds just fine with Clang 16. diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h index 5cb8b59056..d0646320e6 100644 --- a/lib/eal/arm/include/rte_pause_64.h +++ b/lib/eal/arm/include/rte_pause_64.h @@ -153,8 +153,7 @@ rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, { uint16_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && - memorder != rte_memory_order_relaxed); + RTE_BUILD_BUG_ON(__builtin_constant_p(memorder)); __RTE_ARM_LOAD_EXC_16(addr, value, memorder) if (value != expected) { @@ -172,8 +171,7 @@ rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, { uint32_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && - memorder != rte_memory_order_relaxed); + RTE_BUILD_BUG_ON(__builtin_constant_p(memorder)); __RTE_ARM_LOAD_EXC_32(addr, value, memorder) if (value != expected) { @@ -191,8 +189,7 @@ rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, { uint64_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && - memorder != rte_memory_order_relaxed); + RTE_BUILD_BUG_ON(__builtin_constant_p(memorder)); __RTE_ARM_LOAD_EXC_64(addr, value, memorder) if (value != expected) { diff --git a/lib/eal/include/generic/rte_pause.h b/lib/eal/include/generic/rte_pause.h index f2a1eadcbd..3973488865 100644 --- a/lib/eal/include/generic/rte_pause.h +++ b/lib/eal/include/generic/rte_pause.h @@ -80,6 +80,7 @@ static __rte_always_inline void rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, rte_memory_order memorder) { + RTE_BUILD_BUG_ON(__builtin_constant_p(memorder)); assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed); while (rte_atomic_load_explicit((volatile __rte_atomic uint16_t *)addr, memorder) @@ -91,6 +92,7 @@ static __rte_always_inline void rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, rte_memory_order memorder) { + RTE_BUILD_BUG_ON(__builtin_constant_p(memorder)); assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed); while (rte_atomic_load_explicit((volatile __rte_atomic uint32_t *)addr, memorder) @@ -102,6 +104,7 @@ static __rte_always_inline void rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, rte_memory_order memorder) { + RTE_BUILD_BUG_ON(__builtin_constant_p(memorder)); assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed); while (rte_atomic_load_explicit((volatile __rte_atomic uint64_t *)addr, memorder) This seemed odd, and it doesn't line up with what the GCC documentation says about __builtin_constant_p: > [__builtin_constant_p] does not return 1 when you pass a constant > numeric value to the inline function unless you specify the -O option. https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html So I did some more looking and the behaviour I've seen is that both Clang and GCC don't allow for static checks on inline function parameters: static inline __attribute__((always_inline)) int fn(int val) { _Static_assert(val == 0, "val nonzero"); return 0; } int main(void) { return fn(0); } ( https://godbolt.org/z/TrfWqYoGo ) Both GCC and Clang's __builtin_constant_p return 1 at runtime when called on an inline function parameter static inline __attribute__((always_inline)) int fn(int val) { return __builtin_constant_p(val); } int main(void) { return fn(0); } ( https://godbolt.org/z/hTGqvj91K ) But GCC doesn't allow for static assertions on the return value of __builtin_constant_p, error-ing that the expression is not constant: static inline __attribute__((always_inline)) int fn(int val) { _Static_assert(__builtin_constant_p(val), "v isn't constant"); return 0; } int main(void) { return fn(0); } ( https://godbolt.org/z/4799nEK1T ) And on Clang these static assertions are allowed, but always fail ( https://godbolt.org/z/6j16c5MbT ). I don't really have the experience with Clang or GCC to assess whether this is intended behaviour or a bug (I've not seen evidence this behaviour is new or different from previous versions), it's just what I've observed. > Changing a compile time check into a runtime check means that buggy programs > blow up much later and in a confusing manner. And it impacts all code that > is doing a spin lock, certainly one of the hottest paths in DPDK. True, buggy programs will error later, but other than converting the rte_wait_until_equal_* functions to macros, I haven't seen an approach that will let us use a static assert on the passed in memory order value right now. However, new enough GCC and Clang versions will optimise out runtime checks that are guaranteed to pass, such as in this case when an inline functions is called with a constant value. To give a reduced example: #include <assert.h> enum E { X, Y, Z, }; static inline __attribute__((always_inline)) void add(int *dst, enum E e) { assert(e == X || e == Y); if (e == X) (*dst)++; else (*dst) += 4; } } int fn(int num) { add(&num, Y); return num; } (GCC https://godbolt.org/z/GKGEa7Wdd ) (Clang https://godbolt.org/z/1vYv8MYcs ) With optimisations they both produce a fn that doesn't perform any check on the value of e, and simply return the input+4. Therefore, this patch shouldn't have an impact on the performance of locks when built in release mode. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 14:21 [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant Daniel Gregory 2024-05-02 16:20 ` Stephen Hemminger @ 2024-05-03 13:32 ` David Marchand 2024-05-03 14:21 ` Daniel Gregory 2024-05-03 18:27 ` [PATCH v2] " Daniel Gregory ` (2 subsequent siblings) 4 siblings, 1 reply; 24+ messages in thread From: David Marchand @ 2024-05-03 13:32 UTC (permalink / raw) To: Daniel Gregory; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Thu, May 2, 2024 at 4:22 PM Daniel Gregory <daniel.gregory@bytedance.com> wrote: > > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > memorder, which is not constant. This causes compile errors when it is > enabled with RTE_ARM_USE_WFE. eg. > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > | ^~~~~~~~~~~~ > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > | ^~~~~~~~~~~~~~~~ > > This has been the case since the switch to C11 assert (537caad2). Fix > the compile errors by replacing the check with an RTE_ASSERT. > > Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> - RTE_BUILD_BUG_ON() should not be used indeed. IIRC, this issue was introduced with 875f350924b8 ("eal: add a new helper for wait until scheme"). Please add a corresponding Fixes: tag in next revision. Rather than use RTE_ASSERT(), you can simply revert to a assert() call, like what was done before this change (and this is what is done for the non WFE/generic implementation too, see lib/eal/include/generic/rte_pause.h). - This ARM specific implementation should take a rte_memory_order type instead of a int type for the memorder input variable. This was missed in 1ec6a845b5cb ("eal: use stdatomic API in public headers"). Could you send a fix for this small issue too? Thanks! -- David Marchand ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-03 13:32 ` David Marchand @ 2024-05-03 14:21 ` Daniel Gregory 0 siblings, 0 replies; 24+ messages in thread From: Daniel Gregory @ 2024-05-03 14:21 UTC (permalink / raw) To: David Marchand; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Fri, May 03, 2024 at 03:32:20PM +0200, David Marchand wrote: > - RTE_BUILD_BUG_ON() should not be used indeed. > IIRC, this issue was introduced with 875f350924b8 ("eal: add a new > helper for wait until scheme"). > Please add a corresponding Fixes: tag in next revision. Will do. Should I CC stable@dpdk.org too? > - This ARM specific implementation should take a rte_memory_order type > instead of a int type for the memorder input variable. > This was missed in 1ec6a845b5cb ("eal: use stdatomic API in public headers"). > > Could you send a fix for this small issue too? Yes, sure thing. Thanks, Daniel ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 14:21 [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant Daniel Gregory 2024-05-02 16:20 ` Stephen Hemminger 2024-05-03 13:32 ` David Marchand @ 2024-05-03 18:27 ` Daniel Gregory 2024-05-03 18:30 ` Daniel Gregory ` (4 more replies) 2024-05-04 1:02 ` [PATCH] " Stephen Hemminger 2024-05-11 16:48 ` Wathsala Wathawana Vithanage 4 siblings, 5 replies; 24+ messages in thread From: Daniel Gregory @ 2024-05-03 18:27 UTC (permalink / raw) To: Ruifeng Wang; +Cc: dev, Punit Agrawal, Liang Ma, Daniel Gregory, feifei.wang2 The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check memorder, which is not constant. This causes compile errors when it is enabled with RTE_ARM_USE_WFE. eg. ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) | ^~~~~~~~~~~~ ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && | ^~~~~~~~~~~~~~~~ Fix the compile errors by replacing the check with an assert, like in the generic implementation (lib/eal/include/generic/rte_pause.h). Fixes: 875f350924b8 ("eal: add a new helper for wait until scheme") Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> --- Cc: feifei.wang2@arm.com --- lib/eal/arm/include/rte_pause_64.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h index 5cb8b59056..852660091a 100644 --- a/lib/eal/arm/include/rte_pause_64.h +++ b/lib/eal/arm/include/rte_pause_64.h @@ -10,6 +10,8 @@ extern "C" { #endif +#include <assert.h> + #include <rte_common.h> #ifdef RTE_ARM_USE_WFE @@ -153,7 +155,7 @@ rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, { uint16_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && + assert(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); __RTE_ARM_LOAD_EXC_16(addr, value, memorder) @@ -172,7 +174,7 @@ rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, { uint32_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && + assert(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); __RTE_ARM_LOAD_EXC_32(addr, value, memorder) @@ -191,7 +193,7 @@ rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, { uint64_t value; - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && + assert(memorder != rte_memory_order_acquire && memorder != rte_memory_order_relaxed); __RTE_ARM_LOAD_EXC_64(addr, value, memorder) -- 2.39.2 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-03 18:27 ` [PATCH v2] " Daniel Gregory @ 2024-05-03 18:30 ` Daniel Gregory 2024-05-04 0:59 ` Stephen Hemminger ` (3 subsequent siblings) 4 siblings, 0 replies; 24+ messages in thread From: Daniel Gregory @ 2024-05-03 18:30 UTC (permalink / raw) To: Ruifeng Wang; +Cc: dev, Punit Agrawal, Liang Ma, feifei.wang2 Apologies, mis-sent this before attaching a changelog: v2: * replaced RTE_ASSERT with assert * added Fixes: tag ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-03 18:27 ` [PATCH v2] " Daniel Gregory 2024-05-03 18:30 ` Daniel Gregory @ 2024-05-04 0:59 ` Stephen Hemminger 2024-06-27 15:08 ` Thomas Monjalon 2024-05-06 9:30 ` Ruifeng Wang ` (2 subsequent siblings) 4 siblings, 1 reply; 24+ messages in thread From: Stephen Hemminger @ 2024-05-04 0:59 UTC (permalink / raw) To: Daniel Gregory; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma, feifei.wang2 On Fri, 3 May 2024 19:27:30 +0100 Daniel Gregory <daniel.gregory@bytedance.com> wrote: > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > memorder, which is not constant. This causes compile errors when it is > enabled with RTE_ARM_USE_WFE. eg. > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > | ^~~~~~~~~~~~ > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > | ^~~~~~~~~~~~~~~~ > > Fix the compile errors by replacing the check with an assert, like in > the generic implementation (lib/eal/include/generic/rte_pause.h). No, don't hide the problem. What code is calling these. Looks like a real bug. Could be behind layers of wrappers. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-04 0:59 ` Stephen Hemminger @ 2024-06-27 15:08 ` Thomas Monjalon 2024-06-28 10:05 ` Daniel Gregory 0 siblings, 1 reply; 24+ messages in thread From: Thomas Monjalon @ 2024-06-27 15:08 UTC (permalink / raw) To: Daniel Gregory Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma, feifei.wang2, Stephen Hemminger, david.marchand 04/05/2024 02:59, Stephen Hemminger: > On Fri, 3 May 2024 19:27:30 +0100 > Daniel Gregory <daniel.gregory@bytedance.com> wrote: > > > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > > memorder, which is not constant. This causes compile errors when it is > > enabled with RTE_ARM_USE_WFE. eg. > > > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > > | ^~~~~~~~~~~~ > > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > > | ^~~~~~~~~~~~~~~~ > > > > Fix the compile errors by replacing the check with an assert, like in > > the generic implementation (lib/eal/include/generic/rte_pause.h). > > No, don't hide the problem. > > What code is calling these. Looks like a real bug. Could be behind layers of wrappers. I support Stephen's opinion. Please look for the real issue. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-06-27 15:08 ` Thomas Monjalon @ 2024-06-28 10:05 ` Daniel Gregory 2024-06-28 15:19 ` Stephen Hemminger 0 siblings, 1 reply; 24+ messages in thread From: Daniel Gregory @ 2024-06-28 10:05 UTC (permalink / raw) To: Thomas Monjalon Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma, feifei.wang2, Stephen Hemminger, david.marchand On Thu, Jun 27, 2024 at 05:08:51PM +0200, Thomas Monjalon wrote: > 04/05/2024 02:59, Stephen Hemminger: > > On Fri, 3 May 2024 19:27:30 +0100 > > Daniel Gregory <daniel.gregory@bytedance.com> wrote: > > > > > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > > > memorder, which is not constant. This causes compile errors when it is > > > enabled with RTE_ARM_USE_WFE. eg. > > > > > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > > > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > > > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > > > | ^~~~~~~~~~~~ > > > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > > > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > > > | ^~~~~~~~~~~~~~~~ > > > > > > Fix the compile errors by replacing the check with an assert, like in > > > the generic implementation (lib/eal/include/generic/rte_pause.h). > > > > No, don't hide the problem. > > > > What code is calling these. Looks like a real bug. Could be behind layers of wrappers. > > I support Stephen's opinion. > Please look for the real issue. In DPDK, I have found 26 calls of rte_wait_until_equal_16, largely split between app/test-bbdev/test_bbdev_perf.c and app/test/test_timer.c, with a couple calls in lib/eal/include/rte_pflock.h and lib/eal/include/rte_ticketlock.h as well. 16 calls of rte_wait_until_equal_32, spread amongst various test cases (test_func_reentrancy.c test_mcslock.c, test_mempool_perf.c, ...), two drivers (drivers/event/opdl/opdl_ring.c and drivers/net/thunderx/nicvf_rxrx.c), lib/eal/common/eal_common_mcfg.c, lib/eal/include/generic/rte_spinlock.h, lib/ring/rte_ring_c11_pvt.h, lib/ring/rte_ring_generic_pvt.h and lib/eal/include/rte_mcslock.h. There is a single call to rte_wait_until_equal_64 in app/test/test_pmd_perf.c They all correctly use the primitives from rte_stdatomic.h As I discussed on another chain https://lore.kernel.org/dpdk-dev/20240509110251.GA3795959@ste-uk-lab-gw/ from what I've seen, it seems that neither Clang nor GCC allow for static checks on the parameters of inline functions. For instance, the following does not compile: static inline __attribute__((always_inline)) int fn(int val) { _Static_assert(val == 0, "val nonzero"); return 0; } int main(void) { return fn(0); } ( https://godbolt.org/z/TrfWqYoGo ) With the same "expression in static assertion is not constant" error that I get when cross-compiling DPDK for ARM with WFE enabled on main: diff --git a/config/arm/meson.build b/config/arm/meson.build index a45aa9e466..661c735977 100644 --- a/config/arm/meson.build +++ b/config/arm/meson.build @@ -18,7 +18,7 @@ flags_common = [ # ['RTE_ARM64_MEMCPY_STRICT_ALIGN', false], # Enable use of ARM wait for event instruction. - # ['RTE_ARM_USE_WFE', false], + ['RTE_ARM_USE_WFE', true], ['RTE_ARCH_ARM64', true], ['RTE_CACHE_LINE_SIZE', 128] ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-06-28 10:05 ` Daniel Gregory @ 2024-06-28 15:19 ` Stephen Hemminger 0 siblings, 0 replies; 24+ messages in thread From: Stephen Hemminger @ 2024-06-28 15:19 UTC (permalink / raw) To: Daniel Gregory Cc: Thomas Monjalon, Ruifeng Wang, dev, Punit Agrawal, Liang Ma, feifei.wang2, david.marchand On Fri, 28 Jun 2024 11:05:20 +0100 Daniel Gregory <daniel.gregory@bytedance.com> wrote: > > > > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > > > > memorder, which is not constant. This causes compile errors when it is > > > > enabled with RTE_ARM_USE_WFE. eg. > > > > > > > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > > > > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > > > > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > > > > | ^~~~~~~~~~~~ > > > > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > > > > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > > > > | ^~~~~~~~~~~~~~~~ > > > > > > > > Fix the compile errors by replacing the check with an assert, like in > > > > the generic implementation (lib/eal/include/generic/rte_pause.h). > > > > > > No, don't hide the problem. > > > > > > What code is calling these. Looks like a real bug. Could be behind layers of wrappers. > > > > I support Stephen's opinion. > > Please look for the real issue. > > In DPDK, I have found 26 calls of rte_wait_until_equal_16, largely split > between app/test-bbdev/test_bbdev_perf.c and app/test/test_timer.c, with > a couple calls in lib/eal/include/rte_pflock.h and > lib/eal/include/rte_ticketlock.h as well. 16 calls of > rte_wait_until_equal_32, spread amongst various test cases > (test_func_reentrancy.c test_mcslock.c, test_mempool_perf.c, ...), two > drivers (drivers/event/opdl/opdl_ring.c and > drivers/net/thunderx/nicvf_rxrx.c), lib/eal/common/eal_common_mcfg.c, > lib/eal/include/generic/rte_spinlock.h, lib/ring/rte_ring_c11_pvt.h, > lib/ring/rte_ring_generic_pvt.h and lib/eal/include/rte_mcslock.h. There > is a single call to rte_wait_until_equal_64 in app/test/test_pmd_perf.c > > They all correctly use the primitives from rte_stdatomic.h > > As I discussed on another chain > https://lore.kernel.org/dpdk-dev/20240509110251.GA3795959@ste-uk-lab-gw/ > from what I've seen, it seems that neither Clang nor GCC allow for > static checks on the parameters of inline functions. For instance, the > following does not compile: > > static inline __attribute__((always_inline)) int > fn(int val) > { > _Static_assert(val == 0, "val nonzero"); > return 0; > } > > int main(void) { > return fn(0); > } > > ( https://godbolt.org/z/TrfWqYoGo ) > > With the same "expression in static assertion is not constant" error > that I get when cross-compiling DPDK for ARM with WFE enabled on main: This is unexpected, but I can validate that it works that way. Maybe because of combination of how inlining works and how the static asserts are evaluated. It does work if fn() is a macro #define fn(val) ({ static_assert(val == 0, "val nonzero"); 0; }) ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-03 18:27 ` [PATCH v2] " Daniel Gregory 2024-05-03 18:30 ` Daniel Gregory 2024-05-04 0:59 ` Stephen Hemminger @ 2024-05-06 9:30 ` Ruifeng Wang 2024-05-11 17:00 ` Wathsala Wathawana Vithanage 2024-10-04 17:47 ` Stephen Hemminger 4 siblings, 0 replies; 24+ messages in thread From: Ruifeng Wang @ 2024-05-06 9:30 UTC (permalink / raw) To: Daniel Gregory, Wathsala Wathawana Vithanage, Honnappa Nagarahalli Cc: dev, Punit Agrawal, Liang Ma, Daniel Gregory, nd [-- Attachment #1: Type: text/plain, Size: 1613 bytes --] + Arm team to the loop. Removed invalid email address. From: Daniel Gregory <daniel.gregory@bytedance.com> Date: Saturday, May 4, 2024 at 2:27 AM To: Ruifeng Wang <Ruifeng.Wang@arm.com> Cc: dev@dpdk.org <dev@dpdk.org>, Punit Agrawal <punit.agrawal@bytedance.com>, Liang Ma <liangma@bytedance.com>, Daniel Gregory <daniel.gregory@bytedance.com>, Feifei Wang <Feifei.Wang2@arm.com> Subject: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check memorder, which is not constant. This causes compile errors when it is enabled with RTE_ARM_USE_WFE. eg. ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) | ^~~~~~~~~~~~ ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && | ^~~~~~~~~~~~~~~~ Fix the compile errors by replacing the check with an assert, like in the generic implementation (lib/eal/include/generic/rte_pause.h). Fixes: 875f350924b8 ("eal: add a new helper for wait until scheme") Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> --- Cc: feifei.wang2@arm.com --- lib/eal/arm/include/rte_pause_64.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) [-- Attachment #2: Type: text/html, Size: 4372 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-03 18:27 ` [PATCH v2] " Daniel Gregory ` (2 preceding siblings ...) 2024-05-06 9:30 ` Ruifeng Wang @ 2024-05-11 17:00 ` Wathsala Wathawana Vithanage 2024-10-04 17:47 ` Stephen Hemminger 4 siblings, 0 replies; 24+ messages in thread From: Wathsala Wathawana Vithanage @ 2024-05-11 17:00 UTC (permalink / raw) To: Daniel Gregory, Ruifeng Wang Cc: dev, Punit Agrawal, Liang Ma, Feifei Wang, nd > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion > is not constant > 530 | #define RTE_BUILD_BUG_ON(condition) do { > static_assert(!(condition), #condition); } while (0) > | ^~~~~~~~~~~~ > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro > ‘RTE_BUILD_BUG_ON’ > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > | ^~~~~~~~~~~~~~~~ > > Fix the compile errors by replacing the check with an assert, like in the generic > implementation (lib/eal/include/generic/rte_pause.h). > > Fixes: 875f350924b8 ("eal: add a new helper for wait until scheme") > > Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> Acked-by: Wathsala Vithanage <wathsala.vithanage@arm.com> ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-03 18:27 ` [PATCH v2] " Daniel Gregory ` (3 preceding siblings ...) 2024-05-11 17:00 ` Wathsala Wathawana Vithanage @ 2024-10-04 17:47 ` Stephen Hemminger 2024-10-08 9:47 ` Morten Brørup 4 siblings, 1 reply; 24+ messages in thread From: Stephen Hemminger @ 2024-10-04 17:47 UTC (permalink / raw) To: Daniel Gregory; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma, feifei.wang2 On Fri, 3 May 2024 19:27:30 +0100 Daniel Gregory <daniel.gregory@bytedance.com> wrote: > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > memorder, which is not constant. This causes compile errors when it is > enabled with RTE_ARM_USE_WFE. eg. > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > | ^~~~~~~~~~~~ > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > | ^~~~~~~~~~~~~~~~ > > Fix the compile errors by replacing the check with an assert, like in > the generic implementation (lib/eal/include/generic/rte_pause.h). > > Fixes: 875f350924b8 ("eal: add a new helper for wait until scheme") > > Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> > --- > Cc: feifei.wang2@arm.com > --- > lib/eal/arm/include/rte_pause_64.h | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h > index 5cb8b59056..852660091a 100644 > --- a/lib/eal/arm/include/rte_pause_64.h > +++ b/lib/eal/arm/include/rte_pause_64.h > @@ -10,6 +10,8 @@ > extern "C" { > #endif > > +#include <assert.h> > + > #include <rte_common.h> > > #ifdef RTE_ARM_USE_WFE > @@ -153,7 +155,7 @@ rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, > { > uint16_t value; > > - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > + assert(memorder != rte_memory_order_acquire && > memorder != rte_memory_order_relaxed); > Why not change RET_BUILD_BUG_ON() to RTE_ASSERT()? The one issue is that by default RTE_ENABLE_ASSERT is not enabled. ^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH v2] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-10-04 17:47 ` Stephen Hemminger @ 2024-10-08 9:47 ` Morten Brørup 0 siblings, 0 replies; 24+ messages in thread From: Morten Brørup @ 2024-10-08 9:47 UTC (permalink / raw) To: Stephen Hemminger, Daniel Gregory Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma, feifei.wang2 > From: Stephen Hemminger [mailto:stephen@networkplumber.org] > Sent: Friday, 4 October 2024 19.47 > > On Fri, 3 May 2024 19:27:30 +0100 > Daniel Gregory <daniel.gregory@bytedance.com> wrote: > > > Fix the compile errors by replacing the check with an assert, like in > > the generic implementation (lib/eal/include/generic/rte_pause.h). > > - RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > > + assert(memorder != rte_memory_order_acquire && > > memorder != rte_memory_order_relaxed); > > > > Why not change RET_BUILD_BUG_ON() to RTE_ASSERT()? > The one issue is that by default RTE_ENABLE_ASSERT is not enabled. I don't like assert() either. RTE_ASSERT() should be used instead. However, there should be no objections to doing exactly the same as in the generic implementation. A replacement of assert() throughout the DPDK code would be a different patch. Checkpatch could check for it too. For this patch, Reviewed-by: Morten Brørup <mb@smartsharesystems.com> ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 14:21 [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant Daniel Gregory ` (2 preceding siblings ...) 2024-05-03 18:27 ` [PATCH v2] " Daniel Gregory @ 2024-05-04 1:02 ` Stephen Hemminger 2024-05-09 11:11 ` Daniel Gregory 2024-05-11 16:48 ` Wathsala Wathawana Vithanage 4 siblings, 1 reply; 24+ messages in thread From: Stephen Hemminger @ 2024-05-04 1:02 UTC (permalink / raw) To: Daniel Gregory; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Thu, 2 May 2024 15:21:16 +0100 Daniel Gregory <daniel.gregory@bytedance.com> wrote: > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > memorder, which is not constant. This causes compile errors when it is > enabled with RTE_ARM_USE_WFE. eg. > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > | ^~~~~~~~~~~~ > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > | ^~~~~~~~~~~~~~~~ > > This has been the case since the switch to C11 assert (537caad2). Fix > the compile errors by replacing the check with an RTE_ASSERT. > > Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> The only calls to rte_wait_until_equal_16 in upstream code are in the test_bbdev_perf.c and test_timer.c. Looks like these test never got fixed to use rte_memory_order instead of __ATOMIC_ defines. And there should be a CI test for ARM that enables the WFE code at least to ensure it works! ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-04 1:02 ` [PATCH] " Stephen Hemminger @ 2024-05-09 11:11 ` Daniel Gregory 2024-05-09 16:47 ` Tyler Retzlaff 0 siblings, 1 reply; 24+ messages in thread From: Daniel Gregory @ 2024-05-09 11:11 UTC (permalink / raw) To: Stephen Hemminger; +Cc: Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Fri, May 03, 2024 at 06:02:36PM -0700, Stephen Hemminger wrote: > On Thu, 2 May 2024 15:21:16 +0100 > Daniel Gregory <daniel.gregory@bytedance.com> wrote: > > > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > > memorder, which is not constant. This causes compile errors when it is > > enabled with RTE_ARM_USE_WFE. eg. > > > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > > | ^~~~~~~~~~~~ > > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > > | ^~~~~~~~~~~~~~~~ > > > > This has been the case since the switch to C11 assert (537caad2). Fix > > the compile errors by replacing the check with an RTE_ASSERT. > > > > Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> > > The only calls to rte_wait_until_equal_16 in upstream code > are in the test_bbdev_perf.c and test_timer.c. Looks like > these test never got fixed to use rte_memory_order instead of __ATOMIC_ defines. Apologies, the commit message could make it clearer, but this is also an issue for rte_wait_until_equal_32 and rte_wait_until_equal_64. rte_wait_until_equal_32 is used in a dozen or so lock tests with the old __ATOMIC_ defines, as well as rte_ring_generic_pvt.h and rte_ring_c11_pvt.h, where it's used with the new rte_memorder_order values. Correct me if I'm wrong, but shouldn't the static assertions in rte_stdatomic.h ensure that mixed usage doesn't cause any issues, even if using the older __ATOMIC_ defines isn't ideal? > And there should be a CI test for ARM that enables the WFE code at least > to ensure it works! Yes, that could've caught this sooner. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-09 11:11 ` Daniel Gregory @ 2024-05-09 16:47 ` Tyler Retzlaff 0 siblings, 0 replies; 24+ messages in thread From: Tyler Retzlaff @ 2024-05-09 16:47 UTC (permalink / raw) To: Stephen Hemminger, Ruifeng Wang, dev, Punit Agrawal, Liang Ma On Thu, May 09, 2024 at 12:11:50PM +0100, Daniel Gregory wrote: > On Fri, May 03, 2024 at 06:02:36PM -0700, Stephen Hemminger wrote: > > On Thu, 2 May 2024 15:21:16 +0100 > > Daniel Gregory <daniel.gregory@bytedance.com> wrote: > > > > > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > > > memorder, which is not constant. This causes compile errors when it is > > > enabled with RTE_ARM_USE_WFE. eg. > > > > > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > > > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion is not constant > > > 530 | #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0) > > > | ^~~~~~~~~~~~ > > > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro ‘RTE_BUILD_BUG_ON’ > > > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > > > | ^~~~~~~~~~~~~~~~ > > > > > > This has been the case since the switch to C11 assert (537caad2). Fix > > > the compile errors by replacing the check with an RTE_ASSERT. > > > > > > Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> > > > > The only calls to rte_wait_until_equal_16 in upstream code > > are in the test_bbdev_perf.c and test_timer.c. Looks like > > these test never got fixed to use rte_memory_order instead of __ATOMIC_ defines. > > Apologies, the commit message could make it clearer, but this is also an > issue for rte_wait_until_equal_32 and rte_wait_until_equal_64. > > rte_wait_until_equal_32 is used in a dozen or so lock tests with the old > __ATOMIC_ defines, as well as rte_ring_generic_pvt.h and > rte_ring_c11_pvt.h, where it's used with the new rte_memorder_order > values. Correct me if I'm wrong, but shouldn't the static assertions in > rte_stdatomic.h ensure that mixed usage doesn't cause any issues, even > if using the older __ATOMIC_ defines isn't ideal? this is just informational. the static assertions are intended to make sure there is alignment between the value produced by the rte_memory_order and __ATOMIC_ constant expressions. so you can expect that intermixing __ATOMIC_ and rte_memory_order should work. the older __ATOMIC_ are still used in tests because i just haven't had time to finish conversion. i have a series up now that makes most of the conversions, it is waiting for review. > > > And there should be a CI test for ARM that enables the WFE code at least > > to ensure it works! > > Yes, that could've caught this sooner. ^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant 2024-05-02 14:21 [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant Daniel Gregory ` (3 preceding siblings ...) 2024-05-04 1:02 ` [PATCH] " Stephen Hemminger @ 2024-05-11 16:48 ` Wathsala Wathawana Vithanage 4 siblings, 0 replies; 24+ messages in thread From: Wathsala Wathawana Vithanage @ 2024-05-11 16:48 UTC (permalink / raw) To: Daniel Gregory, Ruifeng Wang; +Cc: dev, Punit Agrawal, Liang Ma, nd, nd > Subject: [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant > > The ARM implementation of rte_pause uses RTE_BUILD_BUG_ON to check > memorder, which is not constant. This causes compile errors when it is > enabled with RTE_ARM_USE_WFE. eg. Use of wfe based rte_wait_until_equal_ implementations had performance issues when used in lock free data structures like rte_ring. To prevent these functions from getting included RTE_ARM_USE_WFE was introduced some time back and this issue has been hiding so far because of that. Solution looks good to me. > > ../lib/eal/arm/include/rte_pause_64.h: In function ‘rte_wait_until_equal_16’: > ../lib/eal/include/rte_common.h:530:56: error: expression in static assertion > is not constant > 530 | #define RTE_BUILD_BUG_ON(condition) do { > static_assert(!(condition), #condition); } while (0) > | ^~~~~~~~~~~~ > ../lib/eal/arm/include/rte_pause_64.h:156:9: note: in expansion of macro > ‘RTE_BUILD_BUG_ON’ > 156 | RTE_BUILD_BUG_ON(memorder != rte_memory_order_acquire && > | ^~~~~~~~~~~~~~~~ > > This has been the case since the switch to C11 assert (537caad2). Fix the > compile errors by replacing the check with an RTE_ASSERT. > > Signed-off-by: Daniel Gregory <daniel.gregory@bytedance.com> Acked-by: Wathsala Vithanage <wathsala.vithanage@arm.com> ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2024-10-08 9:47 UTC | newest] Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-05-02 14:21 [PATCH] eal/arm: replace RTE_BUILD_BUG on non-constant Daniel Gregory 2024-05-02 16:20 ` Stephen Hemminger 2024-05-02 17:44 ` Daniel Gregory 2024-05-02 18:27 ` Stephen Hemminger 2024-05-02 21:48 ` Stephen Hemminger 2024-05-03 9:46 ` Daniel Gregory 2024-05-04 0:56 ` Stephen Hemminger 2024-05-09 11:02 ` Daniel Gregory 2024-05-03 13:32 ` David Marchand 2024-05-03 14:21 ` Daniel Gregory 2024-05-03 18:27 ` [PATCH v2] " Daniel Gregory 2024-05-03 18:30 ` Daniel Gregory 2024-05-04 0:59 ` Stephen Hemminger 2024-06-27 15:08 ` Thomas Monjalon 2024-06-28 10:05 ` Daniel Gregory 2024-06-28 15:19 ` Stephen Hemminger 2024-05-06 9:30 ` Ruifeng Wang 2024-05-11 17:00 ` Wathsala Wathawana Vithanage 2024-10-04 17:47 ` Stephen Hemminger 2024-10-08 9:47 ` Morten Brørup 2024-05-04 1:02 ` [PATCH] " Stephen Hemminger 2024-05-09 11:11 ` Daniel Gregory 2024-05-09 16:47 ` Tyler Retzlaff 2024-05-11 16:48 ` Wathsala Wathawana Vithanage
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).