git: 8dc3f129c4c7 - stable/13 - LinuxKPI: Add support for XA_FLAGS_ALLOC1 xarray flag

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Sat, 22 Jan 2022 19:36:23 UTC
The branch stable/13 has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=8dc3f129c4c7bf980bf744d7fa0aa2cb79c7234e

commit 8dc3f129c4c7bf980bf744d7fa0aa2cb79c7234e
Author:     Vladimir Kondratyev <wulf@FreeBSD.org>
AuthorDate: 2021-11-24 00:05:40 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2022-01-22 19:34:36 +0000

    LinuxKPI: Add support for XA_FLAGS_ALLOC1 xarray flag
    
    XA_FLAGS_ALLOC1 causes allocation of xarray entries starting at 1
    
    Required by drm-kmod 5.7
    
    MFC after:      1 week
    Reviewed by:    hselasky, manu
    Differential Revision:  https://reviews.freebsd.org/D33293
    
    (cherry picked from commit e705066cd87559831096f9638603f35d2fea635f)
---
 sys/compat/linuxkpi/common/include/linux/xarray.h |  2 ++
 sys/compat/linuxkpi/common/src/linux_xarray.c     | 15 +++++++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/xarray.h b/sys/compat/linuxkpi/common/include/linux/xarray.h
index 7427f6e4f9f9..3d9041bf108d 100644
--- 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
index 52be490c100e..c26a2af450e8 100644
--- a/sys/compat/linuxkpi/common/src/linux_xarray.c
+++ b/sys/compat/linuxkpi/common/src/linux_xarray.c
@@ -102,13 +102,13 @@ __xa_alloc(struct xarray *xa, uint32_t *pindex, void *ptr, uint32_t mask, gfp_t
 
 	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_alloc_cyclic(struct xarray *xa, uint32_t *pindex, void *ptr, uint32_t mask,
 
 	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 @@ retry:
 		}
 		(*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 @@ xa_init_flags(struct xarray *xa, uint32_t flags)
 
 	mtx_init(&xa->mtx, "lkpi-xarray", NULL, MTX_DEF | MTX_RECURSE);
 	xa->root.gfp_mask = GFP_NOWAIT;
+	xa->flags = flags;
 }
 
 /*