@@ -2152,25 +2152,7 @@ int ida_pre_get(struct ida *ida, gfp_t gfp)
*/
__must_check bool xb_preload(gfp_t gfp)
{
- if (!this_cpu_read(ida_bitmap)) {
- struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp);
-
- if (!bitmap)
- return false;
- /*
- * The per-CPU variable is updated with preemption enabled.
- * If the calling task is unlucky to be scheduled to another
- * CPU which has no ida_bitmap allocation, it will be detected
- * when setting a bit (i.e. __xb_set_bit()).
- */
- bitmap = this_cpu_cmpxchg(ida_bitmap, NULL, bitmap);
- kfree(bitmap);
- }
-
- if (__radix_tree_preload(gfp, XB_PRELOAD_SIZE) < 0)
- return false;
-
- return true;
+ return __radix_tree_preload(gfp, XB_PRELOAD_SIZE) == 0;
}
EXPORT_SYMBOL(xb_preload);
@@ -18,7 +18,7 @@
* This function is used to set a bit in the xbitmap. If the bitmap that @bit
* resides in is not there, the per-cpu ida_bitmap will be taken.
*
- * Returns: 0 on success. %-EAGAIN indicates that @bit was not set.
+ * Returns: 0 on success. Negative value on failure.
*/
int xb_set_bit(struct xb *xb, unsigned long bit)
{
@@ -28,46 +28,19 @@ int xb_set_bit(struct xb *xb, unsigned long bit)
struct radix_tree_node *node;
void **slot;
struct ida_bitmap *bitmap;
- unsigned long ebit;
bit %= IDA_BITMAP_BITS;
- ebit = bit + 2;
err = __radix_tree_create(root, index, 0, &node, &slot);
if (err)
return err;
bitmap = rcu_dereference_raw(*slot);
- if (radix_tree_exception(bitmap)) {
- unsigned long tmp = (unsigned long)bitmap;
-
- if (ebit < BITS_PER_LONG) {
- tmp |= 1UL << ebit;
- rcu_assign_pointer(*slot, (void *)tmp);
- return 0;
- }
- bitmap = this_cpu_xchg(ida_bitmap, NULL);
- if (!bitmap) {
- __radix_tree_delete(root, node, slot);
- return -EAGAIN;
- }
- memset(bitmap, 0, sizeof(*bitmap));
- bitmap->bitmap[0] = tmp >> RADIX_TREE_EXCEPTIONAL_SHIFT;
- rcu_assign_pointer(*slot, bitmap);
- }
-
if (!bitmap) {
- if (ebit < BITS_PER_LONG) {
- bitmap = (void *)((1UL << ebit) |
- RADIX_TREE_EXCEPTIONAL_ENTRY);
- __radix_tree_replace(root, node, slot, bitmap, NULL);
- return 0;
- }
- bitmap = this_cpu_xchg(ida_bitmap, NULL);
+ bitmap = kzalloc(sizeof(*bitmap), GFP_NOWAIT | __GFP_NOWARN);
if (!bitmap) {
__radix_tree_delete(root, node, slot);
- return -EAGAIN;
+ return -ENOMEM;
}
- memset(bitmap, 0, sizeof(*bitmap));
__radix_tree_replace(root, node, slot, bitmap, NULL);
}
@@ -82,7 +55,7 @@ int xb_set_bit(struct xb *xb, unsigned long bit)
* @bit: index of the bit to set
*
* A wrapper of the xb_preload() and xb_set_bit().
- * Returns: 0 on success; -EAGAIN or -ENOMEM on error.
+ * Returns: 0 on success; -ENOMEM on error.
*/
int xb_preload_and_set_bit(struct xb *xb, unsigned long bit, gfp_t gfp)
{
@@ -113,25 +86,10 @@ void xb_clear_bit(struct xb *xb, unsigned long bit)
struct radix_tree_node *node;
void **slot;
struct ida_bitmap *bitmap;
- unsigned long ebit;
bit %= IDA_BITMAP_BITS;
- ebit = bit + 2;
bitmap = __radix_tree_lookup(root, index, &node, &slot);
- if (radix_tree_exception(bitmap)) {
- unsigned long tmp = (unsigned long)bitmap;
-
- if (ebit >= BITS_PER_LONG)
- return;
- tmp &= ~(1UL << ebit);
- if (tmp == RADIX_TREE_EXCEPTIONAL_ENTRY)
- __radix_tree_delete(root, node, slot);
- else
- rcu_assign_pointer(*slot, (void *)tmp);
- return;
- }
-
if (!bitmap)
return;
@@ -164,20 +122,7 @@ void xb_clear_bit_range(struct xb *xb, unsigned long start, unsigned long end)
unsigned long bit = start % IDA_BITMAP_BITS;
bitmap = __radix_tree_lookup(root, index, &node, &slot);
- if (radix_tree_exception(bitmap)) {
- unsigned long ebit = bit + 2;
- unsigned long tmp = (unsigned long)bitmap;
-
- nbits = min(end - start + 1, BITS_PER_LONG - ebit);
-
- if (ebit >= BITS_PER_LONG)
- continue;
- bitmap_clear(&tmp, ebit, nbits);
- if (tmp == RADIX_TREE_EXCEPTIONAL_ENTRY)
- __radix_tree_delete(root, node, slot);
- else
- rcu_assign_pointer(*slot, (void *)tmp);
- } else if (bitmap) {
+ if (bitmap) {
nbits = min(end - start + 1, IDA_BITMAP_BITS - bit);
if (nbits != IDA_BITMAP_BITS)
@@ -212,12 +157,6 @@ bool xb_test_bit(const struct xb *xb, unsigned long bit)
if (!bitmap)
return false;
- if (radix_tree_exception(bitmap)) {
- bit += RADIX_TREE_EXCEPTIONAL_SHIFT;
- if (bit >= BITS_PER_LONG)
- return false;
- return (unsigned long)bitmap & (1UL << bit);
- }
return test_bit(bit, bitmap->bitmap);
}
EXPORT_SYMBOL(xb_test_bit);
@@ -236,20 +175,7 @@ static unsigned long xb_find_next_bit(struct xb *xb, unsigned long start,
unsigned long bit = start % IDA_BITMAP_BITS;
bmap = __radix_tree_lookup(root, index, &node, &slot);
- if (radix_tree_exception(bmap)) {
- unsigned long tmp = (unsigned long)bmap;
- unsigned long ebit = bit + 2;
-
- if (ebit >= BITS_PER_LONG)
- continue;
- if (set)
- ret = find_next_bit(&tmp, BITS_PER_LONG, ebit);
- else
- ret = find_next_zero_bit(&tmp, BITS_PER_LONG,
- ebit);
- if (ret < BITS_PER_LONG)
- return ret - 2 + IDA_BITMAP_BITS * index;
- } else if (bmap) {
+ if (bmap) {
if (set)
ret = find_next_bit(bmap->bitmap,
IDA_BITMAP_BITS, bit);
@@ -258,7 +184,7 @@ static unsigned long xb_find_next_bit(struct xb *xb, unsigned long start,
IDA_BITMAP_BITS, bit);
if (ret < IDA_BITMAP_BITS)
return ret + index * IDA_BITMAP_BITS;
- } else if (!bmap && !set) {
+ } else if (!set) {
return start;
}
}