|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v10 02/14] xen: introduce generic non-atomic test_*bit()
On Thu, 2024-05-23 at 14:00 +0100, Julien Grall wrote:
> Hi Oleksii,
Hi Julien,
>
> On 17/05/2024 14:54, Oleksii Kurochko wrote:
> > diff --git a/xen/arch/arm/arm64/livepatch.c
> > b/xen/arch/arm/arm64/livepatch.c
> > index df2cebedde..4bc8ed9be5 100644
> > --- a/xen/arch/arm/arm64/livepatch.c
> > +++ b/xen/arch/arm/arm64/livepatch.c
> > @@ -10,7 +10,6 @@
> > #include <xen/mm.h>
> > #include <xen/vmap.h>
> >
> > -#include <asm/bitops.h>
>
> It is a bit unclear how this change is related to the patch. Can you
> explain in the commit message?
Probably it doesn't need anymore. I will double check and if this
change is not needed, I will just drop it in the next patch version.
>
> > #include <asm/byteorder.h>
> > #include <asm/insn.h>
> > #include <asm/livepatch.h>
> > diff --git a/xen/arch/arm/include/asm/bitops.h
> > b/xen/arch/arm/include/asm/bitops.h
> > index 5104334e48..8e16335e76 100644
> > --- a/xen/arch/arm/include/asm/bitops.h
> > +++ b/xen/arch/arm/include/asm/bitops.h
> > @@ -22,9 +22,6 @@
> > #define __set_bit(n,p) set_bit(n,p)
> > #define __clear_bit(n,p) clear_bit(n,p)
> >
> > -#define BITOP_BITS_PER_WORD 32
> > -#define BITOP_MASK(nr) (1UL << ((nr) %
> > BITOP_BITS_PER_WORD))
> > -#define BITOP_WORD(nr) ((nr) / BITOP_BITS_PER_WORD)
> > #define BITS_PER_BYTE 8
>
> OOI, any reason BITS_PER_BYTE has not been moved as well? I don't
> expect
> the value to change across arch.
I can move it to generic one header too in the next patch version.
>
> [...]
>
> > diff --git a/xen/include/xen/bitops.h b/xen/include/xen/bitops.h
> > index f14ad0d33a..6eeeff0117 100644
> > --- a/xen/include/xen/bitops.h
> > +++ b/xen/include/xen/bitops.h
> > @@ -65,10 +65,141 @@ static inline int generic_flsl(unsigned long
> > x)
> > * scope
> > */
> >
> > +#define BITOP_BITS_PER_WORD 32
> > +typedef uint32_t bitop_uint_t;
> > +
> > +#define BITOP_MASK(nr) ((bitop_uint_t)1 << ((nr) %
> > BITOP_BITS_PER_WORD))
> > +
> > +#define BITOP_WORD(nr) ((nr) / BITOP_BITS_PER_WORD)
> > +
> > +extern void __bitop_bad_size(void);
> > +
> > +#define bitop_bad_size(addr) (sizeof(*(addr)) <
> > sizeof(bitop_uint_t))
> > +
> > /* --------------------- Please tidy above here -----------------
> > ---- */
> >
> > #include <asm/bitops.h>
> >
> > +/**
> > + * generic__test_and_set_bit - Set a bit and return its old value
> > + * @nr: Bit to set
> > + * @addr: Address to count from
> > + *
> > + * This operation is non-atomic and can be reordered.
> > + * If two examples of this operation race, one can appear to
> > succeed
> > + * but actually fail. You must protect multiple accesses with a
> > lock.
> > + */
>
> Sorry for only mentioning this on v10. I think this comment should be
> duplicated (or moved to) on top of test_bit() because this is what
> everyone will use. This will avoid the developper to follow the
> function
> calls and only notice the x86 version which says "This function is
> atomic and may not be reordered." and would be wrong for all the
> other arch.
It makes sense to add this comment on top of test_bit(), but I am
curious if it is needed to mention that for x86 arch_test_bit() "is
atomic and may not be reordered":
* This operation is non-atomic and can be reordered. ( Exception: for
* x86 arch_test_bit() is atomic and may not be reordered )
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
>
> > +static always_inline bool
> > +generic__test_and_set_bit(int nr, volatile void *addr)
> > +{
> > + bitop_uint_t mask = BITOP_MASK(nr);
> > + volatile bitop_uint_t *p = (volatile bitop_uint_t *)addr +
> > BITOP_WORD(nr);
> > + bitop_uint_t old = *p;
> > +
> > + *p = old | mask;
> > + return (old & mask);
> > +}
> > +
> > +/**
> > + * generic__test_and_clear_bit - Clear a bit and return its old
> > value
> > + * @nr: Bit to clear
> > + * @addr: Address to count from
> > + *
> > + * This operation is non-atomic and can be reordered.
> > + * If two examples of this operation race, one can appear to
> > succeed
> > + * but actually fail. You must protect multiple accesses with a
> > lock.
> > + */
>
> Same applies here and ...
>
> > +static always_inline bool
> > +generic__test_and_clear_bit(int nr, volatile void *addr)
> > +{
> > + bitop_uint_t mask = BITOP_MASK(nr);
> > + volatile bitop_uint_t *p = (volatile bitop_uint_t *)addr +
> > BITOP_WORD(nr);
> > + bitop_uint_t old = *p;
> > +
> > + *p = old & ~mask;
> > + return (old & mask);
> > +}
> > +
> > +/* WARNING: non atomic and it can be reordered! */
>
> ... here.
>
> > +static always_inline bool
> > +generic__test_and_change_bit(int nr, volatile void *addr)
> > +{
> > + bitop_uint_t mask = BITOP_MASK(nr);
> > + volatile bitop_uint_t *p = (volatile bitop_uint_t *)addr +
> > BITOP_WORD(nr);
> > + bitop_uint_t old = *p;
> > +
> > + *p = old ^ mask;
> > + return (old & mask);
> > +}
> > +/**
> > + * generic_test_bit - Determine whether a bit is set
> > + * @nr: bit number to test
> > + * @addr: Address to start counting from
> > + */
> > +static always_inline bool generic_test_bit(int nr, const volatile
> > void *addr)
> > +{
> > + bitop_uint_t mask = BITOP_MASK(nr);
> > + const volatile bitop_uint_t *p =
> > + (const volatile bitop_uint_t *)addr +
> > BITOP_WORD(nr);
> > +
> > + return (*p & mask);
> > +}
> > +
> > +static always_inline bool
> > +__test_and_set_bit(int nr, volatile void *addr)
> > +{
> > +#ifndef arch__test_and_set_bit
> > +#define arch__test_and_set_bit generic__test_and_set_bit
> > +#endif
> > +
> > + return arch__test_and_set_bit(nr, addr);
> > +}
>
> NIT: It is a bit too late to change this one. But I have to admit, I
> don't understand the purpose of the static inline when you could have
> simply call...
>
> > +#define __test_and_set_bit(nr, addr) ({ \
> > + if ( bitop_bad_size(addr) ) __bitop_bad_size(); \
> > + __test_and_set_bit(nr, addr); \
>
> ... __arch__test_and_set_bit here.
I just wanted to be in sync with other non-atomic test*_bit()
operations and Andrew's patch series ( xen/bitops: Reduce the mess,
starting with ffs() ).
>
>
> The only two reasons I am not providing an ack is the:
> * Explanation for the removal of asm/bitops.h in livepatch.c
> * The placement of the comments
Thanks for review. I'll update the patch and sent new version of the
patch series.
~ Oleksii
>
> There are not too important for me.
>
> Cheers,
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |