hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/lib/find_bit.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* bit search implementation
23 *
34 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
....@@ -9,21 +10,17 @@
910 *
1011 * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease
1112 * size and improve performance, 2015.
12
- *
13
- * This program is free software; you can redistribute it and/or
14
- * modify it under the terms of the GNU General Public License
15
- * as published by the Free Software Foundation; either version
16
- * 2 of the License, or (at your option) any later version.
1713 */
1814
1915 #include <linux/bitops.h>
2016 #include <linux/bitmap.h>
2117 #include <linux/export.h>
2218 #include <linux/kernel.h>
19
+#include <linux/minmax.h>
2320
24
-#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \
25
- !defined(find_next_and_bit)
26
-
21
+#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \
22
+ !defined(find_next_bit_le) || !defined(find_next_zero_bit_le) || \
23
+ !defined(find_next_and_bit)
2724 /*
2825 * This is a common helper function for find_next_bit, find_next_zero_bit, and
2926 * find_next_and_bit. The differences are:
....@@ -31,11 +28,11 @@
3128 * searching it for one bits.
3229 * - The optional "addr2", which is anded with "addr1" if present.
3330 */
34
-static inline unsigned long _find_next_bit(const unsigned long *addr1,
31
+static unsigned long _find_next_bit(const unsigned long *addr1,
3532 const unsigned long *addr2, unsigned long nbits,
36
- unsigned long start, unsigned long invert)
33
+ unsigned long start, unsigned long invert, unsigned long le)
3734 {
38
- unsigned long tmp;
35
+ unsigned long tmp, mask;
3936
4037 if (unlikely(start >= nbits))
4138 return nbits;
....@@ -46,7 +43,12 @@
4643 tmp ^= invert;
4744
4845 /* Handle 1st word. */
49
- tmp &= BITMAP_FIRST_WORD_MASK(start);
46
+ mask = BITMAP_FIRST_WORD_MASK(start);
47
+ if (le)
48
+ mask = swab(mask);
49
+
50
+ tmp &= mask;
51
+
5052 start = round_down(start, BITS_PER_LONG);
5153
5254 while (!tmp) {
....@@ -60,6 +62,9 @@
6062 tmp ^= invert;
6163 }
6264
65
+ if (le)
66
+ tmp = swab(tmp);
67
+
6368 return min(start + __ffs(tmp), nbits);
6469 }
6570 #endif
....@@ -71,7 +76,7 @@
7176 unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
7277 unsigned long offset)
7378 {
74
- return _find_next_bit(addr, NULL, size, offset, 0UL);
79
+ return _find_next_bit(addr, NULL, size, offset, 0UL, 0);
7580 }
7681 EXPORT_SYMBOL(find_next_bit);
7782 #endif
....@@ -80,7 +85,7 @@
8085 unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
8186 unsigned long offset)
8287 {
83
- return _find_next_bit(addr, NULL, size, offset, ~0UL);
88
+ return _find_next_bit(addr, NULL, size, offset, ~0UL, 0);
8489 }
8590 EXPORT_SYMBOL(find_next_zero_bit);
8691 #endif
....@@ -90,7 +95,7 @@
9095 const unsigned long *addr2, unsigned long size,
9196 unsigned long offset)
9297 {
93
- return _find_next_bit(addr1, addr2, size, offset, 0UL);
98
+ return _find_next_bit(addr1, addr2, size, offset, 0UL, 0);
9499 }
95100 EXPORT_SYMBOL(find_next_and_bit);
96101 #endif
....@@ -153,45 +158,11 @@
153158
154159 #ifdef __BIG_ENDIAN
155160
156
-#if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le)
157
-static inline unsigned long _find_next_bit_le(const unsigned long *addr1,
158
- const unsigned long *addr2, unsigned long nbits,
159
- unsigned long start, unsigned long invert)
160
-{
161
- unsigned long tmp;
162
-
163
- if (unlikely(start >= nbits))
164
- return nbits;
165
-
166
- tmp = addr1[start / BITS_PER_LONG];
167
- if (addr2)
168
- tmp &= addr2[start / BITS_PER_LONG];
169
- tmp ^= invert;
170
-
171
- /* Handle 1st word. */
172
- tmp &= swab(BITMAP_FIRST_WORD_MASK(start));
173
- start = round_down(start, BITS_PER_LONG);
174
-
175
- while (!tmp) {
176
- start += BITS_PER_LONG;
177
- if (start >= nbits)
178
- return nbits;
179
-
180
- tmp = addr1[start / BITS_PER_LONG];
181
- if (addr2)
182
- tmp &= addr2[start / BITS_PER_LONG];
183
- tmp ^= invert;
184
- }
185
-
186
- return min(start + __ffs(swab(tmp)), nbits);
187
-}
188
-#endif
189
-
190161 #ifndef find_next_zero_bit_le
191162 unsigned long find_next_zero_bit_le(const void *addr, unsigned
192163 long size, unsigned long offset)
193164 {
194
- return _find_next_bit_le(addr, NULL, size, offset, ~0UL);
165
+ return _find_next_bit(addr, NULL, size, offset, ~0UL, 1);
195166 }
196167 EXPORT_SYMBOL(find_next_zero_bit_le);
197168 #endif
....@@ -200,9 +171,23 @@
200171 unsigned long find_next_bit_le(const void *addr, unsigned
201172 long size, unsigned long offset)
202173 {
203
- return _find_next_bit_le(addr, NULL, size, offset, 0UL);
174
+ return _find_next_bit(addr, NULL, size, offset, 0UL, 1);
204175 }
205176 EXPORT_SYMBOL(find_next_bit_le);
206177 #endif
207178
208179 #endif /* __BIG_ENDIAN */
180
+
181
+unsigned long find_next_clump8(unsigned long *clump, const unsigned long *addr,
182
+ unsigned long size, unsigned long offset)
183
+{
184
+ offset = find_next_bit(addr, size, offset);
185
+ if (offset == size)
186
+ return size;
187
+
188
+ offset = round_down(offset, 8);
189
+ *clump = bitmap_get_value8(addr, offset);
190
+
191
+ return offset;
192
+}
193
+EXPORT_SYMBOL(find_next_clump8);