1ba20ba2eSKent Overstreet #ifndef _LINUX_GENERIC_RADIX_TREE_H 2ba20ba2eSKent Overstreet #define _LINUX_GENERIC_RADIX_TREE_H 3ba20ba2eSKent Overstreet 4ba20ba2eSKent Overstreet /** 5590ba22bSJonathan Corbet * DOC: Generic radix trees/sparse arrays 6ba20ba2eSKent Overstreet * 7ba20ba2eSKent Overstreet * Very simple and minimalistic, supporting arbitrary size entries up to 83a319a24SKent Overstreet * GENRADIX_NODE_SIZE. 9ba20ba2eSKent Overstreet * 10ba20ba2eSKent Overstreet * A genradix is defined with the type it will store, like so: 11ba20ba2eSKent Overstreet * 12ba20ba2eSKent Overstreet * static GENRADIX(struct foo) foo_genradix; 13ba20ba2eSKent Overstreet * 14ba20ba2eSKent Overstreet * The main operations are: 15ba20ba2eSKent Overstreet * 16ba20ba2eSKent Overstreet * - genradix_init(radix) - initialize an empty genradix 17ba20ba2eSKent Overstreet * 18ba20ba2eSKent Overstreet * - genradix_free(radix) - free all memory owned by the genradix and 19ba20ba2eSKent Overstreet * reinitialize it 20ba20ba2eSKent Overstreet * 21ba20ba2eSKent Overstreet * - genradix_ptr(radix, idx) - gets a pointer to the entry at idx, returning 22ba20ba2eSKent Overstreet * NULL if that entry does not exist 23ba20ba2eSKent Overstreet * 24ba20ba2eSKent Overstreet * - genradix_ptr_alloc(radix, idx, gfp) - gets a pointer to an entry, 25ba20ba2eSKent Overstreet * allocating it if necessary 26ba20ba2eSKent Overstreet * 27ba20ba2eSKent Overstreet * - genradix_for_each(radix, iter, p) - iterate over each entry in a genradix 28ba20ba2eSKent Overstreet * 29ba20ba2eSKent Overstreet * The radix tree allocates one page of entries at a time, so entries may exist 30ba20ba2eSKent Overstreet * that were never explicitly allocated - they will be initialized to all 31ba20ba2eSKent Overstreet * zeroes. 32ba20ba2eSKent Overstreet * 33ba20ba2eSKent Overstreet * Internally, a genradix is just a radix tree of pages, and indexing works in 34ba20ba2eSKent Overstreet * terms of byte offsets. The wrappers in this header file use sizeof on the 35ba20ba2eSKent Overstreet * type the radix contains to calculate a byte offset from the index - see 36ba20ba2eSKent Overstreet * __idx_to_offset. 37ba20ba2eSKent Overstreet */ 38ba20ba2eSKent Overstreet 39ba20ba2eSKent Overstreet #include <asm/page.h> 40ba20ba2eSKent Overstreet #include <linux/bug.h> 419492261fSKent Overstreet #include <linux/limits.h> 42ba20ba2eSKent Overstreet #include <linux/log2.h> 43b4b87651SAndy Shevchenko #include <linux/math.h> 44b4b87651SAndy Shevchenko #include <linux/types.h> 45ba20ba2eSKent Overstreet 46ba20ba2eSKent Overstreet struct genradix_root; 47ba20ba2eSKent Overstreet 483a319a24SKent Overstreet #define GENRADIX_NODE_SHIFT 9 493a319a24SKent Overstreet #define GENRADIX_NODE_SIZE (1U << GENRADIX_NODE_SHIFT) 503a319a24SKent Overstreet 51*f6594633SKent Overstreet #define GENRADIX_ARY (GENRADIX_NODE_SIZE / sizeof(struct genradix_node *)) 52*f6594633SKent Overstreet #define GENRADIX_ARY_SHIFT ilog2(GENRADIX_ARY) 53*f6594633SKent Overstreet 54*f6594633SKent Overstreet /* depth that's needed for a genradix that can address up to ULONG_MAX: */ 55*f6594633SKent Overstreet #define GENRADIX_MAX_DEPTH \ 56*f6594633SKent Overstreet DIV_ROUND_UP(BITS_PER_LONG - GENRADIX_NODE_SHIFT, GENRADIX_ARY_SHIFT) 57*f6594633SKent Overstreet 58*f6594633SKent Overstreet #define GENRADIX_DEPTH_MASK \ 59*f6594633SKent Overstreet ((unsigned long) (roundup_pow_of_two(GENRADIX_MAX_DEPTH + 1) - 1)) 60*f6594633SKent Overstreet 61*f6594633SKent Overstreet static inline int genradix_depth_shift(unsigned depth) 62*f6594633SKent Overstreet { 63*f6594633SKent Overstreet return GENRADIX_NODE_SHIFT + GENRADIX_ARY_SHIFT * depth; 64*f6594633SKent Overstreet } 65*f6594633SKent Overstreet 66*f6594633SKent Overstreet /* 67*f6594633SKent Overstreet * Returns size (of data, in bytes) that a tree of a given depth holds: 68*f6594633SKent Overstreet */ 69*f6594633SKent Overstreet static inline size_t genradix_depth_size(unsigned depth) 70*f6594633SKent Overstreet { 71*f6594633SKent Overstreet return 1UL << genradix_depth_shift(depth); 72*f6594633SKent Overstreet } 73*f6594633SKent Overstreet 74*f6594633SKent Overstreet static inline unsigned genradix_root_to_depth(struct genradix_root *r) 75*f6594633SKent Overstreet { 76*f6594633SKent Overstreet return (unsigned long) r & GENRADIX_DEPTH_MASK; 77*f6594633SKent Overstreet } 78*f6594633SKent Overstreet 79*f6594633SKent Overstreet static inline struct genradix_node *genradix_root_to_node(struct genradix_root *r) 80*f6594633SKent Overstreet { 81*f6594633SKent Overstreet return (void *) ((unsigned long) r & ~GENRADIX_DEPTH_MASK); 82*f6594633SKent Overstreet } 83*f6594633SKent Overstreet 84*f6594633SKent Overstreet struct genradix_node { 85*f6594633SKent Overstreet union { 86*f6594633SKent Overstreet /* Interior node: */ 87*f6594633SKent Overstreet struct genradix_node *children[GENRADIX_ARY]; 88*f6594633SKent Overstreet 89*f6594633SKent Overstreet /* Leaf: */ 90*f6594633SKent Overstreet u8 data[GENRADIX_NODE_SIZE]; 91*f6594633SKent Overstreet }; 92*f6594633SKent Overstreet }; 93*f6594633SKent Overstreet 94ba20ba2eSKent Overstreet struct __genradix { 950a650e47SLuc Van Oostenryck struct genradix_root *root; 96ba20ba2eSKent Overstreet }; 97ba20ba2eSKent Overstreet 98ba20ba2eSKent Overstreet /* 993a319a24SKent Overstreet * NOTE: currently, sizeof(_type) must not be larger than GENRADIX_NODE_SIZE: 100ba20ba2eSKent Overstreet */ 101ba20ba2eSKent Overstreet 102ba20ba2eSKent Overstreet #define __GENRADIX_INITIALIZER \ 103ba20ba2eSKent Overstreet { \ 104ba20ba2eSKent Overstreet .tree = { \ 105ba20ba2eSKent Overstreet .root = NULL, \ 106ba20ba2eSKent Overstreet } \ 107ba20ba2eSKent Overstreet } 108ba20ba2eSKent Overstreet 109ba20ba2eSKent Overstreet /* 110ba20ba2eSKent Overstreet * We use a 0 size array to stash the type we're storing without taking any 111ba20ba2eSKent Overstreet * space at runtime - then the various accessor macros can use typeof() to get 112ba20ba2eSKent Overstreet * to it for casts/sizeof - we also force the alignment so that storing a type 113ba20ba2eSKent Overstreet * with a ridiculous alignment doesn't blow up the alignment or size of the 114ba20ba2eSKent Overstreet * genradix. 115ba20ba2eSKent Overstreet */ 116ba20ba2eSKent Overstreet 117ba20ba2eSKent Overstreet #define GENRADIX(_type) \ 118ba20ba2eSKent Overstreet struct { \ 119ba20ba2eSKent Overstreet struct __genradix tree; \ 120ba20ba2eSKent Overstreet _type type[0] __aligned(1); \ 121ba20ba2eSKent Overstreet } 122ba20ba2eSKent Overstreet 123ba20ba2eSKent Overstreet #define DEFINE_GENRADIX(_name, _type) \ 124ba20ba2eSKent Overstreet GENRADIX(_type) _name = __GENRADIX_INITIALIZER 125ba20ba2eSKent Overstreet 126ba20ba2eSKent Overstreet /** 127ba20ba2eSKent Overstreet * genradix_init - initialize a genradix 128ba20ba2eSKent Overstreet * @_radix: genradix to initialize 129ba20ba2eSKent Overstreet * 130ba20ba2eSKent Overstreet * Does not fail 131ba20ba2eSKent Overstreet */ 132ba20ba2eSKent Overstreet #define genradix_init(_radix) \ 133ba20ba2eSKent Overstreet do { \ 134ba20ba2eSKent Overstreet *(_radix) = (typeof(*_radix)) __GENRADIX_INITIALIZER; \ 135ba20ba2eSKent Overstreet } while (0) 136ba20ba2eSKent Overstreet 137ba20ba2eSKent Overstreet void __genradix_free(struct __genradix *); 138ba20ba2eSKent Overstreet 139ba20ba2eSKent Overstreet /** 140ba20ba2eSKent Overstreet * genradix_free: free all memory owned by a genradix 141ba20ba2eSKent Overstreet * @_radix: the genradix to free 142ba20ba2eSKent Overstreet * 143ba20ba2eSKent Overstreet * After freeing, @_radix will be reinitialized and empty 144ba20ba2eSKent Overstreet */ 145ba20ba2eSKent Overstreet #define genradix_free(_radix) __genradix_free(&(_radix)->tree) 146ba20ba2eSKent Overstreet 147ba20ba2eSKent Overstreet static inline size_t __idx_to_offset(size_t idx, size_t obj_size) 148ba20ba2eSKent Overstreet { 149ba20ba2eSKent Overstreet if (__builtin_constant_p(obj_size)) 1503a319a24SKent Overstreet BUILD_BUG_ON(obj_size > GENRADIX_NODE_SIZE); 151ba20ba2eSKent Overstreet else 1523a319a24SKent Overstreet BUG_ON(obj_size > GENRADIX_NODE_SIZE); 153ba20ba2eSKent Overstreet 154ba20ba2eSKent Overstreet if (!is_power_of_2(obj_size)) { 1553a319a24SKent Overstreet size_t objs_per_page = GENRADIX_NODE_SIZE / obj_size; 156ba20ba2eSKent Overstreet 1573a319a24SKent Overstreet return (idx / objs_per_page) * GENRADIX_NODE_SIZE + 158ba20ba2eSKent Overstreet (idx % objs_per_page) * obj_size; 159ba20ba2eSKent Overstreet } else { 160ba20ba2eSKent Overstreet return idx * obj_size; 161ba20ba2eSKent Overstreet } 162ba20ba2eSKent Overstreet } 163ba20ba2eSKent Overstreet 164ba20ba2eSKent Overstreet #define __genradix_cast(_radix) (typeof((_radix)->type[0]) *) 165ba20ba2eSKent Overstreet #define __genradix_obj_size(_radix) sizeof((_radix)->type[0]) 16673badee4SKent Overstreet #define __genradix_objs_per_page(_radix) \ 1673a319a24SKent Overstreet (GENRADIX_NODE_SIZE / sizeof((_radix)->type[0])) 16873badee4SKent Overstreet #define __genradix_page_remainder(_radix) \ 1693a319a24SKent Overstreet (GENRADIX_NODE_SIZE % sizeof((_radix)->type[0])) 17073badee4SKent Overstreet 171ba20ba2eSKent Overstreet #define __genradix_idx_to_offset(_radix, _idx) \ 172ba20ba2eSKent Overstreet __idx_to_offset(_idx, __genradix_obj_size(_radix)) 173ba20ba2eSKent Overstreet 174*f6594633SKent Overstreet static inline void *__genradix_ptr_inlined(struct __genradix *radix, size_t offset) 175*f6594633SKent Overstreet { 176*f6594633SKent Overstreet struct genradix_root *r = READ_ONCE(radix->root); 177*f6594633SKent Overstreet struct genradix_node *n = genradix_root_to_node(r); 178*f6594633SKent Overstreet unsigned level = genradix_root_to_depth(r); 179*f6594633SKent Overstreet unsigned shift = genradix_depth_shift(level); 180*f6594633SKent Overstreet 181*f6594633SKent Overstreet if (unlikely(ilog2(offset) >= genradix_depth_shift(level))) 182*f6594633SKent Overstreet return NULL; 183*f6594633SKent Overstreet 184*f6594633SKent Overstreet while (n && shift > GENRADIX_NODE_SHIFT) { 185*f6594633SKent Overstreet shift -= GENRADIX_ARY_SHIFT; 186*f6594633SKent Overstreet n = n->children[offset >> shift]; 187*f6594633SKent Overstreet offset &= (1UL << shift) - 1; 188*f6594633SKent Overstreet } 189*f6594633SKent Overstreet 190*f6594633SKent Overstreet return n ? &n->data[offset] : NULL; 191*f6594633SKent Overstreet } 192*f6594633SKent Overstreet 193*f6594633SKent Overstreet #define genradix_ptr_inlined(_radix, _idx) \ 194*f6594633SKent Overstreet (__genradix_cast(_radix) \ 195*f6594633SKent Overstreet __genradix_ptr_inlined(&(_radix)->tree, \ 196*f6594633SKent Overstreet __genradix_idx_to_offset(_radix, _idx))) 197*f6594633SKent Overstreet 198ba20ba2eSKent Overstreet void *__genradix_ptr(struct __genradix *, size_t); 199ba20ba2eSKent Overstreet 200ba20ba2eSKent Overstreet /** 201ba20ba2eSKent Overstreet * genradix_ptr - get a pointer to a genradix entry 202ba20ba2eSKent Overstreet * @_radix: genradix to access 203ba20ba2eSKent Overstreet * @_idx: index to fetch 204ba20ba2eSKent Overstreet * 205ba20ba2eSKent Overstreet * Returns a pointer to entry at @_idx, or NULL if that entry does not exist. 206ba20ba2eSKent Overstreet */ 207ba20ba2eSKent Overstreet #define genradix_ptr(_radix, _idx) \ 208ba20ba2eSKent Overstreet (__genradix_cast(_radix) \ 209ba20ba2eSKent Overstreet __genradix_ptr(&(_radix)->tree, \ 210ba20ba2eSKent Overstreet __genradix_idx_to_offset(_radix, _idx))) 211ba20ba2eSKent Overstreet 212ba20ba2eSKent Overstreet void *__genradix_ptr_alloc(struct __genradix *, size_t, gfp_t); 213ba20ba2eSKent Overstreet 214*f6594633SKent Overstreet #define genradix_ptr_alloc_inlined(_radix, _idx, _gfp) \ 215*f6594633SKent Overstreet (__genradix_cast(_radix) \ 216*f6594633SKent Overstreet (__genradix_ptr_inlined(&(_radix)->tree, \ 217*f6594633SKent Overstreet __genradix_idx_to_offset(_radix, _idx)) ?: \ 218*f6594633SKent Overstreet __genradix_ptr_alloc(&(_radix)->tree, \ 219*f6594633SKent Overstreet __genradix_idx_to_offset(_radix, _idx), \ 220*f6594633SKent Overstreet _gfp))) 221*f6594633SKent Overstreet 222ba20ba2eSKent Overstreet /** 223ba20ba2eSKent Overstreet * genradix_ptr_alloc - get a pointer to a genradix entry, allocating it 224ba20ba2eSKent Overstreet * if necessary 225ba20ba2eSKent Overstreet * @_radix: genradix to access 226ba20ba2eSKent Overstreet * @_idx: index to fetch 227ba20ba2eSKent Overstreet * @_gfp: gfp mask 228ba20ba2eSKent Overstreet * 229ba20ba2eSKent Overstreet * Returns a pointer to entry at @_idx, or NULL on allocation failure 230ba20ba2eSKent Overstreet */ 231ba20ba2eSKent Overstreet #define genradix_ptr_alloc(_radix, _idx, _gfp) \ 232ba20ba2eSKent Overstreet (__genradix_cast(_radix) \ 233ba20ba2eSKent Overstreet __genradix_ptr_alloc(&(_radix)->tree, \ 234ba20ba2eSKent Overstreet __genradix_idx_to_offset(_radix, _idx), \ 235ba20ba2eSKent Overstreet _gfp)) 236ba20ba2eSKent Overstreet 237ba20ba2eSKent Overstreet struct genradix_iter { 238ba20ba2eSKent Overstreet size_t offset; 239ba20ba2eSKent Overstreet size_t pos; 240ba20ba2eSKent Overstreet }; 241ba20ba2eSKent Overstreet 242ba20ba2eSKent Overstreet /** 243ba20ba2eSKent Overstreet * genradix_iter_init - initialize a genradix_iter 244ba20ba2eSKent Overstreet * @_radix: genradix that will be iterated over 245ba20ba2eSKent Overstreet * @_idx: index to start iterating from 246ba20ba2eSKent Overstreet */ 247ba20ba2eSKent Overstreet #define genradix_iter_init(_radix, _idx) \ 248ba20ba2eSKent Overstreet ((struct genradix_iter) { \ 249ba20ba2eSKent Overstreet .pos = (_idx), \ 250ba20ba2eSKent Overstreet .offset = __genradix_idx_to_offset((_radix), (_idx)),\ 251ba20ba2eSKent Overstreet }) 252ba20ba2eSKent Overstreet 253ba20ba2eSKent Overstreet void *__genradix_iter_peek(struct genradix_iter *, struct __genradix *, size_t); 254ba20ba2eSKent Overstreet 255ba20ba2eSKent Overstreet /** 256ba20ba2eSKent Overstreet * genradix_iter_peek - get first entry at or above iterator's current 257ba20ba2eSKent Overstreet * position 258ba20ba2eSKent Overstreet * @_iter: a genradix_iter 259ba20ba2eSKent Overstreet * @_radix: genradix being iterated over 260ba20ba2eSKent Overstreet * 261ba20ba2eSKent Overstreet * If no more entries exist at or above @_iter's current position, returns NULL 262ba20ba2eSKent Overstreet */ 263ba20ba2eSKent Overstreet #define genradix_iter_peek(_iter, _radix) \ 264ba20ba2eSKent Overstreet (__genradix_cast(_radix) \ 265ba20ba2eSKent Overstreet __genradix_iter_peek(_iter, &(_radix)->tree, \ 26673badee4SKent Overstreet __genradix_objs_per_page(_radix))) 26773badee4SKent Overstreet 26873badee4SKent Overstreet void *__genradix_iter_peek_prev(struct genradix_iter *, struct __genradix *, 26973badee4SKent Overstreet size_t, size_t); 27073badee4SKent Overstreet 27173badee4SKent Overstreet /** 27273badee4SKent Overstreet * genradix_iter_peek_prev - get first entry at or below iterator's current 27373badee4SKent Overstreet * position 27473badee4SKent Overstreet * @_iter: a genradix_iter 27573badee4SKent Overstreet * @_radix: genradix being iterated over 27673badee4SKent Overstreet * 27773badee4SKent Overstreet * If no more entries exist at or below @_iter's current position, returns NULL 27873badee4SKent Overstreet */ 27973badee4SKent Overstreet #define genradix_iter_peek_prev(_iter, _radix) \ 28073badee4SKent Overstreet (__genradix_cast(_radix) \ 28173badee4SKent Overstreet __genradix_iter_peek_prev(_iter, &(_radix)->tree, \ 28273badee4SKent Overstreet __genradix_objs_per_page(_radix), \ 28373badee4SKent Overstreet __genradix_obj_size(_radix) + \ 28473badee4SKent Overstreet __genradix_page_remainder(_radix))) 285ba20ba2eSKent Overstreet 286ba20ba2eSKent Overstreet static inline void __genradix_iter_advance(struct genradix_iter *iter, 287ba20ba2eSKent Overstreet size_t obj_size) 288ba20ba2eSKent Overstreet { 2899492261fSKent Overstreet if (iter->offset + obj_size < iter->offset) { 2909492261fSKent Overstreet iter->offset = SIZE_MAX; 2919492261fSKent Overstreet iter->pos = SIZE_MAX; 2929492261fSKent Overstreet return; 2939492261fSKent Overstreet } 2949492261fSKent Overstreet 295ba20ba2eSKent Overstreet iter->offset += obj_size; 296ba20ba2eSKent Overstreet 297ba20ba2eSKent Overstreet if (!is_power_of_2(obj_size) && 2983a319a24SKent Overstreet (iter->offset & (GENRADIX_NODE_SIZE - 1)) + obj_size > GENRADIX_NODE_SIZE) 2993a319a24SKent Overstreet iter->offset = round_up(iter->offset, GENRADIX_NODE_SIZE); 300ba20ba2eSKent Overstreet 301ba20ba2eSKent Overstreet iter->pos++; 302ba20ba2eSKent Overstreet } 303ba20ba2eSKent Overstreet 304ba20ba2eSKent Overstreet #define genradix_iter_advance(_iter, _radix) \ 305ba20ba2eSKent Overstreet __genradix_iter_advance(_iter, __genradix_obj_size(_radix)) 306ba20ba2eSKent Overstreet 30773badee4SKent Overstreet static inline void __genradix_iter_rewind(struct genradix_iter *iter, 30873badee4SKent Overstreet size_t obj_size) 30973badee4SKent Overstreet { 31073badee4SKent Overstreet if (iter->offset == 0 || 31173badee4SKent Overstreet iter->offset == SIZE_MAX) { 31273badee4SKent Overstreet iter->offset = SIZE_MAX; 31373badee4SKent Overstreet return; 31473badee4SKent Overstreet } 31573badee4SKent Overstreet 3163a319a24SKent Overstreet if ((iter->offset & (GENRADIX_NODE_SIZE - 1)) == 0) 3173a319a24SKent Overstreet iter->offset -= GENRADIX_NODE_SIZE % obj_size; 31873badee4SKent Overstreet 31973badee4SKent Overstreet iter->offset -= obj_size; 32073badee4SKent Overstreet iter->pos--; 32173badee4SKent Overstreet } 32273badee4SKent Overstreet 32373badee4SKent Overstreet #define genradix_iter_rewind(_iter, _radix) \ 32473badee4SKent Overstreet __genradix_iter_rewind(_iter, __genradix_obj_size(_radix)) 32573badee4SKent Overstreet 326ba20ba2eSKent Overstreet #define genradix_for_each_from(_radix, _iter, _p, _start) \ 327ba20ba2eSKent Overstreet for (_iter = genradix_iter_init(_radix, _start); \ 328ba20ba2eSKent Overstreet (_p = genradix_iter_peek(&_iter, _radix)) != NULL; \ 329ba20ba2eSKent Overstreet genradix_iter_advance(&_iter, _radix)) 330ba20ba2eSKent Overstreet 331ba20ba2eSKent Overstreet /** 332ba20ba2eSKent Overstreet * genradix_for_each - iterate over entry in a genradix 333ba20ba2eSKent Overstreet * @_radix: genradix to iterate over 334ba20ba2eSKent Overstreet * @_iter: a genradix_iter to track current position 335ba20ba2eSKent Overstreet * @_p: pointer to genradix entry type 336ba20ba2eSKent Overstreet * 337ba20ba2eSKent Overstreet * On every iteration, @_p will point to the current entry, and @_iter.pos 338ba20ba2eSKent Overstreet * will be the current entry's index. 339ba20ba2eSKent Overstreet */ 340ba20ba2eSKent Overstreet #define genradix_for_each(_radix, _iter, _p) \ 341ba20ba2eSKent Overstreet genradix_for_each_from(_radix, _iter, _p, 0) 342ba20ba2eSKent Overstreet 34373badee4SKent Overstreet #define genradix_last_pos(_radix) \ 3443a319a24SKent Overstreet (SIZE_MAX / GENRADIX_NODE_SIZE * __genradix_objs_per_page(_radix) - 1) 34573badee4SKent Overstreet 34673badee4SKent Overstreet /** 34773badee4SKent Overstreet * genradix_for_each_reverse - iterate over entry in a genradix, reverse order 34873badee4SKent Overstreet * @_radix: genradix to iterate over 34973badee4SKent Overstreet * @_iter: a genradix_iter to track current position 35073badee4SKent Overstreet * @_p: pointer to genradix entry type 35173badee4SKent Overstreet * 35273badee4SKent Overstreet * On every iteration, @_p will point to the current entry, and @_iter.pos 35373badee4SKent Overstreet * will be the current entry's index. 35473badee4SKent Overstreet */ 35573badee4SKent Overstreet #define genradix_for_each_reverse(_radix, _iter, _p) \ 35673badee4SKent Overstreet for (_iter = genradix_iter_init(_radix, genradix_last_pos(_radix));\ 35773badee4SKent Overstreet (_p = genradix_iter_peek_prev(&_iter, _radix)) != NULL;\ 35873badee4SKent Overstreet genradix_iter_rewind(&_iter, _radix)) 35973badee4SKent Overstreet 360ba20ba2eSKent Overstreet int __genradix_prealloc(struct __genradix *, size_t, gfp_t); 361ba20ba2eSKent Overstreet 362ba20ba2eSKent Overstreet /** 363ba20ba2eSKent Overstreet * genradix_prealloc - preallocate entries in a generic radix tree 364ba20ba2eSKent Overstreet * @_radix: genradix to preallocate 365ba20ba2eSKent Overstreet * @_nr: number of entries to preallocate 366ba20ba2eSKent Overstreet * @_gfp: gfp mask 367ba20ba2eSKent Overstreet * 368ba20ba2eSKent Overstreet * Returns 0 on success, -ENOMEM on failure 369ba20ba2eSKent Overstreet */ 370ba20ba2eSKent Overstreet #define genradix_prealloc(_radix, _nr, _gfp) \ 371ba20ba2eSKent Overstreet __genradix_prealloc(&(_radix)->tree, \ 372ba20ba2eSKent Overstreet __genradix_idx_to_offset(_radix, _nr + 1),\ 373ba20ba2eSKent Overstreet _gfp) 374ba20ba2eSKent Overstreet 375ba20ba2eSKent Overstreet 376ba20ba2eSKent Overstreet #endif /* _LINUX_GENERIC_RADIX_TREE_H */ 377