140b0b3f8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * lib/bitmap.c
41da177e4SLinus Torvalds * Helper functions for bitmap.h.
51da177e4SLinus Torvalds */
6c13656b9SBartosz Golaszewski
71da177e4SLinus Torvalds #include <linux/bitmap.h>
81da177e4SLinus Torvalds #include <linux/bitops.h>
9c13656b9SBartosz Golaszewski #include <linux/ctype.h>
10e829c2e4SBartosz Golaszewski #include <linux/device.h>
11c13656b9SBartosz Golaszewski #include <linux/export.h>
12c42b65e3SAndy Shevchenko #include <linux/slab.h>
13e371c481SYury Norov
147d7363e4SRandy Dunlap /**
157d7363e4SRandy Dunlap * DOC: bitmap introduction
167d7363e4SRandy Dunlap *
17197d6c1dSRandy Dunlap * bitmaps provide an array of bits, implemented using an
181da177e4SLinus Torvalds * array of unsigned longs. The number of valid bits in a
191da177e4SLinus Torvalds * given bitmap does _not_ need to be an exact multiple of
201da177e4SLinus Torvalds * BITS_PER_LONG.
211da177e4SLinus Torvalds *
221da177e4SLinus Torvalds * The possible unused bits in the last, partially used word
231da177e4SLinus Torvalds * of a bitmap are 'don't care'. The implementation makes
241da177e4SLinus Torvalds * no particular effort to keep them zero. It ensures that
251da177e4SLinus Torvalds * their value will not affect the results of any operation.
261da177e4SLinus Torvalds * The bitmap operations that return Boolean (bitmap_empty,
271da177e4SLinus Torvalds * for example) or scalar (bitmap_weight, for example) results
281da177e4SLinus Torvalds * carefully filter out these unused bits from impacting their
291da177e4SLinus Torvalds * results.
301da177e4SLinus Torvalds *
311da177e4SLinus Torvalds * The byte ordering of bitmaps is more natural on little
321da177e4SLinus Torvalds * endian architectures. See the big-endian headers
331da177e4SLinus Torvalds * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h
341da177e4SLinus Torvalds * for the best explanations of this ordering.
351da177e4SLinus Torvalds */
361da177e4SLinus Torvalds
__bitmap_equal(const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)37005f1700SKees Cook bool __bitmap_equal(const unsigned long *bitmap1,
385e068069SRasmus Villemoes const unsigned long *bitmap2, unsigned int bits)
391da177e4SLinus Torvalds {
405e068069SRasmus Villemoes unsigned int k, lim = bits/BITS_PER_LONG;
411da177e4SLinus Torvalds for (k = 0; k < lim; ++k)
421da177e4SLinus Torvalds if (bitmap1[k] != bitmap2[k])
43005f1700SKees Cook return false;
441da177e4SLinus Torvalds
451da177e4SLinus Torvalds if (bits % BITS_PER_LONG)
461da177e4SLinus Torvalds if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
47005f1700SKees Cook return false;
481da177e4SLinus Torvalds
49005f1700SKees Cook return true;
501da177e4SLinus Torvalds }
511da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_equal);
521da177e4SLinus Torvalds
__bitmap_or_equal(const unsigned long * bitmap1,const unsigned long * bitmap2,const unsigned long * bitmap3,unsigned int bits)53b9fa6442SThomas Gleixner bool __bitmap_or_equal(const unsigned long *bitmap1,
54b9fa6442SThomas Gleixner const unsigned long *bitmap2,
55b9fa6442SThomas Gleixner const unsigned long *bitmap3,
56b9fa6442SThomas Gleixner unsigned int bits)
57b9fa6442SThomas Gleixner {
58b9fa6442SThomas Gleixner unsigned int k, lim = bits / BITS_PER_LONG;
59b9fa6442SThomas Gleixner unsigned long tmp;
60b9fa6442SThomas Gleixner
61b9fa6442SThomas Gleixner for (k = 0; k < lim; ++k) {
62b9fa6442SThomas Gleixner if ((bitmap1[k] | bitmap2[k]) != bitmap3[k])
63b9fa6442SThomas Gleixner return false;
64b9fa6442SThomas Gleixner }
65b9fa6442SThomas Gleixner
66b9fa6442SThomas Gleixner if (!(bits % BITS_PER_LONG))
67b9fa6442SThomas Gleixner return true;
68b9fa6442SThomas Gleixner
69b9fa6442SThomas Gleixner tmp = (bitmap1[k] | bitmap2[k]) ^ bitmap3[k];
70b9fa6442SThomas Gleixner return (tmp & BITMAP_LAST_WORD_MASK(bits)) == 0;
71b9fa6442SThomas Gleixner }
72b9fa6442SThomas Gleixner
__bitmap_complement(unsigned long * dst,const unsigned long * src,unsigned int bits)733d6684f4SRasmus Villemoes void __bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int bits)
741da177e4SLinus Torvalds {
75ca1250bbSYury Norov unsigned int k, lim = BITS_TO_LONGS(bits);
761da177e4SLinus Torvalds for (k = 0; k < lim; ++k)
771da177e4SLinus Torvalds dst[k] = ~src[k];
781da177e4SLinus Torvalds }
791da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_complement);
801da177e4SLinus Torvalds
8172fd4a35SRobert P. J. Day /**
821da177e4SLinus Torvalds * __bitmap_shift_right - logical right shift of the bits in a bitmap
8305fb6bf0SRandy Dunlap * @dst : destination bitmap
8405fb6bf0SRandy Dunlap * @src : source bitmap
8505fb6bf0SRandy Dunlap * @shift : shift by this many bits
862fbad299SRasmus Villemoes * @nbits : bitmap size, in bits
871da177e4SLinus Torvalds *
881da177e4SLinus Torvalds * Shifting right (dividing) means moving bits in the MS -> LS bit
891da177e4SLinus Torvalds * direction. Zeros are fed into the vacated MS positions and the
901da177e4SLinus Torvalds * LS bits shifted off the bottom are lost.
911da177e4SLinus Torvalds */
__bitmap_shift_right(unsigned long * dst,const unsigned long * src,unsigned shift,unsigned nbits)922fbad299SRasmus Villemoes void __bitmap_shift_right(unsigned long *dst, const unsigned long *src,
932fbad299SRasmus Villemoes unsigned shift, unsigned nbits)
941da177e4SLinus Torvalds {
95cfac1d08SRasmus Villemoes unsigned k, lim = BITS_TO_LONGS(nbits);
962fbad299SRasmus Villemoes unsigned off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
97cfac1d08SRasmus Villemoes unsigned long mask = BITMAP_LAST_WORD_MASK(nbits);
981da177e4SLinus Torvalds for (k = 0; off + k < lim; ++k) {
991da177e4SLinus Torvalds unsigned long upper, lower;
1001da177e4SLinus Torvalds
1011da177e4SLinus Torvalds /*
1021da177e4SLinus Torvalds * If shift is not word aligned, take lower rem bits of
1031da177e4SLinus Torvalds * word above and make them the top rem bits of result.
1041da177e4SLinus Torvalds */
1051da177e4SLinus Torvalds if (!rem || off + k + 1 >= lim)
1061da177e4SLinus Torvalds upper = 0;
1071da177e4SLinus Torvalds else {
1081da177e4SLinus Torvalds upper = src[off + k + 1];
109cfac1d08SRasmus Villemoes if (off + k + 1 == lim - 1)
1101da177e4SLinus Torvalds upper &= mask;
1119d8a6b2aSRasmus Villemoes upper <<= (BITS_PER_LONG - rem);
1121da177e4SLinus Torvalds }
1131da177e4SLinus Torvalds lower = src[off + k];
114cfac1d08SRasmus Villemoes if (off + k == lim - 1)
1151da177e4SLinus Torvalds lower &= mask;
1169d8a6b2aSRasmus Villemoes lower >>= rem;
1179d8a6b2aSRasmus Villemoes dst[k] = lower | upper;
1181da177e4SLinus Torvalds }
1191da177e4SLinus Torvalds if (off)
1201da177e4SLinus Torvalds memset(&dst[lim - off], 0, off*sizeof(unsigned long));
1211da177e4SLinus Torvalds }
1221da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_shift_right);
1231da177e4SLinus Torvalds
1241da177e4SLinus Torvalds
12572fd4a35SRobert P. J. Day /**
1261da177e4SLinus Torvalds * __bitmap_shift_left - logical left shift of the bits in a bitmap
12705fb6bf0SRandy Dunlap * @dst : destination bitmap
12805fb6bf0SRandy Dunlap * @src : source bitmap
12905fb6bf0SRandy Dunlap * @shift : shift by this many bits
130dba94c25SRasmus Villemoes * @nbits : bitmap size, in bits
1311da177e4SLinus Torvalds *
1321da177e4SLinus Torvalds * Shifting left (multiplying) means moving bits in the LS -> MS
1331da177e4SLinus Torvalds * direction. Zeros are fed into the vacated LS bit positions
1341da177e4SLinus Torvalds * and those MS bits shifted off the top are lost.
1351da177e4SLinus Torvalds */
1361da177e4SLinus Torvalds
__bitmap_shift_left(unsigned long * dst,const unsigned long * src,unsigned int shift,unsigned int nbits)137dba94c25SRasmus Villemoes void __bitmap_shift_left(unsigned long *dst, const unsigned long *src,
138dba94c25SRasmus Villemoes unsigned int shift, unsigned int nbits)
1391da177e4SLinus Torvalds {
140dba94c25SRasmus Villemoes int k;
1417f590657SRasmus Villemoes unsigned int lim = BITS_TO_LONGS(nbits);
142dba94c25SRasmus Villemoes unsigned int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
1431da177e4SLinus Torvalds for (k = lim - off - 1; k >= 0; --k) {
1441da177e4SLinus Torvalds unsigned long upper, lower;
1451da177e4SLinus Torvalds
1461da177e4SLinus Torvalds /*
1471da177e4SLinus Torvalds * If shift is not word aligned, take upper rem bits of
1481da177e4SLinus Torvalds * word below and make them the bottom rem bits of result.
1491da177e4SLinus Torvalds */
1501da177e4SLinus Torvalds if (rem && k > 0)
1516d874ecaSRasmus Villemoes lower = src[k - 1] >> (BITS_PER_LONG - rem);
1521da177e4SLinus Torvalds else
1531da177e4SLinus Torvalds lower = 0;
1547f590657SRasmus Villemoes upper = src[k] << rem;
1556d874ecaSRasmus Villemoes dst[k + off] = lower | upper;
1561da177e4SLinus Torvalds }
1571da177e4SLinus Torvalds if (off)
1581da177e4SLinus Torvalds memset(dst, 0, off*sizeof(unsigned long));
1591da177e4SLinus Torvalds }
1601da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_shift_left);
1611da177e4SLinus Torvalds
16220927671SStefano Brivio /**
16320927671SStefano Brivio * bitmap_cut() - remove bit region from bitmap and right shift remaining bits
16420927671SStefano Brivio * @dst: destination bitmap, might overlap with src
16520927671SStefano Brivio * @src: source bitmap
16620927671SStefano Brivio * @first: start bit of region to be removed
16720927671SStefano Brivio * @cut: number of bits to remove
16820927671SStefano Brivio * @nbits: bitmap size, in bits
16920927671SStefano Brivio *
17020927671SStefano Brivio * Set the n-th bit of @dst iff the n-th bit of @src is set and
17120927671SStefano Brivio * n is less than @first, or the m-th bit of @src is set for any
17220927671SStefano Brivio * m such that @first <= n < nbits, and m = n + @cut.
17320927671SStefano Brivio *
17420927671SStefano Brivio * In pictures, example for a big-endian 32-bit architecture:
17520927671SStefano Brivio *
1764642289bSMauro Carvalho Chehab * The @src bitmap is::
1774642289bSMauro Carvalho Chehab *
17820927671SStefano Brivio * 31 63
17920927671SStefano Brivio * | |
18020927671SStefano Brivio * 10000000 11000001 11110010 00010101 10000000 11000001 01110010 00010101
18120927671SStefano Brivio * | | | |
18220927671SStefano Brivio * 16 14 0 32
18320927671SStefano Brivio *
1844642289bSMauro Carvalho Chehab * if @cut is 3, and @first is 14, bits 14-16 in @src are cut and @dst is::
18520927671SStefano Brivio *
18620927671SStefano Brivio * 31 63
18720927671SStefano Brivio * | |
18820927671SStefano Brivio * 10110000 00011000 00110010 00010101 00010000 00011000 00101110 01000010
18920927671SStefano Brivio * | | |
19020927671SStefano Brivio * 14 (bit 17 0 32
19120927671SStefano Brivio * from @src)
19220927671SStefano Brivio *
19320927671SStefano Brivio * Note that @dst and @src might overlap partially or entirely.
19420927671SStefano Brivio *
19520927671SStefano Brivio * This is implemented in the obvious way, with a shift and carry
19620927671SStefano Brivio * step for each moved bit. Optimisation is left as an exercise
19720927671SStefano Brivio * for the compiler.
19820927671SStefano Brivio */
bitmap_cut(unsigned long * dst,const unsigned long * src,unsigned int first,unsigned int cut,unsigned int nbits)19920927671SStefano Brivio void bitmap_cut(unsigned long *dst, const unsigned long *src,
20020927671SStefano Brivio unsigned int first, unsigned int cut, unsigned int nbits)
20120927671SStefano Brivio {
20220927671SStefano Brivio unsigned int len = BITS_TO_LONGS(nbits);
20320927671SStefano Brivio unsigned long keep = 0, carry;
20420927671SStefano Brivio int i;
20520927671SStefano Brivio
20620927671SStefano Brivio if (first % BITS_PER_LONG) {
20720927671SStefano Brivio keep = src[first / BITS_PER_LONG] &
20820927671SStefano Brivio (~0UL >> (BITS_PER_LONG - first % BITS_PER_LONG));
20920927671SStefano Brivio }
21020927671SStefano Brivio
2115959f829SStefano Brivio memmove(dst, src, len * sizeof(*dst));
2125959f829SStefano Brivio
21320927671SStefano Brivio while (cut--) {
21420927671SStefano Brivio for (i = first / BITS_PER_LONG; i < len; i++) {
21520927671SStefano Brivio if (i < len - 1)
21620927671SStefano Brivio carry = dst[i + 1] & 1UL;
21720927671SStefano Brivio else
21820927671SStefano Brivio carry = 0;
21920927671SStefano Brivio
22020927671SStefano Brivio dst[i] = (dst[i] >> 1) | (carry << (BITS_PER_LONG - 1));
22120927671SStefano Brivio }
22220927671SStefano Brivio }
22320927671SStefano Brivio
22420927671SStefano Brivio dst[first / BITS_PER_LONG] &= ~0UL << (first % BITS_PER_LONG);
22520927671SStefano Brivio dst[first / BITS_PER_LONG] |= keep;
22620927671SStefano Brivio }
22720927671SStefano Brivio EXPORT_SYMBOL(bitmap_cut);
22820927671SStefano Brivio
__bitmap_and(unsigned long * dst,const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)229e2863a78SYury Norov bool __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
2302f9305ebSRasmus Villemoes const unsigned long *bitmap2, unsigned int bits)
2311da177e4SLinus Torvalds {
2322f9305ebSRasmus Villemoes unsigned int k;
2337e5f97d1SRasmus Villemoes unsigned int lim = bits/BITS_PER_LONG;
234f4b0373bSLinus Torvalds unsigned long result = 0;
2351da177e4SLinus Torvalds
2367e5f97d1SRasmus Villemoes for (k = 0; k < lim; k++)
237f4b0373bSLinus Torvalds result |= (dst[k] = bitmap1[k] & bitmap2[k]);
2387e5f97d1SRasmus Villemoes if (bits % BITS_PER_LONG)
2397e5f97d1SRasmus Villemoes result |= (dst[k] = bitmap1[k] & bitmap2[k] &
2407e5f97d1SRasmus Villemoes BITMAP_LAST_WORD_MASK(bits));
241f4b0373bSLinus Torvalds return result != 0;
2421da177e4SLinus Torvalds }
2431da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_and);
2441da177e4SLinus Torvalds
__bitmap_or(unsigned long * dst,const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)2451da177e4SLinus Torvalds void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
2462f9305ebSRasmus Villemoes const unsigned long *bitmap2, unsigned int bits)
2471da177e4SLinus Torvalds {
2482f9305ebSRasmus Villemoes unsigned int k;
2492f9305ebSRasmus Villemoes unsigned int nr = BITS_TO_LONGS(bits);
2501da177e4SLinus Torvalds
2511da177e4SLinus Torvalds for (k = 0; k < nr; k++)
2521da177e4SLinus Torvalds dst[k] = bitmap1[k] | bitmap2[k];
2531da177e4SLinus Torvalds }
2541da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_or);
2551da177e4SLinus Torvalds
__bitmap_xor(unsigned long * dst,const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)2561da177e4SLinus Torvalds void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
2572f9305ebSRasmus Villemoes const unsigned long *bitmap2, unsigned int bits)
2581da177e4SLinus Torvalds {
2592f9305ebSRasmus Villemoes unsigned int k;
2602f9305ebSRasmus Villemoes unsigned int nr = BITS_TO_LONGS(bits);
2611da177e4SLinus Torvalds
2621da177e4SLinus Torvalds for (k = 0; k < nr; k++)
2631da177e4SLinus Torvalds dst[k] = bitmap1[k] ^ bitmap2[k];
2641da177e4SLinus Torvalds }
2651da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_xor);
2661da177e4SLinus Torvalds
__bitmap_andnot(unsigned long * dst,const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)267e2863a78SYury Norov bool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
2682f9305ebSRasmus Villemoes const unsigned long *bitmap2, unsigned int bits)
2691da177e4SLinus Torvalds {
2702f9305ebSRasmus Villemoes unsigned int k;
27174e76531SRasmus Villemoes unsigned int lim = bits/BITS_PER_LONG;
272f4b0373bSLinus Torvalds unsigned long result = 0;
2731da177e4SLinus Torvalds
27474e76531SRasmus Villemoes for (k = 0; k < lim; k++)
275f4b0373bSLinus Torvalds result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
27674e76531SRasmus Villemoes if (bits % BITS_PER_LONG)
27774e76531SRasmus Villemoes result |= (dst[k] = bitmap1[k] & ~bitmap2[k] &
27874e76531SRasmus Villemoes BITMAP_LAST_WORD_MASK(bits));
279f4b0373bSLinus Torvalds return result != 0;
2801da177e4SLinus Torvalds }
2811da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_andnot);
2821da177e4SLinus Torvalds
__bitmap_replace(unsigned long * dst,const unsigned long * old,const unsigned long * new,const unsigned long * mask,unsigned int nbits)28330544ed5SAndy Shevchenko void __bitmap_replace(unsigned long *dst,
28430544ed5SAndy Shevchenko const unsigned long *old, const unsigned long *new,
28530544ed5SAndy Shevchenko const unsigned long *mask, unsigned int nbits)
28630544ed5SAndy Shevchenko {
28730544ed5SAndy Shevchenko unsigned int k;
28830544ed5SAndy Shevchenko unsigned int nr = BITS_TO_LONGS(nbits);
28930544ed5SAndy Shevchenko
29030544ed5SAndy Shevchenko for (k = 0; k < nr; k++)
29130544ed5SAndy Shevchenko dst[k] = (old[k] & ~mask[k]) | (new[k] & mask[k]);
29230544ed5SAndy Shevchenko }
29330544ed5SAndy Shevchenko EXPORT_SYMBOL(__bitmap_replace);
29430544ed5SAndy Shevchenko
__bitmap_intersects(const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)295005f1700SKees Cook bool __bitmap_intersects(const unsigned long *bitmap1,
2966dfe9799SRasmus Villemoes const unsigned long *bitmap2, unsigned int bits)
2971da177e4SLinus Torvalds {
2986dfe9799SRasmus Villemoes unsigned int k, lim = bits/BITS_PER_LONG;
2991da177e4SLinus Torvalds for (k = 0; k < lim; ++k)
3001da177e4SLinus Torvalds if (bitmap1[k] & bitmap2[k])
301005f1700SKees Cook return true;
3021da177e4SLinus Torvalds
3031da177e4SLinus Torvalds if (bits % BITS_PER_LONG)
3041da177e4SLinus Torvalds if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
305005f1700SKees Cook return true;
306005f1700SKees Cook return false;
3071da177e4SLinus Torvalds }
3081da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_intersects);
3091da177e4SLinus Torvalds
__bitmap_subset(const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)310005f1700SKees Cook bool __bitmap_subset(const unsigned long *bitmap1,
3115be20213SRasmus Villemoes const unsigned long *bitmap2, unsigned int bits)
3121da177e4SLinus Torvalds {
3135be20213SRasmus Villemoes unsigned int k, lim = bits/BITS_PER_LONG;
3141da177e4SLinus Torvalds for (k = 0; k < lim; ++k)
3151da177e4SLinus Torvalds if (bitmap1[k] & ~bitmap2[k])
316005f1700SKees Cook return false;
3171da177e4SLinus Torvalds
3181da177e4SLinus Torvalds if (bits % BITS_PER_LONG)
3191da177e4SLinus Torvalds if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
320005f1700SKees Cook return false;
321005f1700SKees Cook return true;
3221da177e4SLinus Torvalds }
3231da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_subset);
3241da177e4SLinus Torvalds
32524291cafSYury Norov #define BITMAP_WEIGHT(FETCH, bits) \
32624291cafSYury Norov ({ \
32724291cafSYury Norov unsigned int __bits = (bits), idx, w = 0; \
32824291cafSYury Norov \
32924291cafSYury Norov for (idx = 0; idx < __bits / BITS_PER_LONG; idx++) \
33024291cafSYury Norov w += hweight_long(FETCH); \
33124291cafSYury Norov \
33224291cafSYury Norov if (__bits % BITS_PER_LONG) \
33324291cafSYury Norov w += hweight_long((FETCH) & BITMAP_LAST_WORD_MASK(__bits)); \
33424291cafSYury Norov \
33524291cafSYury Norov w; \
33624291cafSYury Norov })
33724291cafSYury Norov
__bitmap_weight(const unsigned long * bitmap,unsigned int bits)3384e23eeebSLinus Torvalds unsigned int __bitmap_weight(const unsigned long *bitmap, unsigned int bits)
3391da177e4SLinus Torvalds {
34024291cafSYury Norov return BITMAP_WEIGHT(bitmap[idx], bits);
3411da177e4SLinus Torvalds }
3421da177e4SLinus Torvalds EXPORT_SYMBOL(__bitmap_weight);
3431da177e4SLinus Torvalds
__bitmap_weight_and(const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)34424291cafSYury Norov unsigned int __bitmap_weight_and(const unsigned long *bitmap1,
34524291cafSYury Norov const unsigned long *bitmap2, unsigned int bits)
34624291cafSYury Norov {
34724291cafSYury Norov return BITMAP_WEIGHT(bitmap1[idx] & bitmap2[idx], bits);
34824291cafSYury Norov }
34924291cafSYury Norov EXPORT_SYMBOL(__bitmap_weight_and);
35024291cafSYury Norov
__bitmap_weight_andnot(const unsigned long * bitmap1,const unsigned long * bitmap2,unsigned int bits)351*c1f5204eSYury Norov unsigned int __bitmap_weight_andnot(const unsigned long *bitmap1,
352*c1f5204eSYury Norov const unsigned long *bitmap2, unsigned int bits)
353*c1f5204eSYury Norov {
354*c1f5204eSYury Norov return BITMAP_WEIGHT(bitmap1[idx] & ~bitmap2[idx], bits);
355*c1f5204eSYury Norov }
356*c1f5204eSYury Norov EXPORT_SYMBOL(__bitmap_weight_andnot);
357*c1f5204eSYury Norov
__bitmap_set(unsigned long * map,unsigned int start,int len)358e5af323cSMatthew Wilcox void __bitmap_set(unsigned long *map, unsigned int start, int len)
359c1a2a962SAkinobu Mita {
360c1a2a962SAkinobu Mita unsigned long *p = map + BIT_WORD(start);
361fb5ac542SRasmus Villemoes const unsigned int size = start + len;
362c1a2a962SAkinobu Mita int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
363c1a2a962SAkinobu Mita unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
364c1a2a962SAkinobu Mita
365fb5ac542SRasmus Villemoes while (len - bits_to_set >= 0) {
366c1a2a962SAkinobu Mita *p |= mask_to_set;
367fb5ac542SRasmus Villemoes len -= bits_to_set;
368c1a2a962SAkinobu Mita bits_to_set = BITS_PER_LONG;
369c1a2a962SAkinobu Mita mask_to_set = ~0UL;
370c1a2a962SAkinobu Mita p++;
371c1a2a962SAkinobu Mita }
372fb5ac542SRasmus Villemoes if (len) {
373c1a2a962SAkinobu Mita mask_to_set &= BITMAP_LAST_WORD_MASK(size);
374c1a2a962SAkinobu Mita *p |= mask_to_set;
375c1a2a962SAkinobu Mita }
376c1a2a962SAkinobu Mita }
377e5af323cSMatthew Wilcox EXPORT_SYMBOL(__bitmap_set);
378c1a2a962SAkinobu Mita
__bitmap_clear(unsigned long * map,unsigned int start,int len)379e5af323cSMatthew Wilcox void __bitmap_clear(unsigned long *map, unsigned int start, int len)
380c1a2a962SAkinobu Mita {
381c1a2a962SAkinobu Mita unsigned long *p = map + BIT_WORD(start);
382154f5e38SRasmus Villemoes const unsigned int size = start + len;
383c1a2a962SAkinobu Mita int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
384c1a2a962SAkinobu Mita unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
385c1a2a962SAkinobu Mita
386154f5e38SRasmus Villemoes while (len - bits_to_clear >= 0) {
387c1a2a962SAkinobu Mita *p &= ~mask_to_clear;
388154f5e38SRasmus Villemoes len -= bits_to_clear;
389c1a2a962SAkinobu Mita bits_to_clear = BITS_PER_LONG;
390c1a2a962SAkinobu Mita mask_to_clear = ~0UL;
391c1a2a962SAkinobu Mita p++;
392c1a2a962SAkinobu Mita }
393154f5e38SRasmus Villemoes if (len) {
394c1a2a962SAkinobu Mita mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
395c1a2a962SAkinobu Mita *p &= ~mask_to_clear;
396c1a2a962SAkinobu Mita }
397c1a2a962SAkinobu Mita }
398e5af323cSMatthew Wilcox EXPORT_SYMBOL(__bitmap_clear);
399c1a2a962SAkinobu Mita
4005e19b013SMichal Nazarewicz /**
4015e19b013SMichal Nazarewicz * bitmap_find_next_zero_area_off - find a contiguous aligned zero area
402c1a2a962SAkinobu Mita * @map: The address to base the search on
403c1a2a962SAkinobu Mita * @size: The bitmap size in bits
404c1a2a962SAkinobu Mita * @start: The bitnumber to start searching at
405c1a2a962SAkinobu Mita * @nr: The number of zeroed bits we're looking for
406c1a2a962SAkinobu Mita * @align_mask: Alignment mask for zero area
4075e19b013SMichal Nazarewicz * @align_offset: Alignment offset for zero area.
408c1a2a962SAkinobu Mita *
409c1a2a962SAkinobu Mita * The @align_mask should be one less than a power of 2; the effect is that
4105e19b013SMichal Nazarewicz * the bit offset of all zero areas this function finds plus @align_offset
4115e19b013SMichal Nazarewicz * is multiple of that power of 2.
412c1a2a962SAkinobu Mita */
bitmap_find_next_zero_area_off(unsigned long * map,unsigned long size,unsigned long start,unsigned int nr,unsigned long align_mask,unsigned long align_offset)4135e19b013SMichal Nazarewicz unsigned long bitmap_find_next_zero_area_off(unsigned long *map,
414c1a2a962SAkinobu Mita unsigned long size,
415c1a2a962SAkinobu Mita unsigned long start,
416c1a2a962SAkinobu Mita unsigned int nr,
4175e19b013SMichal Nazarewicz unsigned long align_mask,
4185e19b013SMichal Nazarewicz unsigned long align_offset)
419c1a2a962SAkinobu Mita {
420c1a2a962SAkinobu Mita unsigned long index, end, i;
421c1a2a962SAkinobu Mita again:
422c1a2a962SAkinobu Mita index = find_next_zero_bit(map, size, start);
423c1a2a962SAkinobu Mita
424c1a2a962SAkinobu Mita /* Align allocation */
4255e19b013SMichal Nazarewicz index = __ALIGN_MASK(index + align_offset, align_mask) - align_offset;
426c1a2a962SAkinobu Mita
427c1a2a962SAkinobu Mita end = index + nr;
428c1a2a962SAkinobu Mita if (end > size)
429c1a2a962SAkinobu Mita return end;
430c1a2a962SAkinobu Mita i = find_next_bit(map, end, index);
431c1a2a962SAkinobu Mita if (i < end) {
432c1a2a962SAkinobu Mita start = i + 1;
433c1a2a962SAkinobu Mita goto again;
434c1a2a962SAkinobu Mita }
435c1a2a962SAkinobu Mita return index;
436c1a2a962SAkinobu Mita }
4375e19b013SMichal Nazarewicz EXPORT_SYMBOL(bitmap_find_next_zero_area_off);
438c1a2a962SAkinobu Mita
43972fd4a35SRobert P. J. Day /**
4409a86e2baSBen Hutchings * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
441fb5eeeeeSPaul Jackson * @buf: pointer to a bitmap
442df1d80a9SRasmus Villemoes * @pos: a bit position in @buf (0 <= @pos < @nbits)
443df1d80a9SRasmus Villemoes * @nbits: number of valid bit positions in @buf
444fb5eeeeeSPaul Jackson *
445df1d80a9SRasmus Villemoes * Map the bit at position @pos in @buf (of length @nbits) to the
446fb5eeeeeSPaul Jackson * ordinal of which set bit it is. If it is not set or if @pos
44796b7f341SPaul Jackson * is not a valid bit position, map to -1.
448fb5eeeeeSPaul Jackson *
449fb5eeeeeSPaul Jackson * If for example, just bits 4 through 7 are set in @buf, then @pos
450fb5eeeeeSPaul Jackson * values 4 through 7 will get mapped to 0 through 3, respectively,
451a8551748SRasmus Villemoes * and other @pos values will get mapped to -1. When @pos value 7
452fb5eeeeeSPaul Jackson * gets mapped to (returns) @ord value 3 in this example, that means
453fb5eeeeeSPaul Jackson * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
454fb5eeeeeSPaul Jackson *
455fb5eeeeeSPaul Jackson * The bit positions 0 through @bits are valid positions in @buf.
456fb5eeeeeSPaul Jackson */
bitmap_pos_to_ord(const unsigned long * buf,unsigned int pos,unsigned int nbits)457df1d80a9SRasmus Villemoes static int bitmap_pos_to_ord(const unsigned long *buf, unsigned int pos, unsigned int nbits)
458fb5eeeeeSPaul Jackson {
459df1d80a9SRasmus Villemoes if (pos >= nbits || !test_bit(pos, buf))
46096b7f341SPaul Jackson return -1;
461fb5eeeeeSPaul Jackson
46270a1cb10SYury Norov return bitmap_weight(buf, pos);
463fb5eeeeeSPaul Jackson }
464fb5eeeeeSPaul Jackson
465fb5eeeeeSPaul Jackson /**
466fb5eeeeeSPaul Jackson * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
467fb5eeeeeSPaul Jackson * @dst: remapped result
46896b7f341SPaul Jackson * @src: subset to be remapped
469fb5eeeeeSPaul Jackson * @old: defines domain of map
470fb5eeeeeSPaul Jackson * @new: defines range of map
4719814ec13SRasmus Villemoes * @nbits: number of bits in each of these bitmaps
472fb5eeeeeSPaul Jackson *
473fb5eeeeeSPaul Jackson * Let @old and @new define a mapping of bit positions, such that
474fb5eeeeeSPaul Jackson * whatever position is held by the n-th set bit in @old is mapped
475fb5eeeeeSPaul Jackson * to the n-th set bit in @new. In the more general case, allowing
476fb5eeeeeSPaul Jackson * for the possibility that the weight 'w' of @new is less than the
477fb5eeeeeSPaul Jackson * weight of @old, map the position of the n-th set bit in @old to
478fb5eeeeeSPaul Jackson * the position of the m-th set bit in @new, where m == n % w.
479fb5eeeeeSPaul Jackson *
48096b7f341SPaul Jackson * If either of the @old and @new bitmaps are empty, or if @src and
48196b7f341SPaul Jackson * @dst point to the same location, then this routine copies @src
48296b7f341SPaul Jackson * to @dst.
483fb5eeeeeSPaul Jackson *
48496b7f341SPaul Jackson * The positions of unset bits in @old are mapped to themselves
4858ed13a76SJonathan Neuschäfer * (the identity map).
486fb5eeeeeSPaul Jackson *
487fb5eeeeeSPaul Jackson * Apply the above specified mapping to @src, placing the result in
488fb5eeeeeSPaul Jackson * @dst, clearing any bits previously set in @dst.
489fb5eeeeeSPaul Jackson *
490fb5eeeeeSPaul Jackson * For example, lets say that @old has bits 4 through 7 set, and
491fb5eeeeeSPaul Jackson * @new has bits 12 through 15 set. This defines the mapping of bit
492fb5eeeeeSPaul Jackson * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
49396b7f341SPaul Jackson * bit positions unchanged. So if say @src comes into this routine
49496b7f341SPaul Jackson * with bits 1, 5 and 7 set, then @dst should leave with bits 1,
49596b7f341SPaul Jackson * 13 and 15 set.
496fb5eeeeeSPaul Jackson */
bitmap_remap(unsigned long * dst,const unsigned long * src,const unsigned long * old,const unsigned long * new,unsigned int nbits)497fb5eeeeeSPaul Jackson void bitmap_remap(unsigned long *dst, const unsigned long *src,
498fb5eeeeeSPaul Jackson const unsigned long *old, const unsigned long *new,
4999814ec13SRasmus Villemoes unsigned int nbits)
500fb5eeeeeSPaul Jackson {
5019814ec13SRasmus Villemoes unsigned int oldbit, w;
502fb5eeeeeSPaul Jackson
503fb5eeeeeSPaul Jackson if (dst == src) /* following doesn't handle inplace remaps */
504fb5eeeeeSPaul Jackson return;
5059814ec13SRasmus Villemoes bitmap_zero(dst, nbits);
50696b7f341SPaul Jackson
5079814ec13SRasmus Villemoes w = bitmap_weight(new, nbits);
5089814ec13SRasmus Villemoes for_each_set_bit(oldbit, src, nbits) {
5099814ec13SRasmus Villemoes int n = bitmap_pos_to_ord(old, oldbit, nbits);
51008564fb7SAkinobu Mita
51196b7f341SPaul Jackson if (n < 0 || w == 0)
51296b7f341SPaul Jackson set_bit(oldbit, dst); /* identity map */
51396b7f341SPaul Jackson else
51497848c10SYury Norov set_bit(find_nth_bit(new, nbits, n % w), dst);
515fb5eeeeeSPaul Jackson }
516fb5eeeeeSPaul Jackson }
517cde3d0f8SAndy Shevchenko EXPORT_SYMBOL(bitmap_remap);
518fb5eeeeeSPaul Jackson
519fb5eeeeeSPaul Jackson /**
520fb5eeeeeSPaul Jackson * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
5216e1907ffSRandy Dunlap * @oldbit: bit position to be mapped
522fb5eeeeeSPaul Jackson * @old: defines domain of map
523fb5eeeeeSPaul Jackson * @new: defines range of map
524fb5eeeeeSPaul Jackson * @bits: number of bits in each of these bitmaps
525fb5eeeeeSPaul Jackson *
526fb5eeeeeSPaul Jackson * Let @old and @new define a mapping of bit positions, such that
527fb5eeeeeSPaul Jackson * whatever position is held by the n-th set bit in @old is mapped
528fb5eeeeeSPaul Jackson * to the n-th set bit in @new. In the more general case, allowing
529fb5eeeeeSPaul Jackson * for the possibility that the weight 'w' of @new is less than the
530fb5eeeeeSPaul Jackson * weight of @old, map the position of the n-th set bit in @old to
531fb5eeeeeSPaul Jackson * the position of the m-th set bit in @new, where m == n % w.
532fb5eeeeeSPaul Jackson *
53396b7f341SPaul Jackson * The positions of unset bits in @old are mapped to themselves
5348ed13a76SJonathan Neuschäfer * (the identity map).
535fb5eeeeeSPaul Jackson *
536fb5eeeeeSPaul Jackson * Apply the above specified mapping to bit position @oldbit, returning
537fb5eeeeeSPaul Jackson * the new bit position.
538fb5eeeeeSPaul Jackson *
539fb5eeeeeSPaul Jackson * For example, lets say that @old has bits 4 through 7 set, and
540fb5eeeeeSPaul Jackson * @new has bits 12 through 15 set. This defines the mapping of bit
541fb5eeeeeSPaul Jackson * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
54296b7f341SPaul Jackson * bit positions unchanged. So if say @oldbit is 5, then this routine
54396b7f341SPaul Jackson * returns 13.
544fb5eeeeeSPaul Jackson */
bitmap_bitremap(int oldbit,const unsigned long * old,const unsigned long * new,int bits)545fb5eeeeeSPaul Jackson int bitmap_bitremap(int oldbit, const unsigned long *old,
546fb5eeeeeSPaul Jackson const unsigned long *new, int bits)
547fb5eeeeeSPaul Jackson {
54896b7f341SPaul Jackson int w = bitmap_weight(new, bits);
54996b7f341SPaul Jackson int n = bitmap_pos_to_ord(old, oldbit, bits);
55096b7f341SPaul Jackson if (n < 0 || w == 0)
55196b7f341SPaul Jackson return oldbit;
55296b7f341SPaul Jackson else
55397848c10SYury Norov return find_nth_bit(new, bits, n % w);
554fb5eeeeeSPaul Jackson }
555cde3d0f8SAndy Shevchenko EXPORT_SYMBOL(bitmap_bitremap);
556fb5eeeeeSPaul Jackson
557cde3d0f8SAndy Shevchenko #ifdef CONFIG_NUMA
5587ea931c9SPaul Jackson /**
5597ea931c9SPaul Jackson * bitmap_onto - translate one bitmap relative to another
5607ea931c9SPaul Jackson * @dst: resulting translated bitmap
5617ea931c9SPaul Jackson * @orig: original untranslated bitmap
5627ea931c9SPaul Jackson * @relmap: bitmap relative to which translated
5637ea931c9SPaul Jackson * @bits: number of bits in each of these bitmaps
5647ea931c9SPaul Jackson *
5657ea931c9SPaul Jackson * Set the n-th bit of @dst iff there exists some m such that the
5667ea931c9SPaul Jackson * n-th bit of @relmap is set, the m-th bit of @orig is set, and
5677ea931c9SPaul Jackson * the n-th bit of @relmap is also the m-th _set_ bit of @relmap.
5687ea931c9SPaul Jackson * (If you understood the previous sentence the first time your
5697ea931c9SPaul Jackson * read it, you're overqualified for your current job.)
5707ea931c9SPaul Jackson *
5717ea931c9SPaul Jackson * In other words, @orig is mapped onto (surjectively) @dst,
572da3dae54SMasanari Iida * using the map { <n, m> | the n-th bit of @relmap is the
5737ea931c9SPaul Jackson * m-th set bit of @relmap }.
5747ea931c9SPaul Jackson *
5757ea931c9SPaul Jackson * Any set bits in @orig above bit number W, where W is the
5767ea931c9SPaul Jackson * weight of (number of set bits in) @relmap are mapped nowhere.
5777ea931c9SPaul Jackson * In particular, if for all bits m set in @orig, m >= W, then
5787ea931c9SPaul Jackson * @dst will end up empty. In situations where the possibility
5797ea931c9SPaul Jackson * of such an empty result is not desired, one way to avoid it is
5807ea931c9SPaul Jackson * to use the bitmap_fold() operator, below, to first fold the
5817ea931c9SPaul Jackson * @orig bitmap over itself so that all its set bits x are in the
5827ea931c9SPaul Jackson * range 0 <= x < W. The bitmap_fold() operator does this by
5837ea931c9SPaul Jackson * setting the bit (m % W) in @dst, for each bit (m) set in @orig.
5847ea931c9SPaul Jackson *
5857ea931c9SPaul Jackson * Example [1] for bitmap_onto():
5867ea931c9SPaul Jackson * Let's say @relmap has bits 30-39 set, and @orig has bits
5877ea931c9SPaul Jackson * 1, 3, 5, 7, 9 and 11 set. Then on return from this routine,
5887ea931c9SPaul Jackson * @dst will have bits 31, 33, 35, 37 and 39 set.
5897ea931c9SPaul Jackson *
5907ea931c9SPaul Jackson * When bit 0 is set in @orig, it means turn on the bit in
5917ea931c9SPaul Jackson * @dst corresponding to whatever is the first bit (if any)
5927ea931c9SPaul Jackson * that is turned on in @relmap. Since bit 0 was off in the
5937ea931c9SPaul Jackson * above example, we leave off that bit (bit 30) in @dst.
5947ea931c9SPaul Jackson *
5957ea931c9SPaul Jackson * When bit 1 is set in @orig (as in the above example), it
5967ea931c9SPaul Jackson * means turn on the bit in @dst corresponding to whatever
5977ea931c9SPaul Jackson * is the second bit that is turned on in @relmap. The second
5987ea931c9SPaul Jackson * bit in @relmap that was turned on in the above example was
5997ea931c9SPaul Jackson * bit 31, so we turned on bit 31 in @dst.
6007ea931c9SPaul Jackson *
6017ea931c9SPaul Jackson * Similarly, we turned on bits 33, 35, 37 and 39 in @dst,
6027ea931c9SPaul Jackson * because they were the 4th, 6th, 8th and 10th set bits
6037ea931c9SPaul Jackson * set in @relmap, and the 4th, 6th, 8th and 10th bits of
6047ea931c9SPaul Jackson * @orig (i.e. bits 3, 5, 7 and 9) were also set.
6057ea931c9SPaul Jackson *
6067ea931c9SPaul Jackson * When bit 11 is set in @orig, it means turn on the bit in
60725985edcSLucas De Marchi * @dst corresponding to whatever is the twelfth bit that is
6087ea931c9SPaul Jackson * turned on in @relmap. In the above example, there were
6097ea931c9SPaul Jackson * only ten bits turned on in @relmap (30..39), so that bit
6107ea931c9SPaul Jackson * 11 was set in @orig had no affect on @dst.
6117ea931c9SPaul Jackson *
6127ea931c9SPaul Jackson * Example [2] for bitmap_fold() + bitmap_onto():
61340bf19a8S[email protected] * Let's say @relmap has these ten bits set::
61440bf19a8S[email protected] *
6157ea931c9SPaul Jackson * 40 41 42 43 45 48 53 61 74 95
61640bf19a8S[email protected] *
6177ea931c9SPaul Jackson * (for the curious, that's 40 plus the first ten terms of the
6187ea931c9SPaul Jackson * Fibonacci sequence.)
6197ea931c9SPaul Jackson *
6207ea931c9SPaul Jackson * Further lets say we use the following code, invoking
6217ea931c9SPaul Jackson * bitmap_fold() then bitmap_onto, as suggested above to
62240bf19a8S[email protected] * avoid the possibility of an empty @dst result::
6237ea931c9SPaul Jackson *
6247ea931c9SPaul Jackson * unsigned long *tmp; // a temporary bitmap's bits
6257ea931c9SPaul Jackson *
6267ea931c9SPaul Jackson * bitmap_fold(tmp, orig, bitmap_weight(relmap, bits), bits);
6277ea931c9SPaul Jackson * bitmap_onto(dst, tmp, relmap, bits);
6287ea931c9SPaul Jackson *
6297ea931c9SPaul Jackson * Then this table shows what various values of @dst would be, for
6307ea931c9SPaul Jackson * various @orig's. I list the zero-based positions of each set bit.
6317ea931c9SPaul Jackson * The tmp column shows the intermediate result, as computed by
6327ea931c9SPaul Jackson * using bitmap_fold() to fold the @orig bitmap modulo ten
63340bf19a8S[email protected] * (the weight of @relmap):
6347ea931c9SPaul Jackson *
63540bf19a8S[email protected] * =============== ============== =================
6367ea931c9SPaul Jackson * @orig tmp @dst
6377ea931c9SPaul Jackson * 0 0 40
6387ea931c9SPaul Jackson * 1 1 41
6397ea931c9SPaul Jackson * 9 9 95
64040bf19a8S[email protected] * 10 0 40 [#f1]_
6417ea931c9SPaul Jackson * 1 3 5 7 1 3 5 7 41 43 48 61
6427ea931c9SPaul Jackson * 0 1 2 3 4 0 1 2 3 4 40 41 42 43 45
6437ea931c9SPaul Jackson * 0 9 18 27 0 9 8 7 40 61 74 95
6447ea931c9SPaul Jackson * 0 10 20 30 0 40
6457ea931c9SPaul Jackson * 0 11 22 33 0 1 2 3 40 41 42 43
6467ea931c9SPaul Jackson * 0 12 24 36 0 2 4 6 40 42 45 53
64740bf19a8S[email protected] * 78 102 211 1 2 8 41 42 74 [#f1]_
64840bf19a8S[email protected] * =============== ============== =================
6497ea931c9SPaul Jackson *
65040bf19a8S[email protected] * .. [#f1]
65140bf19a8S[email protected] *
65240bf19a8S[email protected] * For these marked lines, if we hadn't first done bitmap_fold()
6537ea931c9SPaul Jackson * into tmp, then the @dst result would have been empty.
6547ea931c9SPaul Jackson *
6557ea931c9SPaul Jackson * If either of @orig or @relmap is empty (no set bits), then @dst
6567ea931c9SPaul Jackson * will be returned empty.
6577ea931c9SPaul Jackson *
6587ea931c9SPaul Jackson * If (as explained above) the only set bits in @orig are in positions
6597ea931c9SPaul Jackson * m where m >= W, (where W is the weight of @relmap) then @dst will
6607ea931c9SPaul Jackson * once again be returned empty.
6617ea931c9SPaul Jackson *
6627ea931c9SPaul Jackson * All bits in @dst not set by the above rule are cleared.
6637ea931c9SPaul Jackson */
bitmap_onto(unsigned long * dst,const unsigned long * orig,const unsigned long * relmap,unsigned int bits)6647ea931c9SPaul Jackson void bitmap_onto(unsigned long *dst, const unsigned long *orig,
665eb569883SRasmus Villemoes const unsigned long *relmap, unsigned int bits)
6667ea931c9SPaul Jackson {
667eb569883SRasmus Villemoes unsigned int n, m; /* same meaning as in above comment */
6687ea931c9SPaul Jackson
6697ea931c9SPaul Jackson if (dst == orig) /* following doesn't handle inplace mappings */
6707ea931c9SPaul Jackson return;
6717ea931c9SPaul Jackson bitmap_zero(dst, bits);
6727ea931c9SPaul Jackson
6737ea931c9SPaul Jackson /*
6747ea931c9SPaul Jackson * The following code is a more efficient, but less
6757ea931c9SPaul Jackson * obvious, equivalent to the loop:
6767ea931c9SPaul Jackson * for (m = 0; m < bitmap_weight(relmap, bits); m++) {
67797848c10SYury Norov * n = find_nth_bit(orig, bits, m);
6787ea931c9SPaul Jackson * if (test_bit(m, orig))
6797ea931c9SPaul Jackson * set_bit(n, dst);
6807ea931c9SPaul Jackson * }
6817ea931c9SPaul Jackson */
6827ea931c9SPaul Jackson
6837ea931c9SPaul Jackson m = 0;
68408564fb7SAkinobu Mita for_each_set_bit(n, relmap, bits) {
6857ea931c9SPaul Jackson /* m == bitmap_pos_to_ord(relmap, n, bits) */
6867ea931c9SPaul Jackson if (test_bit(m, orig))
6877ea931c9SPaul Jackson set_bit(n, dst);
6887ea931c9SPaul Jackson m++;
6897ea931c9SPaul Jackson }
6907ea931c9SPaul Jackson }
6917ea931c9SPaul Jackson
6927ea931c9SPaul Jackson /**
6937ea931c9SPaul Jackson * bitmap_fold - fold larger bitmap into smaller, modulo specified size
6947ea931c9SPaul Jackson * @dst: resulting smaller bitmap
6957ea931c9SPaul Jackson * @orig: original larger bitmap
6967ea931c9SPaul Jackson * @sz: specified size
697b26ad583SRasmus Villemoes * @nbits: number of bits in each of these bitmaps
6987ea931c9SPaul Jackson *
6997ea931c9SPaul Jackson * For each bit oldbit in @orig, set bit oldbit mod @sz in @dst.
7007ea931c9SPaul Jackson * Clear all other bits in @dst. See further the comment and
7017ea931c9SPaul Jackson * Example [2] for bitmap_onto() for why and how to use this.
7027ea931c9SPaul Jackson */
bitmap_fold(unsigned long * dst,const unsigned long * orig,unsigned int sz,unsigned int nbits)7037ea931c9SPaul Jackson void bitmap_fold(unsigned long *dst, const unsigned long *orig,
704b26ad583SRasmus Villemoes unsigned int sz, unsigned int nbits)
7057ea931c9SPaul Jackson {
706b26ad583SRasmus Villemoes unsigned int oldbit;
7077ea931c9SPaul Jackson
7087ea931c9SPaul Jackson if (dst == orig) /* following doesn't handle inplace mappings */
7097ea931c9SPaul Jackson return;
710b26ad583SRasmus Villemoes bitmap_zero(dst, nbits);
7117ea931c9SPaul Jackson
712b26ad583SRasmus Villemoes for_each_set_bit(oldbit, orig, nbits)
7137ea931c9SPaul Jackson set_bit(oldbit % sz, dst);
7147ea931c9SPaul Jackson }
715cdc90a18SRasmus Villemoes #endif /* CONFIG_NUMA */
7167ea931c9SPaul Jackson
bitmap_alloc(unsigned int nbits,gfp_t flags)717c42b65e3SAndy Shevchenko unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags)
718c42b65e3SAndy Shevchenko {
719c42b65e3SAndy Shevchenko return kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long),
720c42b65e3SAndy Shevchenko flags);
721c42b65e3SAndy Shevchenko }
722c42b65e3SAndy Shevchenko EXPORT_SYMBOL(bitmap_alloc);
723c42b65e3SAndy Shevchenko
bitmap_zalloc(unsigned int nbits,gfp_t flags)724c42b65e3SAndy Shevchenko unsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags)
725c42b65e3SAndy Shevchenko {
726c42b65e3SAndy Shevchenko return bitmap_alloc(nbits, flags | __GFP_ZERO);
727c42b65e3SAndy Shevchenko }
728c42b65e3SAndy Shevchenko EXPORT_SYMBOL(bitmap_zalloc);
729c42b65e3SAndy Shevchenko
bitmap_alloc_node(unsigned int nbits,gfp_t flags,int node)7307529cc7fSTariq Toukan unsigned long *bitmap_alloc_node(unsigned int nbits, gfp_t flags, int node)
7317529cc7fSTariq Toukan {
7327529cc7fSTariq Toukan return kmalloc_array_node(BITS_TO_LONGS(nbits), sizeof(unsigned long),
7337529cc7fSTariq Toukan flags, node);
7347529cc7fSTariq Toukan }
7357529cc7fSTariq Toukan EXPORT_SYMBOL(bitmap_alloc_node);
7367529cc7fSTariq Toukan
bitmap_zalloc_node(unsigned int nbits,gfp_t flags,int node)7377529cc7fSTariq Toukan unsigned long *bitmap_zalloc_node(unsigned int nbits, gfp_t flags, int node)
7387529cc7fSTariq Toukan {
7397529cc7fSTariq Toukan return bitmap_alloc_node(nbits, flags | __GFP_ZERO, node);
7407529cc7fSTariq Toukan }
7417529cc7fSTariq Toukan EXPORT_SYMBOL(bitmap_zalloc_node);
7427529cc7fSTariq Toukan
bitmap_free(const unsigned long * bitmap)743c42b65e3SAndy Shevchenko void bitmap_free(const unsigned long *bitmap)
744c42b65e3SAndy Shevchenko {
745c42b65e3SAndy Shevchenko kfree(bitmap);
746c42b65e3SAndy Shevchenko }
747c42b65e3SAndy Shevchenko EXPORT_SYMBOL(bitmap_free);
748c42b65e3SAndy Shevchenko
devm_bitmap_free(void * data)749e829c2e4SBartosz Golaszewski static void devm_bitmap_free(void *data)
750e829c2e4SBartosz Golaszewski {
751e829c2e4SBartosz Golaszewski unsigned long *bitmap = data;
752e829c2e4SBartosz Golaszewski
753e829c2e4SBartosz Golaszewski bitmap_free(bitmap);
754e829c2e4SBartosz Golaszewski }
755e829c2e4SBartosz Golaszewski
devm_bitmap_alloc(struct device * dev,unsigned int nbits,gfp_t flags)756e829c2e4SBartosz Golaszewski unsigned long *devm_bitmap_alloc(struct device *dev,
757e829c2e4SBartosz Golaszewski unsigned int nbits, gfp_t flags)
758e829c2e4SBartosz Golaszewski {
759e829c2e4SBartosz Golaszewski unsigned long *bitmap;
760e829c2e4SBartosz Golaszewski int ret;
761e829c2e4SBartosz Golaszewski
762e829c2e4SBartosz Golaszewski bitmap = bitmap_alloc(nbits, flags);
763e829c2e4SBartosz Golaszewski if (!bitmap)
764e829c2e4SBartosz Golaszewski return NULL;
765e829c2e4SBartosz Golaszewski
766e829c2e4SBartosz Golaszewski ret = devm_add_action_or_reset(dev, devm_bitmap_free, bitmap);
767e829c2e4SBartosz Golaszewski if (ret)
768e829c2e4SBartosz Golaszewski return NULL;
769e829c2e4SBartosz Golaszewski
770e829c2e4SBartosz Golaszewski return bitmap;
771e829c2e4SBartosz Golaszewski }
772e829c2e4SBartosz Golaszewski EXPORT_SYMBOL_GPL(devm_bitmap_alloc);
773e829c2e4SBartosz Golaszewski
devm_bitmap_zalloc(struct device * dev,unsigned int nbits,gfp_t flags)774e829c2e4SBartosz Golaszewski unsigned long *devm_bitmap_zalloc(struct device *dev,
775e829c2e4SBartosz Golaszewski unsigned int nbits, gfp_t flags)
776e829c2e4SBartosz Golaszewski {
777e829c2e4SBartosz Golaszewski return devm_bitmap_alloc(dev, nbits, flags | __GFP_ZERO);
778e829c2e4SBartosz Golaszewski }
779e829c2e4SBartosz Golaszewski EXPORT_SYMBOL_GPL(devm_bitmap_zalloc);
780e829c2e4SBartosz Golaszewski
781c724f193SYury Norov #if BITS_PER_LONG == 64
782c724f193SYury Norov /**
783c724f193SYury Norov * bitmap_from_arr32 - copy the contents of u32 array of bits to bitmap
784c724f193SYury Norov * @bitmap: array of unsigned longs, the destination bitmap
785c724f193SYury Norov * @buf: array of u32 (in host byte order), the source bitmap
786c724f193SYury Norov * @nbits: number of bits in @bitmap
787c724f193SYury Norov */
bitmap_from_arr32(unsigned long * bitmap,const u32 * buf,unsigned int nbits)788ccf7a6d4SAndy Shevchenko void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf, unsigned int nbits)
789c724f193SYury Norov {
790c724f193SYury Norov unsigned int i, halfwords;
791c724f193SYury Norov
792c724f193SYury Norov halfwords = DIV_ROUND_UP(nbits, 32);
793c724f193SYury Norov for (i = 0; i < halfwords; i++) {
794c724f193SYury Norov bitmap[i/2] = (unsigned long) buf[i];
795c724f193SYury Norov if (++i < halfwords)
796c724f193SYury Norov bitmap[i/2] |= ((unsigned long) buf[i]) << 32;
797c724f193SYury Norov }
798c724f193SYury Norov
799c724f193SYury Norov /* Clear tail bits in last word beyond nbits. */
800c724f193SYury Norov if (nbits % BITS_PER_LONG)
801c724f193SYury Norov bitmap[(halfwords - 1) / 2] &= BITMAP_LAST_WORD_MASK(nbits);
802c724f193SYury Norov }
803c724f193SYury Norov EXPORT_SYMBOL(bitmap_from_arr32);
804c724f193SYury Norov
805c724f193SYury Norov /**
806c724f193SYury Norov * bitmap_to_arr32 - copy the contents of bitmap to a u32 array of bits
807c724f193SYury Norov * @buf: array of u32 (in host byte order), the dest bitmap
808c724f193SYury Norov * @bitmap: array of unsigned longs, the source bitmap
809c724f193SYury Norov * @nbits: number of bits in @bitmap
810c724f193SYury Norov */
bitmap_to_arr32(u32 * buf,const unsigned long * bitmap,unsigned int nbits)811c724f193SYury Norov void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, unsigned int nbits)
812c724f193SYury Norov {
813c724f193SYury Norov unsigned int i, halfwords;
814c724f193SYury Norov
815c724f193SYury Norov halfwords = DIV_ROUND_UP(nbits, 32);
816c724f193SYury Norov for (i = 0; i < halfwords; i++) {
817c724f193SYury Norov buf[i] = (u32) (bitmap[i/2] & UINT_MAX);
818c724f193SYury Norov if (++i < halfwords)
819c724f193SYury Norov buf[i] = (u32) (bitmap[i/2] >> 32);
820c724f193SYury Norov }
821c724f193SYury Norov
822c724f193SYury Norov /* Clear tail bits in last element of array beyond nbits. */
823c724f193SYury Norov if (nbits % BITS_PER_LONG)
824c724f193SYury Norov buf[halfwords - 1] &= (u32) (UINT_MAX >> ((-nbits) & 31));
825c724f193SYury Norov }
826c724f193SYury Norov EXPORT_SYMBOL(bitmap_to_arr32);
8270a97953fSYury Norov #endif
828c724f193SYury Norov
829c1d2ba10SYury Norov #if BITS_PER_LONG == 32
8300a97953fSYury Norov /**
8310a97953fSYury Norov * bitmap_from_arr64 - copy the contents of u64 array of bits to bitmap
8320a97953fSYury Norov * @bitmap: array of unsigned longs, the destination bitmap
8330a97953fSYury Norov * @buf: array of u64 (in host byte order), the source bitmap
8340a97953fSYury Norov * @nbits: number of bits in @bitmap
8350a97953fSYury Norov */
bitmap_from_arr64(unsigned long * bitmap,const u64 * buf,unsigned int nbits)8360a97953fSYury Norov void bitmap_from_arr64(unsigned long *bitmap, const u64 *buf, unsigned int nbits)
8370a97953fSYury Norov {
8380a97953fSYury Norov int n;
8390a97953fSYury Norov
8400a97953fSYury Norov for (n = nbits; n > 0; n -= 64) {
8410a97953fSYury Norov u64 val = *buf++;
8420a97953fSYury Norov
8430a97953fSYury Norov *bitmap++ = val;
8440a97953fSYury Norov if (n > 32)
8450a97953fSYury Norov *bitmap++ = val >> 32;
8460a97953fSYury Norov }
8470a97953fSYury Norov
8480a97953fSYury Norov /*
8490a97953fSYury Norov * Clear tail bits in the last word beyond nbits.
8500a97953fSYury Norov *
8510a97953fSYury Norov * Negative index is OK because here we point to the word next
8520a97953fSYury Norov * to the last word of the bitmap, except for nbits == 0, which
8530a97953fSYury Norov * is tested implicitly.
8540a97953fSYury Norov */
8550a97953fSYury Norov if (nbits % BITS_PER_LONG)
8560a97953fSYury Norov bitmap[-1] &= BITMAP_LAST_WORD_MASK(nbits);
8570a97953fSYury Norov }
8580a97953fSYury Norov EXPORT_SYMBOL(bitmap_from_arr64);
8590a97953fSYury Norov
8600a97953fSYury Norov /**
8610a97953fSYury Norov * bitmap_to_arr64 - copy the contents of bitmap to a u64 array of bits
8620a97953fSYury Norov * @buf: array of u64 (in host byte order), the dest bitmap
8630a97953fSYury Norov * @bitmap: array of unsigned longs, the source bitmap
8640a97953fSYury Norov * @nbits: number of bits in @bitmap
8650a97953fSYury Norov */
bitmap_to_arr64(u64 * buf,const unsigned long * bitmap,unsigned int nbits)8660a97953fSYury Norov void bitmap_to_arr64(u64 *buf, const unsigned long *bitmap, unsigned int nbits)
8670a97953fSYury Norov {
8680a97953fSYury Norov const unsigned long *end = bitmap + BITS_TO_LONGS(nbits);
8690a97953fSYury Norov
8700a97953fSYury Norov while (bitmap < end) {
8710a97953fSYury Norov *buf = *bitmap++;
8720a97953fSYury Norov if (bitmap < end)
8730a97953fSYury Norov *buf |= (u64)(*bitmap++) << 32;
8740a97953fSYury Norov buf++;
8750a97953fSYury Norov }
8760a97953fSYury Norov
8770a97953fSYury Norov /* Clear tail bits in the last element of array beyond nbits. */
8780a97953fSYury Norov if (nbits % 64)
879428bc098SAlexander Lobakin buf[-1] &= GENMASK_ULL((nbits - 1) % 64, 0);
8800a97953fSYury Norov }
8810a97953fSYury Norov EXPORT_SYMBOL(bitmap_to_arr64);
882c724f193SYury Norov #endif
883