void *), void *data)
{
struct axmap_level *al;
+ uint64_t index = bit_nr;
int i;
for (i = 0; i < axmap->nr_levels; i++) {
- unsigned long index = ulog64(bit_nr, i);
unsigned long offset = index >> UNIT_SHIFT;
unsigned int bit = index & BLOCKS_PER_UNIT_MASK;
if (func(al, offset, bit, data))
return true;
+
+ if (index)
+ index >>= UNIT_SHIFT;
}
return false;
}
static bool axmap_handler_topdown(struct axmap *axmap, uint64_t bit_nr,
- bool (*func)(struct axmap_level *, unsigned long, unsigned int, void *),
- void *data)
+ bool (*func)(struct axmap_level *, unsigned long, unsigned int, void *))
{
- struct axmap_level *al;
int i;
for (i = axmap->nr_levels - 1; i >= 0; i--) {
unsigned long offset = index >> UNIT_SHIFT;
unsigned int bit = index & BLOCKS_PER_UNIT_MASK;
- al = &axmap->levels[i];
-
- if (func(al, offset, bit, data))
+ if (func(&axmap->levels[i], offset, bit, NULL))
return true;
}
* Mask off any potential overlap, only sets contig regions
*/
overlap = al->map[offset] & mask;
- if (overlap == mask)
+ if (overlap == mask) {
+done:
+ data->set_bits = 0;
return true;
+ }
if (overlap) {
const int __bit = ffz(~overlap);
nr_bits = __bit - bit;
if (!nr_bits)
- return true;
+ goto done;
mask = bit_masks[nr_bits] << bit;
}
unsigned int max_bits, this_set;
max_bits = BLOCKS_PER_UNIT - (bit_nr & BLOCKS_PER_UNIT_MASK);
- if (max_bits < nr_bits)
+ if (nr_bits > max_bits)
data.nr_bits = max_bits;
this_set = data.nr_bits;
bool axmap_isset(struct axmap *axmap, uint64_t bit_nr)
{
if (bit_nr <= axmap->nr_bits)
- return axmap_handler_topdown(axmap, bit_nr, axmap_isset_fn, NULL);
+ return axmap_handler_topdown(axmap, bit_nr, axmap_isset_fn);
return false;
}
for (i = level; i >= 0; i--) {
struct axmap_level *al = &axmap->levels[i];
- /*
- * Clear 'ret', this is a bug condition.
- */
- if (index >= al->map_size) {
- ret = -1ULL;
- break;
- }
+ if (index >= al->map_size)
+ goto err;
for (j = index; j < al->map_size; j++) {
if (al->map[j] == -1UL)
if (ret < axmap->nr_bits)
return ret;
+err:
return (uint64_t) -1ULL;
}