1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds #ifndef __LINUX_BITMAP_H 31da177e4SLinus Torvalds #define __LINUX_BITMAP_H 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds #ifndef __ASSEMBLY__ 61da177e4SLinus Torvalds 708c5188eSAndy Shevchenko #include <linux/align.h> 81da177e4SLinus Torvalds #include <linux/bitops.h> 9d12a8284SBartosz Golaszewski #include <linux/cleanup.h> 106cb42f91SYury Norov #include <linux/errno.h> 1147d8c156SYury Norov #include <linux/find.h> 1208c5188eSAndy Shevchenko #include <linux/limits.h> 13c13656b9SBartosz Golaszewski #include <linux/string.h> 14c13656b9SBartosz Golaszewski #include <linux/types.h> 15aae06fc1SYury Norov #include <linux/bitmap-str.h> 161da177e4SLinus Torvalds 17e829c2e4SBartosz Golaszewski struct device; 18e829c2e4SBartosz Golaszewski 191da177e4SLinus Torvalds /* 201da177e4SLinus Torvalds * bitmaps provide bit arrays that consume one or more unsigned 211da177e4SLinus Torvalds * longs. The bitmap interface and available operations are listed 221da177e4SLinus Torvalds * here, in bitmap.h 231da177e4SLinus Torvalds * 241da177e4SLinus Torvalds * Function implementations generic to all architectures are in 251da177e4SLinus Torvalds * lib/bitmap.c. Functions implementations that are architecture 261da177e4SLinus Torvalds * specific are in various include/asm-<arch>/bitops.h headers 271da177e4SLinus Torvalds * and other arch/<arch> specific files. 281da177e4SLinus Torvalds * 291da177e4SLinus Torvalds * See lib/bitmap.c for more details. 301da177e4SLinus Torvalds */ 311da177e4SLinus Torvalds 327d7363e4SRandy Dunlap /** 337d7363e4SRandy Dunlap * DOC: bitmap overview 347d7363e4SRandy Dunlap * 351da177e4SLinus Torvalds * The available bitmap operations and their rough meaning in the 361da177e4SLinus Torvalds * case that the bitmap is a single unsigned long are thus: 371da177e4SLinus Torvalds * 3841e7b166SRasmus Villemoes * The generated code is more efficient when nbits is known at 3941e7b166SRasmus Villemoes * compile-time and at most BITS_PER_LONG. 4008cd3657SAndi Kleen * 417d7363e4SRandy Dunlap * :: 427d7363e4SRandy Dunlap * 431da177e4SLinus Torvalds * bitmap_zero(dst, nbits) *dst = 0UL 441da177e4SLinus Torvalds * bitmap_fill(dst, nbits) *dst = ~0UL 451da177e4SLinus Torvalds * bitmap_copy(dst, src, nbits) *dst = *src 461da177e4SLinus Torvalds * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2 471da177e4SLinus Torvalds * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2 481da177e4SLinus Torvalds * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2 491da177e4SLinus Torvalds * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2) 501da177e4SLinus Torvalds * bitmap_complement(dst, src, nbits) *dst = ~(*src) 511da177e4SLinus Torvalds * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal? 521da177e4SLinus Torvalds * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap? 531da177e4SLinus Torvalds * bitmap_subset(src1, src2, nbits) Is *src1 a subset of *src2? 541da177e4SLinus Torvalds * bitmap_empty(src, nbits) Are all bits zero in *src? 551da177e4SLinus Torvalds * bitmap_full(src, nbits) Are all bits set in *src? 561da177e4SLinus Torvalds * bitmap_weight(src, nbits) Hamming Weight: number set bits 5724291cafSYury Norov * bitmap_weight_and(src1, src2, nbits) Hamming Weight of and'ed bitmap 58c1f5204eSYury Norov * bitmap_weight_andnot(src1, src2, nbits) Hamming Weight of andnot'ed bitmap 59c1a2a962SAkinobu Mita * bitmap_set(dst, pos, nbits) Set specified bit area 60c1a2a962SAkinobu Mita * bitmap_clear(dst, pos, nbits) Clear specified bit area 61c1a2a962SAkinobu Mita * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area 62780d2a9cSWolfram Sang * bitmap_find_next_zero_area_off(buf, len, pos, n, mask, mask_off) as above 631da177e4SLinus Torvalds * bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n 641da177e4SLinus Torvalds * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n 6520927671SStefano Brivio * bitmap_cut(dst, src, first, n, nbits) Cut n bits from first, copy rest 6630544ed5SAndy Shevchenko * bitmap_replace(dst, old, new, mask, nbits) *dst = (*old & ~(*mask)) | (*new & *mask) 67de5f8433SAndy Shevchenko * bitmap_scatter(dst, src, mask, nbits) *dst = map(dense, sparse)(src) 68de5f8433SAndy Shevchenko * bitmap_gather(dst, src, mask, nbits) *dst = map(sparse, dense)(src) 69fb5eeeeeSPaul Jackson * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src) 70fb5eeeeeSPaul Jackson * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit) 717ea931c9SPaul Jackson * bitmap_onto(dst, orig, relmap, nbits) *dst = orig relative to relmap 727ea931c9SPaul Jackson * bitmap_fold(dst, orig, sz, nbits) dst bits = orig bits mod sz 7301a3ee2bSReinette Chatre * bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf 7401a3ee2bSReinette Chatre * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf 754b060420SMike Travis * bitmap_parselist(buf, dst, nbits) Parse bitmap dst from kernel buf 764b060420SMike Travis * bitmap_parselist_user(buf, dst, nbits) Parse bitmap dst from user buf 7787e24802SPaul Jackson * bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region 7887e24802SPaul Jackson * bitmap_release_region(bitmap, pos, order) Free specified bit region 7987e24802SPaul Jackson * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region 80c724f193SYury Norov * bitmap_from_arr32(dst, buf, nbits) Copy nbits from u32[] buf to dst 81ba1afa67SQu Wenruo * bitmap_from_arr64(dst, buf, nbits) Copy nbits from u64[] buf to dst 82c724f193SYury Norov * bitmap_to_arr32(buf, src, nbits) Copy nbits from buf to u32[] dst 830a97953fSYury Norov * bitmap_to_arr64(buf, src, nbits) Copy nbits from buf to u64[] dst 84169c474fSWilliam Breathitt Gray * bitmap_get_value8(map, start) Get 8bit value from map at start 85169c474fSWilliam Breathitt Gray * bitmap_set_value8(map, value, start) Set 8bit value to map at start 8663c15822SSyed Nayyar Waris * bitmap_read(map, start, nbits) Read an nbits-sized value from 8763c15822SSyed Nayyar Waris * map at start 8863c15822SSyed Nayyar Waris * bitmap_write(map, value, start, nbits) Write an nbits-sized value to 8963c15822SSyed Nayyar Waris * map at start 907d7363e4SRandy Dunlap * 91334cfa48SAndy Shevchenko * Note, bitmap_zero() and bitmap_fill() operate over the region of 92334cfa48SAndy Shevchenko * unsigned longs, that is, bits behind bitmap till the unsigned long 93334cfa48SAndy Shevchenko * boundary will be zeroed or filled as well. Consider to use 94334cfa48SAndy Shevchenko * bitmap_clear() or bitmap_set() to make explicit zeroing or filling 95334cfa48SAndy Shevchenko * respectively. 961da177e4SLinus Torvalds */ 971da177e4SLinus Torvalds 987d7363e4SRandy Dunlap /** 997d7363e4SRandy Dunlap * DOC: bitmap bitops 1007d7363e4SRandy Dunlap * 1017d7363e4SRandy Dunlap * Also the following operations in asm/bitops.h apply to bitmaps.:: 1021da177e4SLinus Torvalds * 1031da177e4SLinus Torvalds * set_bit(bit, addr) *addr |= bit 1041da177e4SLinus Torvalds * clear_bit(bit, addr) *addr &= ~bit 1051da177e4SLinus Torvalds * change_bit(bit, addr) *addr ^= bit 1061da177e4SLinus Torvalds * test_bit(bit, addr) Is bit set in *addr? 1071da177e4SLinus Torvalds * test_and_set_bit(bit, addr) Set bit and return old value 1081da177e4SLinus Torvalds * test_and_clear_bit(bit, addr) Clear bit and return old value 1091da177e4SLinus Torvalds * test_and_change_bit(bit, addr) Change bit and return old value 1101da177e4SLinus Torvalds * find_first_zero_bit(addr, nbits) Position first zero bit in *addr 1111da177e4SLinus Torvalds * find_first_bit(addr, nbits) Position first set bit in *addr 1120ade34c3SClement Courbet * find_next_zero_bit(addr, nbits, bit) 1130ade34c3SClement Courbet * Position next zero bit in *addr >= bit 1141da177e4SLinus Torvalds * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit 1150ade34c3SClement Courbet * find_next_and_bit(addr1, addr2, nbits, bit) 1160ade34c3SClement Courbet * Same as find_next_bit, but in 1170ade34c3SClement Courbet * (*addr1 & *addr2) 1187d7363e4SRandy Dunlap * 1191da177e4SLinus Torvalds */ 1201da177e4SLinus Torvalds 1217d7363e4SRandy Dunlap /** 1227d7363e4SRandy Dunlap * DOC: declare bitmap 1231da177e4SLinus Torvalds * The DECLARE_BITMAP(name,bits) macro, in linux/types.h, can be used 1241da177e4SLinus Torvalds * to declare an array named 'name' of just enough unsigned longs to 1251da177e4SLinus Torvalds * contain all bit positions from 0 to 'bits' - 1. 1261da177e4SLinus Torvalds */ 1271da177e4SLinus Torvalds 1281da177e4SLinus Torvalds /* 129c42b65e3SAndy Shevchenko * Allocation and deallocation of bitmap. 130c42b65e3SAndy Shevchenko * Provided in lib/bitmap.c to avoid circular dependency. 131c42b65e3SAndy Shevchenko */ 13298635b29SBartosz Golaszewski unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags); 13398635b29SBartosz Golaszewski unsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags); 1347529cc7fSTariq Toukan unsigned long *bitmap_alloc_node(unsigned int nbits, gfp_t flags, int node); 1357529cc7fSTariq Toukan unsigned long *bitmap_zalloc_node(unsigned int nbits, gfp_t flags, int node); 13698635b29SBartosz Golaszewski void bitmap_free(const unsigned long *bitmap); 137c42b65e3SAndy Shevchenko 138d12a8284SBartosz Golaszewski DEFINE_FREE(bitmap, unsigned long *, if (_T) bitmap_free(_T)) 139d12a8284SBartosz Golaszewski 140e829c2e4SBartosz Golaszewski /* Managed variants of the above. */ 141e829c2e4SBartosz Golaszewski unsigned long *devm_bitmap_alloc(struct device *dev, 142e829c2e4SBartosz Golaszewski unsigned int nbits, gfp_t flags); 143e829c2e4SBartosz Golaszewski unsigned long *devm_bitmap_zalloc(struct device *dev, 144e829c2e4SBartosz Golaszewski unsigned int nbits, gfp_t flags); 145e829c2e4SBartosz Golaszewski 146c42b65e3SAndy Shevchenko /* 1471da177e4SLinus Torvalds * lib/bitmap.c provides these functions: 1481da177e4SLinus Torvalds */ 1491da177e4SLinus Torvalds 150005f1700SKees Cook bool __bitmap_equal(const unsigned long *bitmap1, 1515e068069SRasmus Villemoes const unsigned long *bitmap2, unsigned int nbits); 15298635b29SBartosz Golaszewski bool __pure __bitmap_or_equal(const unsigned long *src1, 153b9fa6442SThomas Gleixner const unsigned long *src2, 154b9fa6442SThomas Gleixner const unsigned long *src3, 155b9fa6442SThomas Gleixner unsigned int nbits); 15698635b29SBartosz Golaszewski void __bitmap_complement(unsigned long *dst, const unsigned long *src, 1573d6684f4SRasmus Villemoes unsigned int nbits); 15898635b29SBartosz Golaszewski void __bitmap_shift_right(unsigned long *dst, const unsigned long *src, 1592fbad299SRasmus Villemoes unsigned int shift, unsigned int nbits); 16098635b29SBartosz Golaszewski void __bitmap_shift_left(unsigned long *dst, const unsigned long *src, 161dba94c25SRasmus Villemoes unsigned int shift, unsigned int nbits); 16298635b29SBartosz Golaszewski void bitmap_cut(unsigned long *dst, const unsigned long *src, 16398635b29SBartosz Golaszewski unsigned int first, unsigned int cut, unsigned int nbits); 164e2863a78SYury Norov bool __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, 1652f9305ebSRasmus Villemoes const unsigned long *bitmap2, unsigned int nbits); 16698635b29SBartosz Golaszewski void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, 1672f9305ebSRasmus Villemoes const unsigned long *bitmap2, unsigned int nbits); 16898635b29SBartosz Golaszewski void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, 1692f9305ebSRasmus Villemoes const unsigned long *bitmap2, unsigned int nbits); 170e2863a78SYury Norov bool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, 1712f9305ebSRasmus Villemoes const unsigned long *bitmap2, unsigned int nbits); 17298635b29SBartosz Golaszewski void __bitmap_replace(unsigned long *dst, 17330544ed5SAndy Shevchenko const unsigned long *old, const unsigned long *new, 17430544ed5SAndy Shevchenko const unsigned long *mask, unsigned int nbits); 175005f1700SKees Cook bool __bitmap_intersects(const unsigned long *bitmap1, 1766dfe9799SRasmus Villemoes const unsigned long *bitmap2, unsigned int nbits); 177005f1700SKees Cook bool __bitmap_subset(const unsigned long *bitmap1, 1785be20213SRasmus Villemoes const unsigned long *bitmap2, unsigned int nbits); 1794e23eeebSLinus Torvalds unsigned int __bitmap_weight(const unsigned long *bitmap, unsigned int nbits); 18024291cafSYury Norov unsigned int __bitmap_weight_and(const unsigned long *bitmap1, 18124291cafSYury Norov const unsigned long *bitmap2, unsigned int nbits); 182c1f5204eSYury Norov unsigned int __bitmap_weight_andnot(const unsigned long *bitmap1, 183c1f5204eSYury Norov const unsigned long *bitmap2, unsigned int nbits); 18498635b29SBartosz Golaszewski void __bitmap_set(unsigned long *map, unsigned int start, int len); 18598635b29SBartosz Golaszewski void __bitmap_clear(unsigned long *map, unsigned int start, int len); 1865e19b013SMichal Nazarewicz 18798635b29SBartosz Golaszewski unsigned long bitmap_find_next_zero_area_off(unsigned long *map, 188c1a2a962SAkinobu Mita unsigned long size, 189c1a2a962SAkinobu Mita unsigned long start, 190c1a2a962SAkinobu Mita unsigned int nr, 1915e19b013SMichal Nazarewicz unsigned long align_mask, 1925e19b013SMichal Nazarewicz unsigned long align_offset); 1935e19b013SMichal Nazarewicz 1945e19b013SMichal Nazarewicz /** 1955e19b013SMichal Nazarewicz * bitmap_find_next_zero_area - find a contiguous aligned zero area 1965e19b013SMichal Nazarewicz * @map: The address to base the search on 1975e19b013SMichal Nazarewicz * @size: The bitmap size in bits 1985e19b013SMichal Nazarewicz * @start: The bitnumber to start searching at 1995e19b013SMichal Nazarewicz * @nr: The number of zeroed bits we're looking for 2005e19b013SMichal Nazarewicz * @align_mask: Alignment mask for zero area 2015e19b013SMichal Nazarewicz * 2025e19b013SMichal Nazarewicz * The @align_mask should be one less than a power of 2; the effect is that 2035e19b013SMichal Nazarewicz * the bit offset of all zero areas this function finds is multiples of that 2045e19b013SMichal Nazarewicz * power of 2. A @align_mask of 0 means no alignment is required. 2055e19b013SMichal Nazarewicz */ 206*ed8cd2b3SYury Norov static __always_inline 207*ed8cd2b3SYury Norov unsigned long bitmap_find_next_zero_area(unsigned long *map, 2085e19b013SMichal Nazarewicz unsigned long size, 2095e19b013SMichal Nazarewicz unsigned long start, 2105e19b013SMichal Nazarewicz unsigned int nr, 2115e19b013SMichal Nazarewicz unsigned long align_mask) 2125e19b013SMichal Nazarewicz { 2135e19b013SMichal Nazarewicz return bitmap_find_next_zero_area_off(map, size, start, nr, 2145e19b013SMichal Nazarewicz align_mask, 0); 2155e19b013SMichal Nazarewicz } 216c1a2a962SAkinobu Mita 21798635b29SBartosz Golaszewski void bitmap_remap(unsigned long *dst, const unsigned long *src, 2189814ec13SRasmus Villemoes const unsigned long *old, const unsigned long *new, unsigned int nbits); 21998635b29SBartosz Golaszewski int bitmap_bitremap(int oldbit, 220fb5eeeeeSPaul Jackson const unsigned long *old, const unsigned long *new, int bits); 22198635b29SBartosz Golaszewski void bitmap_onto(unsigned long *dst, const unsigned long *orig, 222eb569883SRasmus Villemoes const unsigned long *relmap, unsigned int bits); 22398635b29SBartosz Golaszewski void bitmap_fold(unsigned long *dst, const unsigned long *orig, 224b26ad583SRasmus Villemoes unsigned int sz, unsigned int nbits); 2253aa56885SYury Norov 22689c1e79eSRasmus Villemoes #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) 22789c1e79eSRasmus Villemoes #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) 2281da177e4SLinus Torvalds 229a37fbe66SAlexander Lobakin #define bitmap_size(nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE) 230a37fbe66SAlexander Lobakin 231*ed8cd2b3SYury Norov static __always_inline void bitmap_zero(unsigned long *dst, unsigned int nbits) 2321da177e4SLinus Torvalds { 233a37fbe66SAlexander Lobakin unsigned int len = bitmap_size(nbits); 2343e7e5baaSAlexander Lobakin 2353e7e5baaSAlexander Lobakin if (small_const_nbits(nbits)) 2363e7e5baaSAlexander Lobakin *dst = 0; 2373e7e5baaSAlexander Lobakin else 2381da177e4SLinus Torvalds memset(dst, 0, len); 2391da177e4SLinus Torvalds } 2401da177e4SLinus Torvalds 241*ed8cd2b3SYury Norov static __always_inline void bitmap_fill(unsigned long *dst, unsigned int nbits) 2421da177e4SLinus Torvalds { 243a37fbe66SAlexander Lobakin unsigned int len = bitmap_size(nbits); 2443e7e5baaSAlexander Lobakin 2453e7e5baaSAlexander Lobakin if (small_const_nbits(nbits)) 2463e7e5baaSAlexander Lobakin *dst = ~0UL; 2473e7e5baaSAlexander Lobakin else 2481da177e4SLinus Torvalds memset(dst, 0xff, len); 2491da177e4SLinus Torvalds } 2501da177e4SLinus Torvalds 251*ed8cd2b3SYury Norov static __always_inline 252*ed8cd2b3SYury Norov void bitmap_copy(unsigned long *dst, const unsigned long *src, unsigned int nbits) 2531da177e4SLinus Torvalds { 254a37fbe66SAlexander Lobakin unsigned int len = bitmap_size(nbits); 2553e7e5baaSAlexander Lobakin 2563e7e5baaSAlexander Lobakin if (small_const_nbits(nbits)) 2573e7e5baaSAlexander Lobakin *dst = *src; 2583e7e5baaSAlexander Lobakin else 2591da177e4SLinus Torvalds memcpy(dst, src, len); 2601da177e4SLinus Torvalds } 2611da177e4SLinus Torvalds 262c724f193SYury Norov /* 263c724f193SYury Norov * Copy bitmap and clear tail bits in last word. 264c724f193SYury Norov */ 265*ed8cd2b3SYury Norov static __always_inline 266*ed8cd2b3SYury Norov void bitmap_copy_clear_tail(unsigned long *dst, const unsigned long *src, unsigned int nbits) 267c724f193SYury Norov { 268c724f193SYury Norov bitmap_copy(dst, src, nbits); 269c724f193SYury Norov if (nbits % BITS_PER_LONG) 270c724f193SYury Norov dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits); 271c724f193SYury Norov } 272c724f193SYury Norov 273c724f193SYury Norov /* 274e041e0acSYury Norov * On 32-bit systems bitmaps are represented as u32 arrays internally. On LE64 275e041e0acSYury Norov * machines the order of hi and lo parts of numbers match the bitmap structure. 276e041e0acSYury Norov * In both cases conversion is not needed when copying data from/to arrays of 277e041e0acSYury Norov * u32. But in LE64 case, typecast in bitmap_copy_clear_tail() may lead 278e041e0acSYury Norov * to out-of-bound access. To avoid that, both LE and BE variants of 64-bit 279e041e0acSYury Norov * architectures are not using bitmap_copy_clear_tail(). 280c724f193SYury Norov */ 281c724f193SYury Norov #if BITS_PER_LONG == 64 28298635b29SBartosz Golaszewski void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf, 283c724f193SYury Norov unsigned int nbits); 28498635b29SBartosz Golaszewski void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, 285c724f193SYury Norov unsigned int nbits); 286c724f193SYury Norov #else 287c724f193SYury Norov #define bitmap_from_arr32(bitmap, buf, nbits) \ 288c724f193SYury Norov bitmap_copy_clear_tail((unsigned long *) (bitmap), \ 289c724f193SYury Norov (const unsigned long *) (buf), (nbits)) 290c724f193SYury Norov #define bitmap_to_arr32(buf, bitmap, nbits) \ 291c724f193SYury Norov bitmap_copy_clear_tail((unsigned long *) (buf), \ 292c724f193SYury Norov (const unsigned long *) (bitmap), (nbits)) 293c724f193SYury Norov #endif 294c724f193SYury Norov 2950a97953fSYury Norov /* 296c1d2ba10SYury Norov * On 64-bit systems bitmaps are represented as u64 arrays internally. So, 297c1d2ba10SYury Norov * the conversion is not needed when copying data from/to arrays of u64. 2980a97953fSYury Norov */ 299c1d2ba10SYury Norov #if BITS_PER_LONG == 32 3000a97953fSYury Norov void bitmap_from_arr64(unsigned long *bitmap, const u64 *buf, unsigned int nbits); 3010a97953fSYury Norov void bitmap_to_arr64(u64 *buf, const unsigned long *bitmap, unsigned int nbits); 3020a97953fSYury Norov #else 3030a97953fSYury Norov #define bitmap_from_arr64(bitmap, buf, nbits) \ 3040a97953fSYury Norov bitmap_copy_clear_tail((unsigned long *)(bitmap), (const unsigned long *)(buf), (nbits)) 3050a97953fSYury Norov #define bitmap_to_arr64(buf, bitmap, nbits) \ 3060a97953fSYury Norov bitmap_copy_clear_tail((unsigned long *)(buf), (const unsigned long *)(bitmap), (nbits)) 3070a97953fSYury Norov #endif 3080a97953fSYury Norov 309*ed8cd2b3SYury Norov static __always_inline 310*ed8cd2b3SYury Norov bool bitmap_and(unsigned long *dst, const unsigned long *src1, 3112f9305ebSRasmus Villemoes const unsigned long *src2, unsigned int nbits) 3121da177e4SLinus Torvalds { 3134b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 3147e5f97d1SRasmus Villemoes return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0; 315f4b0373bSLinus Torvalds return __bitmap_and(dst, src1, src2, nbits); 3161da177e4SLinus Torvalds } 3171da177e4SLinus Torvalds 318*ed8cd2b3SYury Norov static __always_inline 319*ed8cd2b3SYury Norov void bitmap_or(unsigned long *dst, const unsigned long *src1, 3202f9305ebSRasmus Villemoes const unsigned long *src2, unsigned int nbits) 3211da177e4SLinus Torvalds { 3224b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 3231da177e4SLinus Torvalds *dst = *src1 | *src2; 3241da177e4SLinus Torvalds else 3251da177e4SLinus Torvalds __bitmap_or(dst, src1, src2, nbits); 3261da177e4SLinus Torvalds } 3271da177e4SLinus Torvalds 328*ed8cd2b3SYury Norov static __always_inline 329*ed8cd2b3SYury Norov void bitmap_xor(unsigned long *dst, const unsigned long *src1, 3302f9305ebSRasmus Villemoes const unsigned long *src2, unsigned int nbits) 3311da177e4SLinus Torvalds { 3324b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 3331da177e4SLinus Torvalds *dst = *src1 ^ *src2; 3341da177e4SLinus Torvalds else 3351da177e4SLinus Torvalds __bitmap_xor(dst, src1, src2, nbits); 3361da177e4SLinus Torvalds } 3371da177e4SLinus Torvalds 338*ed8cd2b3SYury Norov static __always_inline 339*ed8cd2b3SYury Norov bool bitmap_andnot(unsigned long *dst, const unsigned long *src1, 3402f9305ebSRasmus Villemoes const unsigned long *src2, unsigned int nbits) 3411da177e4SLinus Torvalds { 3424b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 34374e76531SRasmus Villemoes return (*dst = *src1 & ~(*src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; 344f4b0373bSLinus Torvalds return __bitmap_andnot(dst, src1, src2, nbits); 3451da177e4SLinus Torvalds } 3461da177e4SLinus Torvalds 347*ed8cd2b3SYury Norov static __always_inline 348*ed8cd2b3SYury Norov void bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int nbits) 3491da177e4SLinus Torvalds { 3504b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 35165b4ee62SRasmus Villemoes *dst = ~(*src); 3521da177e4SLinus Torvalds else 3531da177e4SLinus Torvalds __bitmap_complement(dst, src, nbits); 3541da177e4SLinus Torvalds } 3551da177e4SLinus Torvalds 35621035965SOmar Sandoval #ifdef __LITTLE_ENDIAN 35721035965SOmar Sandoval #define BITMAP_MEM_ALIGNMENT 8 35821035965SOmar Sandoval #else 35921035965SOmar Sandoval #define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long)) 36021035965SOmar Sandoval #endif 36121035965SOmar Sandoval #define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1) 36221035965SOmar Sandoval 363*ed8cd2b3SYury Norov static __always_inline 364*ed8cd2b3SYury Norov bool bitmap_equal(const unsigned long *src1, const unsigned long *src2, unsigned int nbits) 3651da177e4SLinus Torvalds { 3664b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 3671da177e4SLinus Torvalds return !((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); 36821035965SOmar Sandoval if (__builtin_constant_p(nbits & BITMAP_MEM_MASK) && 36921035965SOmar Sandoval IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT)) 3707dd96816SMartin Schwidefsky return !memcmp(src1, src2, nbits / 8); 3711da177e4SLinus Torvalds return __bitmap_equal(src1, src2, nbits); 3721da177e4SLinus Torvalds } 3731da177e4SLinus Torvalds 374b9fa6442SThomas Gleixner /** 3752a7e582fSRandy Dunlap * bitmap_or_equal - Check whether the or of two bitmaps is equal to a third 376b9fa6442SThomas Gleixner * @src1: Pointer to bitmap 1 377b9fa6442SThomas Gleixner * @src2: Pointer to bitmap 2 will be or'ed with bitmap 1 378b9fa6442SThomas Gleixner * @src3: Pointer to bitmap 3. Compare to the result of *@src1 | *@src2 3792a7e582fSRandy Dunlap * @nbits: number of bits in each of these bitmaps 380b9fa6442SThomas Gleixner * 381b9fa6442SThomas Gleixner * Returns: True if (*@src1 | *@src2) == *@src3, false otherwise 382b9fa6442SThomas Gleixner */ 383*ed8cd2b3SYury Norov static __always_inline 384*ed8cd2b3SYury Norov bool bitmap_or_equal(const unsigned long *src1, const unsigned long *src2, 385*ed8cd2b3SYury Norov const unsigned long *src3, unsigned int nbits) 386b9fa6442SThomas Gleixner { 387b9fa6442SThomas Gleixner if (!small_const_nbits(nbits)) 388b9fa6442SThomas Gleixner return __bitmap_or_equal(src1, src2, src3, nbits); 389b9fa6442SThomas Gleixner 390b9fa6442SThomas Gleixner return !(((*src1 | *src2) ^ *src3) & BITMAP_LAST_WORD_MASK(nbits)); 391b9fa6442SThomas Gleixner } 392b9fa6442SThomas Gleixner 393*ed8cd2b3SYury Norov static __always_inline 394*ed8cd2b3SYury Norov bool bitmap_intersects(const unsigned long *src1, const unsigned long *src2, unsigned int nbits) 3951da177e4SLinus Torvalds { 3964b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 3971da177e4SLinus Torvalds return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; 3981da177e4SLinus Torvalds else 3991da177e4SLinus Torvalds return __bitmap_intersects(src1, src2, nbits); 4001da177e4SLinus Torvalds } 4011da177e4SLinus Torvalds 402*ed8cd2b3SYury Norov static __always_inline 403*ed8cd2b3SYury Norov bool bitmap_subset(const unsigned long *src1, const unsigned long *src2, unsigned int nbits) 4041da177e4SLinus Torvalds { 4054b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 4061da177e4SLinus Torvalds return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); 4071da177e4SLinus Torvalds else 4081da177e4SLinus Torvalds return __bitmap_subset(src1, src2, nbits); 4091da177e4SLinus Torvalds } 4101da177e4SLinus Torvalds 411*ed8cd2b3SYury Norov static __always_inline 412*ed8cd2b3SYury Norov bool bitmap_empty(const unsigned long *src, unsigned nbits) 4131da177e4SLinus Torvalds { 4144b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 4151da177e4SLinus Torvalds return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); 4162afe27c7SYury Norov 4172afe27c7SYury Norov return find_first_bit(src, nbits) == nbits; 4181da177e4SLinus Torvalds } 4191da177e4SLinus Torvalds 420*ed8cd2b3SYury Norov static __always_inline 421*ed8cd2b3SYury Norov bool bitmap_full(const unsigned long *src, unsigned int nbits) 4221da177e4SLinus Torvalds { 4234b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 4241da177e4SLinus Torvalds return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); 4252afe27c7SYury Norov 4262afe27c7SYury Norov return find_first_zero_bit(src, nbits) == nbits; 4271da177e4SLinus Torvalds } 4281da177e4SLinus Torvalds 4294dea97f8SYury Norov static __always_inline 4304e23eeebSLinus Torvalds unsigned int bitmap_weight(const unsigned long *src, unsigned int nbits) 4311da177e4SLinus Torvalds { 4324b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 43308cd3657SAndi Kleen return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); 4341da177e4SLinus Torvalds return __bitmap_weight(src, nbits); 4351da177e4SLinus Torvalds } 4361da177e4SLinus Torvalds 43724291cafSYury Norov static __always_inline 43824291cafSYury Norov unsigned long bitmap_weight_and(const unsigned long *src1, 43924291cafSYury Norov const unsigned long *src2, unsigned int nbits) 44024291cafSYury Norov { 44124291cafSYury Norov if (small_const_nbits(nbits)) 44224291cafSYury Norov return hweight_long(*src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)); 44324291cafSYury Norov return __bitmap_weight_and(src1, src2, nbits); 44424291cafSYury Norov } 44524291cafSYury Norov 446c1f5204eSYury Norov static __always_inline 447c1f5204eSYury Norov unsigned long bitmap_weight_andnot(const unsigned long *src1, 448c1f5204eSYury Norov const unsigned long *src2, unsigned int nbits) 449c1f5204eSYury Norov { 450c1f5204eSYury Norov if (small_const_nbits(nbits)) 451c1f5204eSYury Norov return hweight_long(*src1 & ~(*src2) & BITMAP_LAST_WORD_MASK(nbits)); 452c1f5204eSYury Norov return __bitmap_weight_andnot(src1, src2, nbits); 453c1f5204eSYury Norov } 454c1f5204eSYury Norov 455*ed8cd2b3SYury Norov static __always_inline 456*ed8cd2b3SYury Norov void bitmap_set(unsigned long *map, unsigned int start, unsigned int nbits) 457e5af323cSMatthew Wilcox { 458e5af323cSMatthew Wilcox if (__builtin_constant_p(nbits) && nbits == 1) 459e5af323cSMatthew Wilcox __set_bit(start, map); 4603e7e5baaSAlexander Lobakin else if (small_const_nbits(start + nbits)) 4613e7e5baaSAlexander Lobakin *map |= GENMASK(start + nbits - 1, start); 46221035965SOmar Sandoval else if (__builtin_constant_p(start & BITMAP_MEM_MASK) && 46321035965SOmar Sandoval IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) && 46421035965SOmar Sandoval __builtin_constant_p(nbits & BITMAP_MEM_MASK) && 46521035965SOmar Sandoval IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT)) 4662a98dc02SMatthew Wilcox memset((char *)map + start / 8, 0xff, nbits / 8); 467e5af323cSMatthew Wilcox else 468e5af323cSMatthew Wilcox __bitmap_set(map, start, nbits); 469e5af323cSMatthew Wilcox } 470e5af323cSMatthew Wilcox 471*ed8cd2b3SYury Norov static __always_inline 472*ed8cd2b3SYury Norov void bitmap_clear(unsigned long *map, unsigned int start, unsigned int nbits) 473e5af323cSMatthew Wilcox { 474e5af323cSMatthew Wilcox if (__builtin_constant_p(nbits) && nbits == 1) 475e5af323cSMatthew Wilcox __clear_bit(start, map); 4763e7e5baaSAlexander Lobakin else if (small_const_nbits(start + nbits)) 4773e7e5baaSAlexander Lobakin *map &= ~GENMASK(start + nbits - 1, start); 47821035965SOmar Sandoval else if (__builtin_constant_p(start & BITMAP_MEM_MASK) && 47921035965SOmar Sandoval IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) && 48021035965SOmar Sandoval __builtin_constant_p(nbits & BITMAP_MEM_MASK) && 48121035965SOmar Sandoval IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT)) 4822a98dc02SMatthew Wilcox memset((char *)map + start / 8, 0, nbits / 8); 483e5af323cSMatthew Wilcox else 484e5af323cSMatthew Wilcox __bitmap_clear(map, start, nbits); 485e5af323cSMatthew Wilcox } 486e5af323cSMatthew Wilcox 487*ed8cd2b3SYury Norov static __always_inline 488*ed8cd2b3SYury Norov void bitmap_shift_right(unsigned long *dst, const unsigned long *src, 489d9873969SRasmus Villemoes unsigned int shift, unsigned int nbits) 4901da177e4SLinus Torvalds { 4914b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 4922fbad299SRasmus Villemoes *dst = (*src & BITMAP_LAST_WORD_MASK(nbits)) >> shift; 4931da177e4SLinus Torvalds else 4942fbad299SRasmus Villemoes __bitmap_shift_right(dst, src, shift, nbits); 4951da177e4SLinus Torvalds } 4961da177e4SLinus Torvalds 497*ed8cd2b3SYury Norov static __always_inline 498*ed8cd2b3SYury Norov void bitmap_shift_left(unsigned long *dst, const unsigned long *src, 499dba94c25SRasmus Villemoes unsigned int shift, unsigned int nbits) 5001da177e4SLinus Torvalds { 5014b0bc0bcSRusty Russell if (small_const_nbits(nbits)) 502dba94c25SRasmus Villemoes *dst = (*src << shift) & BITMAP_LAST_WORD_MASK(nbits); 5031da177e4SLinus Torvalds else 504dba94c25SRasmus Villemoes __bitmap_shift_left(dst, src, shift, nbits); 5051da177e4SLinus Torvalds } 5061da177e4SLinus Torvalds 507*ed8cd2b3SYury Norov static __always_inline 508*ed8cd2b3SYury Norov void bitmap_replace(unsigned long *dst, 50930544ed5SAndy Shevchenko const unsigned long *old, 51030544ed5SAndy Shevchenko const unsigned long *new, 51130544ed5SAndy Shevchenko const unsigned long *mask, 51230544ed5SAndy Shevchenko unsigned int nbits) 51330544ed5SAndy Shevchenko { 51430544ed5SAndy Shevchenko if (small_const_nbits(nbits)) 51530544ed5SAndy Shevchenko *dst = (*old & ~(*mask)) | (*new & *mask); 51630544ed5SAndy Shevchenko else 51730544ed5SAndy Shevchenko __bitmap_replace(dst, old, new, mask, nbits); 51830544ed5SAndy Shevchenko } 51930544ed5SAndy Shevchenko 520de5f8433SAndy Shevchenko /** 521de5f8433SAndy Shevchenko * bitmap_scatter - Scatter a bitmap according to the given mask 522de5f8433SAndy Shevchenko * @dst: scattered bitmap 523de5f8433SAndy Shevchenko * @src: gathered bitmap 524de5f8433SAndy Shevchenko * @mask: mask representing bits to assign to in the scattered bitmap 525de5f8433SAndy Shevchenko * @nbits: number of bits in each of these bitmaps 526de5f8433SAndy Shevchenko * 527de5f8433SAndy Shevchenko * Scatters bitmap with sequential bits according to the given @mask. 528de5f8433SAndy Shevchenko * 529de5f8433SAndy Shevchenko * Example: 530de5f8433SAndy Shevchenko * If @src bitmap = 0x005a, with @mask = 0x1313, @dst will be 0x0302. 531de5f8433SAndy Shevchenko * 532de5f8433SAndy Shevchenko * Or in binary form 533de5f8433SAndy Shevchenko * @src @mask @dst 534de5f8433SAndy Shevchenko * 0000000001011010 0001001100010011 0000001100000010 535de5f8433SAndy Shevchenko * 536de5f8433SAndy Shevchenko * (Bits 0, 1, 2, 3, 4, 5 are copied to the bits 0, 1, 4, 8, 9, 12) 537de5f8433SAndy Shevchenko * 5382d9d9f25SHerve Codina * A more 'visual' description of the operation:: 5392d9d9f25SHerve Codina * 540de5f8433SAndy Shevchenko * src: 0000000001011010 541de5f8433SAndy Shevchenko * |||||| 542de5f8433SAndy Shevchenko * +------+||||| 543de5f8433SAndy Shevchenko * | +----+|||| 544de5f8433SAndy Shevchenko * | |+----+||| 545de5f8433SAndy Shevchenko * | || +-+|| 546de5f8433SAndy Shevchenko * | || | || 547de5f8433SAndy Shevchenko * mask: ...v..vv...v..vv 548de5f8433SAndy Shevchenko * ...0..11...0..10 549de5f8433SAndy Shevchenko * dst: 0000001100000010 550de5f8433SAndy Shevchenko * 551de5f8433SAndy Shevchenko * A relationship exists between bitmap_scatter() and bitmap_gather(). 552de5f8433SAndy Shevchenko * bitmap_gather() can be seen as the 'reverse' bitmap_scatter() operation. 553de5f8433SAndy Shevchenko * See bitmap_scatter() for details related to this relationship. 554de5f8433SAndy Shevchenko */ 555*ed8cd2b3SYury Norov static __always_inline 556*ed8cd2b3SYury Norov void bitmap_scatter(unsigned long *dst, const unsigned long *src, 557de5f8433SAndy Shevchenko const unsigned long *mask, unsigned int nbits) 558de5f8433SAndy Shevchenko { 559de5f8433SAndy Shevchenko unsigned int n = 0; 560de5f8433SAndy Shevchenko unsigned int bit; 561de5f8433SAndy Shevchenko 562de5f8433SAndy Shevchenko bitmap_zero(dst, nbits); 563de5f8433SAndy Shevchenko 564de5f8433SAndy Shevchenko for_each_set_bit(bit, mask, nbits) 565de5f8433SAndy Shevchenko __assign_bit(bit, dst, test_bit(n++, src)); 566de5f8433SAndy Shevchenko } 567de5f8433SAndy Shevchenko 568de5f8433SAndy Shevchenko /** 569de5f8433SAndy Shevchenko * bitmap_gather - Gather a bitmap according to given mask 570de5f8433SAndy Shevchenko * @dst: gathered bitmap 571de5f8433SAndy Shevchenko * @src: scattered bitmap 572de5f8433SAndy Shevchenko * @mask: mask representing bits to extract from in the scattered bitmap 573de5f8433SAndy Shevchenko * @nbits: number of bits in each of these bitmaps 574de5f8433SAndy Shevchenko * 575de5f8433SAndy Shevchenko * Gathers bitmap with sparse bits according to the given @mask. 576de5f8433SAndy Shevchenko * 577de5f8433SAndy Shevchenko * Example: 578de5f8433SAndy Shevchenko * If @src bitmap = 0x0302, with @mask = 0x1313, @dst will be 0x001a. 579de5f8433SAndy Shevchenko * 580de5f8433SAndy Shevchenko * Or in binary form 581de5f8433SAndy Shevchenko * @src @mask @dst 582de5f8433SAndy Shevchenko * 0000001100000010 0001001100010011 0000000000011010 583de5f8433SAndy Shevchenko * 584de5f8433SAndy Shevchenko * (Bits 0, 1, 4, 8, 9, 12 are copied to the bits 0, 1, 2, 3, 4, 5) 585de5f8433SAndy Shevchenko * 5862d9d9f25SHerve Codina * A more 'visual' description of the operation:: 5872d9d9f25SHerve Codina * 588de5f8433SAndy Shevchenko * mask: ...v..vv...v..vv 589de5f8433SAndy Shevchenko * src: 0000001100000010 590de5f8433SAndy Shevchenko * ^ ^^ ^ 0 591de5f8433SAndy Shevchenko * | || | 10 592de5f8433SAndy Shevchenko * | || > 010 593de5f8433SAndy Shevchenko * | |+--> 1010 594de5f8433SAndy Shevchenko * | +--> 11010 595de5f8433SAndy Shevchenko * +----> 011010 596de5f8433SAndy Shevchenko * dst: 0000000000011010 597de5f8433SAndy Shevchenko * 598de5f8433SAndy Shevchenko * A relationship exists between bitmap_gather() and bitmap_scatter(). See 599de5f8433SAndy Shevchenko * bitmap_scatter() for the bitmap scatter detailed operations. 600de5f8433SAndy Shevchenko * Suppose scattered computed using bitmap_scatter(scattered, src, mask, n). 601de5f8433SAndy Shevchenko * The operation bitmap_gather(result, scattered, mask, n) leads to a result 602de5f8433SAndy Shevchenko * equal or equivalent to src. 603de5f8433SAndy Shevchenko * 604de5f8433SAndy Shevchenko * The result can be 'equivalent' because bitmap_scatter() and bitmap_gather() 605de5f8433SAndy Shevchenko * are not bijective. 606de5f8433SAndy Shevchenko * The result and src values are equivalent in that sense that a call to 607de5f8433SAndy Shevchenko * bitmap_scatter(res, src, mask, n) and a call to 608de5f8433SAndy Shevchenko * bitmap_scatter(res, result, mask, n) will lead to the same res value. 609de5f8433SAndy Shevchenko */ 610*ed8cd2b3SYury Norov static __always_inline 611*ed8cd2b3SYury Norov void bitmap_gather(unsigned long *dst, const unsigned long *src, 612de5f8433SAndy Shevchenko const unsigned long *mask, unsigned int nbits) 613de5f8433SAndy Shevchenko { 614de5f8433SAndy Shevchenko unsigned int n = 0; 615de5f8433SAndy Shevchenko unsigned int bit; 616de5f8433SAndy Shevchenko 617de5f8433SAndy Shevchenko bitmap_zero(dst, nbits); 618de5f8433SAndy Shevchenko 619de5f8433SAndy Shevchenko for_each_set_bit(bit, mask, nbits) 620de5f8433SAndy Shevchenko __assign_bit(n++, dst, test_bit(bit, src)); 621de5f8433SAndy Shevchenko } 622de5f8433SAndy Shevchenko 623*ed8cd2b3SYury Norov static __always_inline 624*ed8cd2b3SYury Norov void bitmap_next_set_region(unsigned long *bitmap, unsigned int *rs, 625*ed8cd2b3SYury Norov unsigned int *re, unsigned int end) 626e837dfdeSDennis Zhou { 627e837dfdeSDennis Zhou *rs = find_next_bit(bitmap, end, *rs); 628e837dfdeSDennis Zhou *re = find_next_zero_bit(bitmap, end, *rs + 1); 629e837dfdeSDennis Zhou } 630e837dfdeSDennis Zhou 631404376afSRandy Dunlap /** 6326cb42f91SYury Norov * bitmap_release_region - release allocated bitmap region 6336cb42f91SYury Norov * @bitmap: array of unsigned longs corresponding to the bitmap 6346cb42f91SYury Norov * @pos: beginning of bit region to release 6356cb42f91SYury Norov * @order: region size (log base 2 of number of bits) to release 6366cb42f91SYury Norov * 6376cb42f91SYury Norov * This is the complement to __bitmap_find_free_region() and releases 6386cb42f91SYury Norov * the found region (by clearing it in the bitmap). 6396cb42f91SYury Norov */ 640*ed8cd2b3SYury Norov static __always_inline 641*ed8cd2b3SYury Norov void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order) 6426cb42f91SYury Norov { 6436cb42f91SYury Norov bitmap_clear(bitmap, pos, BIT(order)); 6446cb42f91SYury Norov } 6456cb42f91SYury Norov 6466cb42f91SYury Norov /** 6476cb42f91SYury Norov * bitmap_allocate_region - allocate bitmap region 6486cb42f91SYury Norov * @bitmap: array of unsigned longs corresponding to the bitmap 6496cb42f91SYury Norov * @pos: beginning of bit region to allocate 6506cb42f91SYury Norov * @order: region size (log base 2 of number of bits) to allocate 6516cb42f91SYury Norov * 6526cb42f91SYury Norov * Allocate (set bits in) a specified region of a bitmap. 6536cb42f91SYury Norov * 6546cb42f91SYury Norov * Returns: 0 on success, or %-EBUSY if specified region wasn't 6556cb42f91SYury Norov * free (not all bits were zero). 6566cb42f91SYury Norov */ 657*ed8cd2b3SYury Norov static __always_inline 658*ed8cd2b3SYury Norov int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order) 6596cb42f91SYury Norov { 6606cb42f91SYury Norov unsigned int len = BIT(order); 6616cb42f91SYury Norov 6626cb42f91SYury Norov if (find_next_bit(bitmap, pos + len, pos) < pos + len) 6636cb42f91SYury Norov return -EBUSY; 6646cb42f91SYury Norov bitmap_set(bitmap, pos, len); 6656cb42f91SYury Norov return 0; 6666cb42f91SYury Norov } 6676cb42f91SYury Norov 6686cb42f91SYury Norov /** 6696cb42f91SYury Norov * bitmap_find_free_region - find a contiguous aligned mem region 6706cb42f91SYury Norov * @bitmap: array of unsigned longs corresponding to the bitmap 6716cb42f91SYury Norov * @bits: number of bits in the bitmap 6726cb42f91SYury Norov * @order: region size (log base 2 of number of bits) to find 6736cb42f91SYury Norov * 6746cb42f91SYury Norov * Find a region of free (zero) bits in a @bitmap of @bits bits and 6756cb42f91SYury Norov * allocate them (set them to one). Only consider regions of length 6766cb42f91SYury Norov * a power (@order) of two, aligned to that power of two, which 6776cb42f91SYury Norov * makes the search algorithm much faster. 6786cb42f91SYury Norov * 6796cb42f91SYury Norov * Returns: the bit offset in bitmap of the allocated region, 6806cb42f91SYury Norov * or -errno on failure. 6816cb42f91SYury Norov */ 682*ed8cd2b3SYury Norov static __always_inline 683*ed8cd2b3SYury Norov int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order) 6846cb42f91SYury Norov { 6856cb42f91SYury Norov unsigned int pos, end; /* scans bitmap by regions of size order */ 6866cb42f91SYury Norov 6876cb42f91SYury Norov for (pos = 0; (end = pos + BIT(order)) <= bits; pos = end) { 6886cb42f91SYury Norov if (!bitmap_allocate_region(bitmap, pos, order)) 6896cb42f91SYury Norov return pos; 6906cb42f91SYury Norov } 6916cb42f91SYury Norov return -ENOMEM; 6926cb42f91SYury Norov } 6936cb42f91SYury Norov 6946cb42f91SYury Norov /** 69560ef6900SYury Norov * BITMAP_FROM_U64() - Represent u64 value in the format suitable for bitmap. 696404376afSRandy Dunlap * @n: u64 value 69760ef6900SYury Norov * 69860ef6900SYury Norov * Linux bitmaps are internally arrays of unsigned longs, i.e. 32-bit 69960ef6900SYury Norov * integers in 32-bit environment, and 64-bit integers in 64-bit one. 70060ef6900SYury Norov * 70160ef6900SYury Norov * There are four combinations of endianness and length of the word in linux 70260ef6900SYury Norov * ABIs: LE64, BE64, LE32 and BE32. 70360ef6900SYury Norov * 70460ef6900SYury Norov * On 64-bit kernels 64-bit LE and BE numbers are naturally ordered in 70560ef6900SYury Norov * bitmaps and therefore don't require any special handling. 70660ef6900SYury Norov * 70760ef6900SYury Norov * On 32-bit kernels 32-bit LE ABI orders lo word of 64-bit number in memory 70860ef6900SYury Norov * prior to hi, and 32-bit BE orders hi word prior to lo. The bitmap on the 70960ef6900SYury Norov * other hand is represented as an array of 32-bit words and the position of 71060ef6900SYury Norov * bit N may therefore be calculated as: word #(N/32) and bit #(N%32) in that 71160ef6900SYury Norov * word. For example, bit #42 is located at 10th position of 2nd word. 71260ef6900SYury Norov * It matches 32-bit LE ABI, and we can simply let the compiler store 64-bit 71360ef6900SYury Norov * values in memory as it usually does. But for BE we need to swap hi and lo 71460ef6900SYury Norov * words manually. 71560ef6900SYury Norov * 71660ef6900SYury Norov * With all that, the macro BITMAP_FROM_U64() does explicit reordering of hi and 71760ef6900SYury Norov * lo parts of u64. For LE32 it does nothing, and for BE environment it swaps 71860ef6900SYury Norov * hi and lo words, as is expected by bitmap. 71960ef6900SYury Norov */ 72060ef6900SYury Norov #if __BITS_PER_LONG == 64 72160ef6900SYury Norov #define BITMAP_FROM_U64(n) (n) 72260ef6900SYury Norov #else 72360ef6900SYury Norov #define BITMAP_FROM_U64(n) ((unsigned long) ((u64)(n) & ULONG_MAX)), \ 72460ef6900SYury Norov ((unsigned long) ((u64)(n) >> 32)) 72560ef6900SYury Norov #endif 72660ef6900SYury Norov 727404376afSRandy Dunlap /** 72829dd3288SMadhavan Srinivasan * bitmap_from_u64 - Check and swap words within u64. 72929dd3288SMadhavan Srinivasan * @mask: source bitmap 73029dd3288SMadhavan Srinivasan * @dst: destination bitmap 73129dd3288SMadhavan Srinivasan * 732404376afSRandy Dunlap * In 32-bit Big Endian kernel, when using ``(u32 *)(&val)[*]`` 73329dd3288SMadhavan Srinivasan * to read u64 mask, we will get the wrong word. 734404376afSRandy Dunlap * That is ``(u32 *)(&val)[0]`` gets the upper 32 bits, 73529dd3288SMadhavan Srinivasan * but we expect the lower 32-bits of u64. 73629dd3288SMadhavan Srinivasan */ 737*ed8cd2b3SYury Norov static __always_inline void bitmap_from_u64(unsigned long *dst, u64 mask) 73829dd3288SMadhavan Srinivasan { 7390a97953fSYury Norov bitmap_from_arr64(dst, &mask, 64); 74029dd3288SMadhavan Srinivasan } 74129dd3288SMadhavan Srinivasan 742169c474fSWilliam Breathitt Gray /** 74363c15822SSyed Nayyar Waris * bitmap_read - read a value of n-bits from the memory region 74463c15822SSyed Nayyar Waris * @map: address to the bitmap memory region 74563c15822SSyed Nayyar Waris * @start: bit offset of the n-bit value 74663c15822SSyed Nayyar Waris * @nbits: size of value in bits, nonzero, up to BITS_PER_LONG 74763c15822SSyed Nayyar Waris * 74863c15822SSyed Nayyar Waris * Returns: value of @nbits bits located at the @start bit offset within the 74963c15822SSyed Nayyar Waris * @map memory region. For @nbits = 0 and @nbits > BITS_PER_LONG the return 75063c15822SSyed Nayyar Waris * value is undefined. 75163c15822SSyed Nayyar Waris */ 752*ed8cd2b3SYury Norov static __always_inline 753*ed8cd2b3SYury Norov unsigned long bitmap_read(const unsigned long *map, unsigned long start, unsigned long nbits) 75463c15822SSyed Nayyar Waris { 75563c15822SSyed Nayyar Waris size_t index = BIT_WORD(start); 75663c15822SSyed Nayyar Waris unsigned long offset = start % BITS_PER_LONG; 75763c15822SSyed Nayyar Waris unsigned long space = BITS_PER_LONG - offset; 75863c15822SSyed Nayyar Waris unsigned long value_low, value_high; 75963c15822SSyed Nayyar Waris 76063c15822SSyed Nayyar Waris if (unlikely(!nbits || nbits > BITS_PER_LONG)) 76163c15822SSyed Nayyar Waris return 0; 76263c15822SSyed Nayyar Waris 76363c15822SSyed Nayyar Waris if (space >= nbits) 76463c15822SSyed Nayyar Waris return (map[index] >> offset) & BITMAP_LAST_WORD_MASK(nbits); 76563c15822SSyed Nayyar Waris 76663c15822SSyed Nayyar Waris value_low = map[index] & BITMAP_FIRST_WORD_MASK(start); 76763c15822SSyed Nayyar Waris value_high = map[index + 1] & BITMAP_LAST_WORD_MASK(start + nbits); 76863c15822SSyed Nayyar Waris return (value_low >> offset) | (value_high << space); 76963c15822SSyed Nayyar Waris } 77063c15822SSyed Nayyar Waris 77163c15822SSyed Nayyar Waris /** 77263c15822SSyed Nayyar Waris * bitmap_write - write n-bit value within a memory region 77363c15822SSyed Nayyar Waris * @map: address to the bitmap memory region 77463c15822SSyed Nayyar Waris * @value: value to write, clamped to nbits 77563c15822SSyed Nayyar Waris * @start: bit offset of the n-bit value 77663c15822SSyed Nayyar Waris * @nbits: size of value in bits, nonzero, up to BITS_PER_LONG. 77763c15822SSyed Nayyar Waris * 77863c15822SSyed Nayyar Waris * bitmap_write() behaves as-if implemented as @nbits calls of __assign_bit(), 77963c15822SSyed Nayyar Waris * i.e. bits beyond @nbits are ignored: 78063c15822SSyed Nayyar Waris * 78163c15822SSyed Nayyar Waris * for (bit = 0; bit < nbits; bit++) 78263c15822SSyed Nayyar Waris * __assign_bit(start + bit, bitmap, val & BIT(bit)); 78363c15822SSyed Nayyar Waris * 78463c15822SSyed Nayyar Waris * For @nbits == 0 and @nbits > BITS_PER_LONG no writes are performed. 78563c15822SSyed Nayyar Waris */ 786*ed8cd2b3SYury Norov static __always_inline 787*ed8cd2b3SYury Norov void bitmap_write(unsigned long *map, unsigned long value, 78863c15822SSyed Nayyar Waris unsigned long start, unsigned long nbits) 78963c15822SSyed Nayyar Waris { 79063c15822SSyed Nayyar Waris size_t index; 79163c15822SSyed Nayyar Waris unsigned long offset; 79263c15822SSyed Nayyar Waris unsigned long space; 79363c15822SSyed Nayyar Waris unsigned long mask; 79463c15822SSyed Nayyar Waris bool fit; 79563c15822SSyed Nayyar Waris 79663c15822SSyed Nayyar Waris if (unlikely(!nbits || nbits > BITS_PER_LONG)) 79763c15822SSyed Nayyar Waris return; 79863c15822SSyed Nayyar Waris 79963c15822SSyed Nayyar Waris mask = BITMAP_LAST_WORD_MASK(nbits); 80063c15822SSyed Nayyar Waris value &= mask; 80163c15822SSyed Nayyar Waris offset = start % BITS_PER_LONG; 80263c15822SSyed Nayyar Waris space = BITS_PER_LONG - offset; 80363c15822SSyed Nayyar Waris fit = space >= nbits; 80463c15822SSyed Nayyar Waris index = BIT_WORD(start); 80563c15822SSyed Nayyar Waris 80663c15822SSyed Nayyar Waris map[index] &= (fit ? (~(mask << offset)) : ~BITMAP_FIRST_WORD_MASK(start)); 80763c15822SSyed Nayyar Waris map[index] |= value << offset; 80863c15822SSyed Nayyar Waris if (fit) 80963c15822SSyed Nayyar Waris return; 81063c15822SSyed Nayyar Waris 81163c15822SSyed Nayyar Waris map[index + 1] &= BITMAP_FIRST_WORD_MASK(start + nbits); 81263c15822SSyed Nayyar Waris map[index + 1] |= (value >> space); 81363c15822SSyed Nayyar Waris } 81463c15822SSyed Nayyar Waris 815b4475970SAlexander Lobakin #define bitmap_get_value8(map, start) \ 816b4475970SAlexander Lobakin bitmap_read(map, start, BITS_PER_BYTE) 817b4475970SAlexander Lobakin #define bitmap_set_value8(map, value, start) \ 818b4475970SAlexander Lobakin bitmap_write(map, value, start, BITS_PER_BYTE) 819b4475970SAlexander Lobakin 8201da177e4SLinus Torvalds #endif /* __ASSEMBLY__ */ 8211da177e4SLinus Torvalds 8221da177e4SLinus Torvalds #endif /* __LINUX_BITMAP_H */ 823