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