diff --git a/sys/compat/linuxkpi/common/include/linux/xarray.h b/sys/compat/linuxkpi/common/include/linux/xarray.h --- a/sys/compat/linuxkpi/common/include/linux/xarray.h +++ b/sys/compat/linuxkpi/common/include/linux/xarray.h @@ -40,6 +40,7 @@ #define XA_FLAGS_ALLOC (1U << 0) #define XA_FLAGS_LOCK_IRQ (1U << 1) +#define XA_FLAGS_ALLOC1 (1U << 2) #define XA_ERROR(x) \ ERR_PTR(x) @@ -53,6 +54,7 @@ struct xarray { struct radix_tree_root root; struct mtx mtx; /* internal mutex */ + uint32_t flags; /* see XA_FLAGS_XXX */ }; /* diff --git a/sys/compat/linuxkpi/common/src/linux_xarray.c b/sys/compat/linuxkpi/common/src/linux_xarray.c --- a/sys/compat/linuxkpi/common/src/linux_xarray.c +++ b/sys/compat/linuxkpi/common/src/linux_xarray.c @@ -102,13 +102,13 @@ XA_ASSERT_LOCKED(xa); - /* mask cannot be zero */ - MPASS(mask != 0); + /* mask should allow to allocate at least one item */ + MPASS(mask > (xa->flags & XA_FLAGS_ALLOC1) != 0 ? 1 : 0); /* mask can be any power of two value minus one */ MPASS((mask & (mask + 1)) == 0); - *pindex = 0; + *pindex = (xa->flags & XA_FLAGS_ALLOC1) != 0 ? 1 : 0; retry: retval = radix_tree_insert(&xa->root, *pindex, ptr); @@ -159,13 +159,13 @@ XA_ASSERT_LOCKED(xa); - /* mask cannot be zero */ - MPASS(mask != 0); + /* mask should allow to allocate at least one item */ + MPASS(mask > (xa->flags & XA_FLAGS_ALLOC1) != 0 ? 1 : 0); /* mask can be any power of two value minus one */ MPASS((mask & (mask + 1)) == 0); - *pnext_index = 0; + *pnext_index = (xa->flags & XA_FLAGS_ALLOC1) != 0 ? 1 : 0; retry: retval = radix_tree_insert(&xa->root, *pnext_index, ptr); @@ -177,6 +177,8 @@ } (*pnext_index)++; (*pnext_index) &= mask; + if (*pnext_index == 0 && (xa->flags & XA_FLAGS_ALLOC1) != 0) + (*pnext_index)++; goto retry; case -ENOMEM: if (likely(gfp & M_WAITOK)) { @@ -302,6 +304,7 @@ mtx_init(&xa->mtx, "lkpi-xarray", NULL, MTX_DEF | MTX_RECURSE); xa->root.gfp_mask = GFP_NOWAIT; + xa->flags = flags; } /*