1*d96e5996SHans Petter Selasky /*- 2*d96e5996SHans Petter Selasky * Copyright (c) 2020 Mellanox Technologies, Ltd. 3*d96e5996SHans Petter Selasky * All rights reserved. 4*d96e5996SHans Petter Selasky * 5*d96e5996SHans Petter Selasky * Redistribution and use in source and binary forms, with or without 6*d96e5996SHans Petter Selasky * modification, are permitted provided that the following conditions 7*d96e5996SHans Petter Selasky * are met: 8*d96e5996SHans Petter Selasky * 1. Redistributions of source code must retain the above copyright 9*d96e5996SHans Petter Selasky * notice unmodified, this list of conditions, and the following 10*d96e5996SHans Petter Selasky * disclaimer. 11*d96e5996SHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright 12*d96e5996SHans Petter Selasky * notice, this list of conditions and the following disclaimer in the 13*d96e5996SHans Petter Selasky * documentation and/or other materials provided with the distribution. 14*d96e5996SHans Petter Selasky * 15*d96e5996SHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16*d96e5996SHans Petter Selasky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17*d96e5996SHans Petter Selasky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18*d96e5996SHans Petter Selasky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19*d96e5996SHans Petter Selasky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20*d96e5996SHans Petter Selasky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21*d96e5996SHans Petter Selasky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22*d96e5996SHans Petter Selasky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23*d96e5996SHans Petter Selasky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24*d96e5996SHans Petter Selasky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25*d96e5996SHans Petter Selasky * 26*d96e5996SHans Petter Selasky * $FreeBSD$ 27*d96e5996SHans Petter Selasky */ 28*d96e5996SHans Petter Selasky #ifndef _LINUX_XARRAY_H_ 29*d96e5996SHans Petter Selasky #define _LINUX_XARRAY_H_ 30*d96e5996SHans Petter Selasky 31*d96e5996SHans Petter Selasky #include <linux/gfp.h> 32*d96e5996SHans Petter Selasky #include <linux/radix-tree.h> 33*d96e5996SHans Petter Selasky #include <linux/err.h> 34*d96e5996SHans Petter Selasky 35*d96e5996SHans Petter Selasky #include <sys/lock.h> 36*d96e5996SHans Petter Selasky #include <sys/mutex.h> 37*d96e5996SHans Petter Selasky 38*d96e5996SHans Petter Selasky #define XA_LIMIT(min, max) \ 39*d96e5996SHans Petter Selasky ({ CTASSERT((min) == 0); (uint32_t)(max); }) 40*d96e5996SHans Petter Selasky 41*d96e5996SHans Petter Selasky #define XA_FLAGS_ALLOC (1U << 0) 42*d96e5996SHans Petter Selasky #define XA_FLAGS_LOCK_IRQ (1U << 1) 43*d96e5996SHans Petter Selasky 44*d96e5996SHans Petter Selasky #define XA_ERROR(x) \ 45*d96e5996SHans Petter Selasky ERR_PTR(x) 46*d96e5996SHans Petter Selasky 47*d96e5996SHans Petter Selasky #define xa_limit_32b XA_LIMIT(0, 0xFFFFFFFF) 48*d96e5996SHans Petter Selasky 49*d96e5996SHans Petter Selasky #define XA_ASSERT_LOCKED(xa) mtx_assert(&(xa)->mtx, MA_OWNED) 50*d96e5996SHans Petter Selasky #define xa_lock(xa) mtx_lock(&(xa)->mtx) 51*d96e5996SHans Petter Selasky #define xa_unlock(xa) mtx_unlock(&(xa)->mtx) 52*d96e5996SHans Petter Selasky 53*d96e5996SHans Petter Selasky struct xarray { 54*d96e5996SHans Petter Selasky struct radix_tree_root root; 55*d96e5996SHans Petter Selasky struct mtx mtx; /* internal mutex */ 56*d96e5996SHans Petter Selasky }; 57*d96e5996SHans Petter Selasky 58*d96e5996SHans Petter Selasky /* 59*d96e5996SHans Petter Selasky * Extensible arrays API implemented as a wrapper 60*d96e5996SHans Petter Selasky * around the radix tree implementation. 61*d96e5996SHans Petter Selasky */ 62*d96e5996SHans Petter Selasky void *xa_erase(struct xarray *, uint32_t); 63*d96e5996SHans Petter Selasky void *xa_load(struct xarray *, uint32_t); 64*d96e5996SHans Petter Selasky int xa_alloc(struct xarray *, uint32_t *, void *, uint32_t, gfp_t); 65*d96e5996SHans Petter Selasky int xa_alloc_cyclic(struct xarray *, uint32_t *, void *, uint32_t, uint32_t *, gfp_t); 66*d96e5996SHans Petter Selasky int xa_insert(struct xarray *, uint32_t, void *, gfp_t); 67*d96e5996SHans Petter Selasky void *xa_store(struct xarray *, uint32_t, void *, gfp_t); 68*d96e5996SHans Petter Selasky void xa_init_flags(struct xarray *, uint32_t); 69*d96e5996SHans Petter Selasky bool xa_empty(struct xarray *); 70*d96e5996SHans Petter Selasky void xa_destroy(struct xarray *); 71*d96e5996SHans Petter Selasky void *xa_next(struct xarray *, unsigned long *, bool); 72*d96e5996SHans Petter Selasky 73*d96e5996SHans Petter Selasky #define xa_for_each(xa, index, entry) \ 74*d96e5996SHans Petter Selasky for ((entry) = NULL, (index) = 0; \ 75*d96e5996SHans Petter Selasky ((entry) = xa_next(xa, &index, (entry) != NULL)) != NULL; ) 76*d96e5996SHans Petter Selasky 77*d96e5996SHans Petter Selasky /* 78*d96e5996SHans Petter Selasky * Unlocked version of functions above. 79*d96e5996SHans Petter Selasky */ 80*d96e5996SHans Petter Selasky void *__xa_erase(struct xarray *, uint32_t); 81*d96e5996SHans Petter Selasky int __xa_alloc(struct xarray *, uint32_t *, void *, uint32_t, gfp_t); 82*d96e5996SHans Petter Selasky int __xa_alloc_cyclic(struct xarray *, uint32_t *, void *, uint32_t, uint32_t *, gfp_t); 83*d96e5996SHans Petter Selasky int __xa_insert(struct xarray *, uint32_t, void *, gfp_t); 84*d96e5996SHans Petter Selasky void *__xa_store(struct xarray *, uint32_t, void *, gfp_t); 85*d96e5996SHans Petter Selasky bool __xa_empty(struct xarray *); 86*d96e5996SHans Petter Selasky void *__xa_next(struct xarray *, unsigned long *, bool); 87*d96e5996SHans Petter Selasky 88*d96e5996SHans Petter Selasky static inline int 89*d96e5996SHans Petter Selasky xa_err(void *ptr) 90*d96e5996SHans Petter Selasky { 91*d96e5996SHans Petter Selasky return (PTR_ERR_OR_ZERO(ptr)); 92*d96e5996SHans Petter Selasky } 93*d96e5996SHans Petter Selasky 94*d96e5996SHans Petter Selasky #endif /* _LINUX_XARRAY_H_ */ 95