[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v4 2/3] bitmap: import bitmap_{set/clear} from Linux 5.5



Import the functions and it's dependencies. Based on Linux 5.5, commit
id d5226fa6dbae0569ee43ecfc08bdcd6770fc4755.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
 xen/common/bitmap.c          | 41 ++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/bitops.h |  2 ++
 xen/include/xen/bitmap.h     | 38 +++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+)

diff --git a/xen/common/bitmap.c b/xen/common/bitmap.c
index fd070bee97..f8b243e77e 100644
--- a/xen/common/bitmap.c
+++ b/xen/common/bitmap.c
@@ -212,6 +212,47 @@ 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;
+       }
+}
+EXPORT_SYMBOL(__bitmap_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;
+       }
+}
+EXPORT_SYMBOL(__bitmap_clear);
 
 /**
  *     bitmap_find_free_region - find a contiguous aligned mem region
diff --git a/xen/include/asm-x86/bitops.h b/xen/include/asm-x86/bitops.h
index 5a71afbc89..04b1530388 100644
--- a/xen/include/asm-x86/bitops.h
+++ b/xen/include/asm-x86/bitops.h
@@ -480,4 +480,6 @@ static inline int fls(unsigned int x)
 #define hweight16(x) generic_hweight16(x)
 #define hweight8(x) generic_hweight8(x)
 
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+
 #endif /* _X86_BITOPS_H */
diff --git a/xen/include/xen/bitmap.h b/xen/include/xen/bitmap.h
index 4e1e690af1..f07d1f6935 100644
--- a/xen/include/xen/bitmap.h
+++ b/xen/include/xen/bitmap.h
@@ -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,42 @@ static inline int bitmap_weight(const unsigned long *src, 
int nbits)
        return __bitmap_weight(src, nbits);
 }
 
+#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
 
-- 
2.25.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.