31 #include <linux/slab.h>
32 #include <linux/export.h>
33 #include <linux/bitmap.h>
38 static int set_bits_ll(
unsigned long *
addr,
unsigned long mask_to_set)
40 unsigned long val, nval;
45 if (val & mask_to_set)
48 }
while ((nval =
cmpxchg(addr, val, val | mask_to_set)) != val);
53 static int clear_bits_ll(
unsigned long *addr,
unsigned long mask_to_clear)
55 unsigned long val, nval;
60 if ((val & mask_to_clear) != mask_to_clear)
63 }
while ((nval =
cmpxchg(addr, val, val & ~mask_to_clear)) != val);
79 static int bitmap_set_ll(
unsigned long *
map,
int start,
int nr)
82 const int size = start +
nr;
86 while (nr - bits_to_set >= 0) {
87 if (set_bits_ll(p, mask_to_set))
96 if (set_bits_ll(p, mask_to_set))
114 static int bitmap_clear_ll(
unsigned long *map,
int start,
int nr)
116 unsigned long *p = map +
BIT_WORD(start);
117 const int size = start +
nr;
121 while (nr - bits_to_clear >= 0) {
122 if (clear_bits_ll(p, mask_to_clear))
126 mask_to_clear = ~0
UL;
131 if (clear_bits_ll(p, mask_to_clear))
153 INIT_LIST_HEAD(&pool->
chunks);
176 size_t size,
int nid)
181 BITS_TO_LONGS(nbits) *
sizeof(
long);
192 spin_lock(&pool->
lock);
194 spin_unlock(&pool->
lock);
267 unsigned long addr = 0;
269 int nbits,
start_bit = 0, end_bit, remain;
271 #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
286 start_bit = pool->
algo(chunk->
bits, end_bit, start_bit, nbits,
288 if (start_bit >= end_bit)
290 remain = bitmap_set_ll(chunk->
bits, start_bit, nbits);
292 remain = bitmap_clear_ll(chunk->
bits, start_bit,
299 size = nbits <<
order;
324 #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
333 start_bit = (addr - chunk->
start_addr) >> order;
334 remain = bitmap_clear_ll(chunk->
bits, start_bit, nbits);
336 size = nbits <<
order;
363 list_for_each_entry_rcu(chunk, &(pool)->chunks,
next_chunk)
364 func(pool, chunk, data);
441 unsigned long start,
unsigned int nr,
void *
data)
460 unsigned long start,
unsigned int nr,
void *
data)
463 unsigned long len = size + 1;
468 while (index < size) {
470 if ((next_bit - index) < len) {
471 len = next_bit -
index;
477 next_bit + 1, nr, 0);