* Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set
  * in xa_init_flags().
  *
+ * Note that callers interested in whether wrapping has occurred should
+ * use __xa_alloc_cyclic() instead.
+ *
  * Context: Any context.  Takes and releases the xa_lock.  May sleep if
  * the @gfp flags permit.
- * Return: 0 if the allocation succeeded without wrapping.  1 if the
- * allocation succeeded after wrapping, -ENOMEM if memory could not be
+ * Return: 0 if the allocation succeeded, -ENOMEM if memory could not be
  * allocated or -EBUSY if there are no free entries in @limit.
  */
 static inline int xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry,
        err = __xa_alloc_cyclic(xa, id, entry, limit, next, gfp);
        xa_unlock(xa);
 
-       return err;
+       return err < 0 ? err : 0;
 }
 
 /**
  * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set
  * in xa_init_flags().
  *
+ * Note that callers interested in whether wrapping has occurred should
+ * use __xa_alloc_cyclic() instead.
+ *
  * Context: Any context.  Takes and releases the xa_lock while
  * disabling softirqs.  May sleep if the @gfp flags permit.
- * Return: 0 if the allocation succeeded without wrapping.  1 if the
- * allocation succeeded after wrapping, -ENOMEM if memory could not be
+ * Return: 0 if the allocation succeeded, -ENOMEM if memory could not be
  * allocated or -EBUSY if there are no free entries in @limit.
  */
 static inline int xa_alloc_cyclic_bh(struct xarray *xa, u32 *id, void *entry,
        err = __xa_alloc_cyclic(xa, id, entry, limit, next, gfp);
        xa_unlock_bh(xa);
 
-       return err;
+       return err < 0 ? err : 0;
 }
 
 /**
  * Must only be operated on an xarray initialized with flag XA_FLAGS_ALLOC set
  * in xa_init_flags().
  *
+ * Note that callers interested in whether wrapping has occurred should
+ * use __xa_alloc_cyclic() instead.
+ *
  * Context: Process context.  Takes and releases the xa_lock while
  * disabling interrupts.  May sleep if the @gfp flags permit.
- * Return: 0 if the allocation succeeded without wrapping.  1 if the
- * allocation succeeded after wrapping, -ENOMEM if memory could not be
+ * Return: 0 if the allocation succeeded, -ENOMEM if memory could not be
  * allocated or -EBUSY if there are no free entries in @limit.
  */
 static inline int xa_alloc_cyclic_irq(struct xarray *xa, u32 *id, void *entry,
        err = __xa_alloc_cyclic(xa, id, entry, limit, next, gfp);
        xa_unlock_irq(xa);
 
-       return err;
+       return err < 0 ? err : 0;
 }
 
 /**
 
        unsigned int i, id;
        unsigned long index;
        void *entry;
+       int ret;
 
        XA_BUG_ON(xa, xa_alloc_cyclic(xa, &id, xa_mk_index(1), limit,
                                &next, GFP_KERNEL) != 0);
                else
                        entry = xa_mk_index(i - 0x3fff);
                XA_BUG_ON(xa, xa_alloc_cyclic(xa, &id, entry, limit,
-                                       &next, GFP_KERNEL) != (id == 1));
+                                       &next, GFP_KERNEL) != 0);
                XA_BUG_ON(xa, xa_mk_index(id) != entry);
        }
 
                                xa_limit_32b, &next, GFP_KERNEL) != 0);
        XA_BUG_ON(xa, id != UINT_MAX);
        XA_BUG_ON(xa, xa_alloc_cyclic(xa, &id, xa_mk_index(base),
-                               xa_limit_32b, &next, GFP_KERNEL) != 1);
+                               xa_limit_32b, &next, GFP_KERNEL) != 0);
        XA_BUG_ON(xa, id != base);
        XA_BUG_ON(xa, xa_alloc_cyclic(xa, &id, xa_mk_index(base + 1),
                                xa_limit_32b, &next, GFP_KERNEL) != 0);
 
        xa_for_each(xa, index, entry)
                xa_erase_index(xa, index);
+       XA_BUG_ON(xa, !xa_empty(xa));
 
+       /* check wrap-around return of __xa_alloc_cyclic() */
+       next = UINT_MAX;
+       XA_BUG_ON(xa, xa_alloc_cyclic(xa, &id, xa_mk_index(UINT_MAX),
+                                     xa_limit_32b, &next, GFP_KERNEL) != 0);
+       xa_lock(xa);
+       ret = __xa_alloc_cyclic(xa, &id, xa_mk_index(base), xa_limit_32b,
+                               &next, GFP_KERNEL);
+       xa_unlock(xa);
+       XA_BUG_ON(xa, ret != 1);
+       xa_for_each(xa, index, entry)
+               xa_erase_index(xa, index);
        XA_BUG_ON(xa, !xa_empty(xa));
 }