hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/include/linux/bitmap.h
....@@ -4,10 +4,12 @@
44
55 #ifndef __ASSEMBLY__
66
7
-#include <linux/types.h>
87 #include <linux/bitops.h>
9
-#include <linux/string.h>
108 #include <linux/kernel.h>
9
+#include <linux/string.h>
10
+#include <linux/types.h>
11
+
12
+struct device;
1113
1214 /*
1315 * bitmaps provide bit arrays that consume one or more unsigned
....@@ -28,8 +30,8 @@
2830 * The available bitmap operations and their rough meaning in the
2931 * case that the bitmap is a single unsigned long are thus:
3032 *
31
- * Note that nbits should be always a compile time evaluable constant.
32
- * Otherwise many inlines will generate horrible code.
33
+ * The generated code is more efficient when nbits is known at
34
+ * compile-time and at most BITS_PER_LONG.
3335 *
3436 * ::
3537 *
....@@ -50,9 +52,17 @@
5052 * bitmap_set(dst, pos, nbits) Set specified bit area
5153 * bitmap_clear(dst, pos, nbits) Clear specified bit area
5254 * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
53
- * bitmap_find_next_zero_area_off(buf, len, pos, n, mask) as above
55
+ * bitmap_find_next_zero_area_off(buf, len, pos, n, mask, mask_off) as above
56
+ * bitmap_next_clear_region(map, &start, &end, nbits) Find next clear region
57
+ * bitmap_next_set_region(map, &start, &end, nbits) Find next set region
58
+ * bitmap_for_each_clear_region(map, rs, re, start, end)
59
+ * Iterate over all clear regions
60
+ * bitmap_for_each_set_region(map, rs, re, start, end)
61
+ * Iterate over all set regions
5462 * bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n
5563 * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n
64
+ * bitmap_cut(dst, src, first, n, nbits) Cut n bits from first, copy rest
65
+ * bitmap_replace(dst, old, new, mask, nbits) *dst = (*old & ~(*mask)) | (*new & *mask)
5666 * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src)
5767 * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit)
5868 * bitmap_onto(dst, orig, relmap, nbits) *dst = orig relative to relmap
....@@ -66,6 +76,8 @@
6676 * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region
6777 * bitmap_from_arr32(dst, buf, nbits) Copy nbits from u32[] buf to dst
6878 * bitmap_to_arr32(buf, src, nbits) Copy nbits from buf to u32[] dst
79
+ * bitmap_get_value8(map, start) Get 8bit value from map at start
80
+ * bitmap_set_value8(map, value, start) Set 8bit value to map at start
6981 *
7082 * Note, bitmap_zero() and bitmap_fill() operate over the region of
7183 * unsigned longs, that is, bits behind bitmap till the unsigned long
....@@ -112,6 +124,12 @@
112124 extern unsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags);
113125 extern void bitmap_free(const unsigned long *bitmap);
114126
127
+/* Managed variants of the above. */
128
+unsigned long *devm_bitmap_alloc(struct device *dev,
129
+ unsigned int nbits, gfp_t flags);
130
+unsigned long *devm_bitmap_zalloc(struct device *dev,
131
+ unsigned int nbits, gfp_t flags);
132
+
115133 /*
116134 * lib/bitmap.c provides these functions:
117135 */
....@@ -120,12 +138,19 @@
120138 extern int __bitmap_full(const unsigned long *bitmap, unsigned int nbits);
121139 extern int __bitmap_equal(const unsigned long *bitmap1,
122140 const unsigned long *bitmap2, unsigned int nbits);
141
+extern bool __pure __bitmap_or_equal(const unsigned long *src1,
142
+ const unsigned long *src2,
143
+ const unsigned long *src3,
144
+ unsigned int nbits);
123145 extern void __bitmap_complement(unsigned long *dst, const unsigned long *src,
124146 unsigned int nbits);
125147 extern void __bitmap_shift_right(unsigned long *dst, const unsigned long *src,
126148 unsigned int shift, unsigned int nbits);
127149 extern void __bitmap_shift_left(unsigned long *dst, const unsigned long *src,
128150 unsigned int shift, unsigned int nbits);
151
+extern void bitmap_cut(unsigned long *dst, const unsigned long *src,
152
+ unsigned int first, unsigned int cut,
153
+ unsigned int nbits);
129154 extern int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
130155 const unsigned long *bitmap2, unsigned int nbits);
131156 extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
....@@ -134,6 +159,9 @@
134159 const unsigned long *bitmap2, unsigned int nbits);
135160 extern int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
136161 const unsigned long *bitmap2, unsigned int nbits);
162
+extern void __bitmap_replace(unsigned long *dst,
163
+ const unsigned long *old, const unsigned long *new,
164
+ const unsigned long *mask, unsigned int nbits);
137165 extern int __bitmap_intersects(const unsigned long *bitmap1,
138166 const unsigned long *bitmap2, unsigned int nbits);
139167 extern int __bitmap_subset(const unsigned long *bitmap1,
....@@ -172,7 +200,7 @@
172200 align_mask, 0);
173201 }
174202
175
-extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
203
+extern int bitmap_parse(const char *buf, unsigned int buflen,
176204 unsigned long *dst, int nbits);
177205 extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
178206 unsigned long *dst, int nbits);
....@@ -214,33 +242,21 @@
214242
215243 static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
216244 {
217
- if (small_const_nbits(nbits))
218
- *dst = 0UL;
219
- else {
220
- unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
221
- memset(dst, 0, len);
222
- }
245
+ unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
246
+ memset(dst, 0, len);
223247 }
224248
225249 static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
226250 {
227
- if (small_const_nbits(nbits))
228
- *dst = ~0UL;
229
- else {
230
- unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
231
- memset(dst, 0xff, len);
232
- }
251
+ unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
252
+ memset(dst, 0xff, len);
233253 }
234254
235255 static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
236256 unsigned int nbits)
237257 {
238
- if (small_const_nbits(nbits))
239
- *dst = *src;
240
- else {
241
- unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
242
- memcpy(dst, src, len);
243
- }
258
+ unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
259
+ memcpy(dst, src, len);
244260 }
245261
246262 /*
....@@ -333,6 +349,26 @@
333349 return __bitmap_equal(src1, src2, nbits);
334350 }
335351
352
+/**
353
+ * bitmap_or_equal - Check whether the or of two bitmaps is equal to a third
354
+ * @src1: Pointer to bitmap 1
355
+ * @src2: Pointer to bitmap 2 will be or'ed with bitmap 1
356
+ * @src3: Pointer to bitmap 3. Compare to the result of *@src1 | *@src2
357
+ * @nbits: number of bits in each of these bitmaps
358
+ *
359
+ * Returns: True if (*@src1 | *@src2) == *@src3, false otherwise
360
+ */
361
+static inline bool bitmap_or_equal(const unsigned long *src1,
362
+ const unsigned long *src2,
363
+ const unsigned long *src3,
364
+ unsigned int nbits)
365
+{
366
+ if (!small_const_nbits(nbits))
367
+ return __bitmap_or_equal(src1, src2, src3, nbits);
368
+
369
+ return !(((*src1 | *src2) ^ *src3) & BITMAP_LAST_WORD_MASK(nbits));
370
+}
371
+
336372 static inline int bitmap_intersects(const unsigned long *src1,
337373 const unsigned long *src2, unsigned int nbits)
338374 {
....@@ -420,11 +456,52 @@
420456 __bitmap_shift_left(dst, src, shift, nbits);
421457 }
422458
423
-static inline int bitmap_parse(const char *buf, unsigned int buflen,
424
- unsigned long *maskp, int nmaskbits)
459
+static inline void bitmap_replace(unsigned long *dst,
460
+ const unsigned long *old,
461
+ const unsigned long *new,
462
+ const unsigned long *mask,
463
+ unsigned int nbits)
425464 {
426
- return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits);
465
+ if (small_const_nbits(nbits))
466
+ *dst = (*old & ~(*mask)) | (*new & *mask);
467
+ else
468
+ __bitmap_replace(dst, old, new, mask, nbits);
427469 }
470
+
471
+static inline void bitmap_next_clear_region(unsigned long *bitmap,
472
+ unsigned int *rs, unsigned int *re,
473
+ unsigned int end)
474
+{
475
+ *rs = find_next_zero_bit(bitmap, end, *rs);
476
+ *re = find_next_bit(bitmap, end, *rs + 1);
477
+}
478
+
479
+static inline void bitmap_next_set_region(unsigned long *bitmap,
480
+ unsigned int *rs, unsigned int *re,
481
+ unsigned int end)
482
+{
483
+ *rs = find_next_bit(bitmap, end, *rs);
484
+ *re = find_next_zero_bit(bitmap, end, *rs + 1);
485
+}
486
+
487
+/*
488
+ * Bitmap region iterators. Iterates over the bitmap between [@start, @end).
489
+ * @rs and @re should be integer variables and will be set to start and end
490
+ * index of the current clear or set region.
491
+ */
492
+#define bitmap_for_each_clear_region(bitmap, rs, re, start, end) \
493
+ for ((rs) = (start), \
494
+ bitmap_next_clear_region((bitmap), &(rs), &(re), (end)); \
495
+ (rs) < (re); \
496
+ (rs) = (re) + 1, \
497
+ bitmap_next_clear_region((bitmap), &(rs), &(re), (end)))
498
+
499
+#define bitmap_for_each_set_region(bitmap, rs, re, start, end) \
500
+ for ((rs) = (start), \
501
+ bitmap_next_set_region((bitmap), &(rs), &(re), (end)); \
502
+ (rs) < (re); \
503
+ (rs) = (re) + 1, \
504
+ bitmap_next_set_region((bitmap), &(rs), &(re), (end)))
428505
429506 /**
430507 * BITMAP_FROM_U64() - Represent u64 value in the format suitable for bitmap.
....@@ -477,6 +554,39 @@
477554 dst[1] = mask >> 32;
478555 }
479556
557
+/**
558
+ * bitmap_get_value8 - get an 8-bit value within a memory region
559
+ * @map: address to the bitmap memory region
560
+ * @start: bit offset of the 8-bit value; must be a multiple of 8
561
+ *
562
+ * Returns the 8-bit value located at the @start bit offset within the @src
563
+ * memory region.
564
+ */
565
+static inline unsigned long bitmap_get_value8(const unsigned long *map,
566
+ unsigned long start)
567
+{
568
+ const size_t index = BIT_WORD(start);
569
+ const unsigned long offset = start % BITS_PER_LONG;
570
+
571
+ return (map[index] >> offset) & 0xFF;
572
+}
573
+
574
+/**
575
+ * bitmap_set_value8 - set an 8-bit value within a memory region
576
+ * @map: address to the bitmap memory region
577
+ * @value: the 8-bit value; values wider than 8 bits may clobber bitmap
578
+ * @start: bit offset of the 8-bit value; must be a multiple of 8
579
+ */
580
+static inline void bitmap_set_value8(unsigned long *map, unsigned long value,
581
+ unsigned long start)
582
+{
583
+ const size_t index = BIT_WORD(start);
584
+ const unsigned long offset = start % BITS_PER_LONG;
585
+
586
+ map[index] &= ~(0xFFUL << offset);
587
+ map[index] |= value << offset;
588
+}
589
+
480590 #endif /* __ASSEMBLY__ */
481591
482592 #endif /* __LINUX_BITMAP_H */