]> xenbits.xensource.com Git - people/dwmw2/xen.git/commitdiff
bitmap: import bitmap_{set/clear} from Linux 5.5
authorRoger Pau Monne <roger.pau@citrix.com>
Wed, 19 Feb 2020 10:22:55 +0000 (11:22 +0100)
committerJulien Grall <julien@xen.org>
Wed, 19 Feb 2020 12:34:21 +0000 (12:34 +0000)
Import the functions and it's dependencies. Based on Linux 5.5, commit
id d5226fa6dbae0569ee43ecfc08bdcd6770fc4755.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/common/bitmap.c
xen/include/xen/bitmap.h

index fd070bee97af3c8aec5669f787f0d3673b7ea950..88768bf8bc66889a14ce282be97d827da467e624 100644 (file)
@@ -212,6 +212,45 @@ int __bitmap_weight(const unsigned long *bitmap, int bits)
 #endif
 EXPORT_SYMBOL(__bitmap_weight);
 
+void __bitmap_set(unsigned long *map, unsigned int start, int len)
+{
+       unsigned long *p = map + BIT_WORD(start);
+       const unsigned int size = start + len;
+       int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
+       unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
+
+       while (len - bits_to_set >= 0) {
+               *p |= mask_to_set;
+               len -= bits_to_set;
+               bits_to_set = BITS_PER_LONG;
+               mask_to_set = ~0UL;
+               p++;
+       }
+       if (len) {
+               mask_to_set &= BITMAP_LAST_WORD_MASK(size);
+               *p |= mask_to_set;
+       }
+}
+
+void __bitmap_clear(unsigned long *map, unsigned int start, int len)
+{
+       unsigned long *p = map + BIT_WORD(start);
+       const unsigned int size = start + len;
+       int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
+       unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
+
+       while (len - bits_to_clear >= 0) {
+               *p &= ~mask_to_clear;
+               len -= bits_to_clear;
+               bits_to_clear = BITS_PER_LONG;
+               mask_to_clear = ~0UL;
+               p++;
+       }
+       if (len) {
+               mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
+               *p &= ~mask_to_clear;
+       }
+}
 
 /**
  *     bitmap_find_free_region - find a contiguous aligned mem region
index 4e1e690af1e8345c530966147bea69ba850c7189..c44e009f8c964ad7a183c754022abc1f305b4809 100644 (file)
@@ -85,6 +85,8 @@ extern int __bitmap_intersects(const unsigned long *bitmap1,
 extern int __bitmap_subset(const unsigned long *bitmap1,
                        const unsigned long *bitmap2, int bits);
 extern int __bitmap_weight(const unsigned long *bitmap, int bits);
+extern void __bitmap_set(unsigned long *map, unsigned int start, int len);
+extern void __bitmap_clear(unsigned long *map, unsigned int start, int len);
 
 extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order);
 extern void bitmap_release_region(unsigned long *bitmap, int pos, int order);
@@ -227,6 +229,44 @@ static inline int bitmap_weight(const unsigned long *src, int nbits)
        return __bitmap_weight(src, nbits);
 }
 
+#include <asm/byteorder.h>
+
+#ifdef __LITTLE_ENDIAN
+#define BITMAP_MEM_ALIGNMENT 8
+#else
+#define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long))
+#endif
+#define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
+#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
+
+static inline void bitmap_set(unsigned long *map, unsigned int start,
+               unsigned int nbits)
+{
+       if (__builtin_constant_p(nbits) && nbits == 1)
+               __set_bit(start, map);
+       else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
+                IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
+                __builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
+                IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
+               memset((char *)map + start / 8, 0xff, nbits / 8);
+       else
+               __bitmap_set(map, start, nbits);
+}
+
+static inline void bitmap_clear(unsigned long *map, unsigned int start,
+               unsigned int nbits)
+{
+       if (__builtin_constant_p(nbits) && nbits == 1)
+               __clear_bit(start, map);
+       else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
+                IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
+                __builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
+                IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
+               memset((char *)map + start / 8, 0, nbits / 8);
+       else
+               __bitmap_clear(map, start, nbits);
+}
+
 #undef bitmap_switch
 #undef bitmap_bytes