[dpdk-dev] [PATCH v4 1/2] eal: add WC store functions

Nicolau, Radu radu.nicolau at intel.com
Mon Jul 6 11:15:01 CEST 2020


Hi David, thanks for reviewing!

Some comments inline.


On 7/3/2020 4:19 PM, David Marchand wrote:
> On Thu, Jul 2, 2020 at 11:24 AM Radu Nicolau<radu.nicolau at intel.com>  wrote:
>> +static inline void
>> +rte_write32_wc(uint32_t value, volatile void *addr);
> This is a new API, and even if inlined, it should be marked experimental.
Will do.
> Is volatile necessary?
Yes, most of these functions will be called on mmio addresses/volatile 
pointers. All other io functions have it.
>
> +static inline void
> +rte_write32_wc_relaxed(uint32_t value, volatile void *addr);
> +
> +
> Double empty line (there are some other in this patch that I won't flag again).
I will check all occurrences.
>
>
>>   #endif /* __DOXYGEN__ */
>>
>>   #ifndef RTE_OVERRIDE_IO_H
>> @@ -345,6 +378,20 @@ rte_write64(uint64_t value, volatile void *addr)
>>          rte_write64_relaxed(value, addr);
>>   }
>>
>> +#ifndef RTE_NATIVE_WRITE32_WC
> Missing return type, this causes build failure on anything but x86.
Yes, got lost in the copy/paste. I will fix it in the next version
>
>
>> +rte_write32_wc(uint32_t value, volatile void *addr)
>> +{
>> +       rte_write32(value, addr);
>> +}
>> +
>> +static __rte_always_inline void
>> +rte_write32_wc_relaxed(uint32_t value, volatile void *addr)
>> +{
>> +       rte_write32_relaxed(value, addr);
>> +}
>> +#endif /* RTE_NATIVE_WRITE32_WC */
>> +
>> +
>>   #endif /* RTE_OVERRIDE_IO_H */
>>
>>   #endif /* _RTE_IO_H_ */
>> diff --git a/lib/librte_eal/x86/include/rte_io.h b/lib/librte_eal/x86/include/rte_io.h
>> index 2db71b1..c95ed67 100644
>> --- a/lib/librte_eal/x86/include/rte_io.h
>> +++ b/lib/librte_eal/x86/include/rte_io.h
>> @@ -9,8 +9,64 @@
>>   extern "C" {
>>   #endif
>>
>> +#include "rte_cpuflags.h"
> Inclusion of this header should be out of the extern "C" block.
Why? It is used elsewhere inside the extern "C" block e.g. 
x86/rte_spinlock.h
>
>
>> +
>> +#define RTE_NATIVE_WRITE32_WC
>>   #include "generic/rte_io.h"
>>
>> +/**
>> + * @internal
>> + * MOVDIRI wrapper.
>> + */
>> +static __rte_always_inline void
>> +_rte_x86_movdiri(uint32_t value, volatile void *addr)
>> +{
>> +       asm volatile(
>> +               /* MOVDIRI */
>> +               ".byte 0x40, 0x0f, 0x38, 0xf9, 0x02"
>> +               :
>> +               : "a" (value), "d" (addr));
>> +}
>> +
>> +static __rte_always_inline void
>> +rte_write32_wc(uint32_t value, volatile void *addr)
>> +{
>> +       static int _x86_movdiri_flag = -1;
>> +       if (_x86_movdiri_flag == 1) {
>> +               rte_wmb();
>> +               _rte_x86_movdiri(value, addr);
>> +       } else if (_x86_movdiri_flag == 0) {
>> +               rte_write32(value, addr);
>> +       } else {
>> +               _x86_movdiri_flag =
>> +                       (rte_cpu_get_flag_enabled(RTE_CPUFLAG_MOVDIRI) > 0);
> Can't this cpu flag check be moved in a constructor?
> This would avoid this copy/paste.
We evaluated this approach but it creates more problems than if fixes - 
it will need a variable that needs to be exported and there is no good 
place to put it.
>
>
>> +               if (_x86_movdiri_flag == 1) {
>> +                       rte_wmb();
>> +                       _rte_x86_movdiri(value, addr);
>> +               } else {
>> +                       rte_write32(value, addr);
>> +               }
>> +       }
>> +}
>> +
>> +static __rte_always_inline void
>> +rte_write32_wc_relaxed(uint32_t value, volatile void *addr)
>> +{
>> +       static int _x86_movdiri_flag = -1;
> Same check with a static variable with the same name.
It should be no problem, they are static local variables.
>
>
> I wonder if wrapping all of this in a single function would be more elegant.
> Then rte_write32_wc(|_relaxed) would call it with a flag.
Yes, it will be more elegant but also it will cost more, it was written 
like this to minimize the number of branches taken for the movdiri path.


More information about the dev mailing list