On Tue, 05/26 18:54, Paolo Bonzini wrote: > From: Stefan Hajnoczi <stefa...@redhat.com> > > Use atomic_or() for atomic bitmaps where several threads may set bits at > the same time. This avoids the race condition between threads loading > an element, bitwise ORing, and then storing the element. > > When setting all bits in a word we can avoid atomic ops and instead just > use an smp_mb() at the end. > > Most bitmap users don't need atomicity so introduce new functions. > > Signed-off-by: Stefan Hajnoczi <stefa...@redhat.com> > Message-Id: <1417519399-3166-2-git-send-email-stefa...@redhat.com> > [Avoid barrier in the single word case, use full barrier instead of write. > - Paolo] > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> > --- > include/qemu/bitmap.h | 2 ++ > include/qemu/bitops.h | 14 ++++++++++++++ > util/bitmap.c | 38 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 54 insertions(+) > > diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h > index f0273c9..3e0a4f3 100644 > --- a/include/qemu/bitmap.h > +++ b/include/qemu/bitmap.h > @@ -39,6 +39,7 @@ > * bitmap_empty(src, nbits) Are all bits zero in *src? > * bitmap_full(src, nbits) Are all bits set in *src? > * bitmap_set(dst, pos, nbits) Set specified bit area > + * bitmap_set_atomic(dst, pos, nbits) Set specified bit area with atomic > ops
The tab/space mix is not consistent. Fixing can be on top. > * bitmap_clear(dst, pos, nbits) Clear specified bit area > * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free > area > */ > @@ -226,6 +227,7 @@ static inline int bitmap_intersects(const unsigned long > *src1, > } > > void bitmap_set(unsigned long *map, long i, long len); > +void bitmap_set_atomic(unsigned long *map, long i, long len); > void bitmap_clear(unsigned long *map, long start, long nr); > unsigned long bitmap_find_next_zero_area(unsigned long *map, > unsigned long size, > diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h > index 8abdcf9..8164225 100644 > --- a/include/qemu/bitops.h > +++ b/include/qemu/bitops.h > @@ -16,6 +16,7 @@ > #include <assert.h> > > #include "host-utils.h" > +#include "atomic.h" > > #define BITS_PER_BYTE CHAR_BIT > #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) > @@ -39,6 +40,19 @@ static inline void set_bit(long nr, unsigned long *addr) > } > > /** > + * set_bit_atomic - Set a bit in memory atomically > + * @nr: the bit to set > + * @addr: the address to start counting from > + */ > +static inline void set_bit_atomic(long nr, unsigned long *addr) > +{ > + unsigned long mask = BIT_MASK(nr); > + unsigned long *p = addr + BIT_WORD(nr); > + > + atomic_or(p, mask); > +} Where is this function used? Fam