diff options
Diffstat (limited to 'lib/radix-tree.c')
-rw-r--r-- | lib/radix-tree.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index eaea14b8f2ca..7b9f8515033e 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -70,6 +70,14 @@ static struct kmem_cache *radix_tree_node_cachep; | |||
70 | #define IDR_PRELOAD_SIZE (IDR_MAX_PATH * 2 - 1) | 70 | #define IDR_PRELOAD_SIZE (IDR_MAX_PATH * 2 - 1) |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * The IDA is even shorter since it uses a bitmap at the last level. | ||
74 | */ | ||
75 | #define IDA_INDEX_BITS (8 * sizeof(int) - 1 - ilog2(IDA_BITMAP_BITS)) | ||
76 | #define IDA_MAX_PATH (DIV_ROUND_UP(IDA_INDEX_BITS, \ | ||
77 | RADIX_TREE_MAP_SHIFT)) | ||
78 | #define IDA_PRELOAD_SIZE (IDA_MAX_PATH * 2 - 1) | ||
79 | |||
80 | /* | ||
73 | * Per-cpu pool of preloaded nodes | 81 | * Per-cpu pool of preloaded nodes |
74 | */ | 82 | */ |
75 | struct radix_tree_preload { | 83 | struct radix_tree_preload { |
@@ -346,9 +354,8 @@ static void dump_ida_node(void *entry, unsigned long index) | |||
346 | static void ida_dump(struct ida *ida) | 354 | static void ida_dump(struct ida *ida) |
347 | { | 355 | { |
348 | struct radix_tree_root *root = &ida->ida_rt; | 356 | struct radix_tree_root *root = &ida->ida_rt; |
349 | pr_debug("ida: %p %p free %d bitmap %p\n", ida, root->rnode, | 357 | pr_debug("ida: %p node %p free %d\n", ida, root->rnode, |
350 | root->gfp_mask >> ROOT_TAG_SHIFT, | 358 | root->gfp_mask >> ROOT_TAG_SHIFT); |
351 | ida->free_bitmap); | ||
352 | dump_ida_node(root->rnode, 0); | 359 | dump_ida_node(root->rnode, 0); |
353 | } | 360 | } |
354 | #endif | 361 | #endif |
@@ -2080,6 +2087,36 @@ void idr_preload(gfp_t gfp_mask) | |||
2080 | } | 2087 | } |
2081 | EXPORT_SYMBOL(idr_preload); | 2088 | EXPORT_SYMBOL(idr_preload); |
2082 | 2089 | ||
2090 | /** | ||
2091 | * ida_pre_get - reserve resources for ida allocation | ||
2092 | * @ida: ida handle | ||
2093 | * @gfp: memory allocation flags | ||
2094 | * | ||
2095 | * This function should be called before calling ida_get_new_above(). If it | ||
2096 | * is unable to allocate memory, it will return %0. On success, it returns %1. | ||
2097 | */ | ||
2098 | int ida_pre_get(struct ida *ida, gfp_t gfp) | ||
2099 | { | ||
2100 | __radix_tree_preload(gfp, IDA_PRELOAD_SIZE); | ||
2101 | /* | ||
2102 | * The IDA API has no preload_end() equivalent. Instead, | ||
2103 | * ida_get_new() can return -EAGAIN, prompting the caller | ||
2104 | * to return to the ida_pre_get() step. | ||
2105 | */ | ||
2106 | preempt_enable(); | ||
2107 | |||
2108 | if (!this_cpu_read(ida_bitmap)) { | ||
2109 | struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp); | ||
2110 | if (!bitmap) | ||
2111 | return 0; | ||
2112 | bitmap = this_cpu_cmpxchg(ida_bitmap, NULL, bitmap); | ||
2113 | kfree(bitmap); | ||
2114 | } | ||
2115 | |||
2116 | return 1; | ||
2117 | } | ||
2118 | EXPORT_SYMBOL(ida_pre_get); | ||
2119 | |||
2083 | void **idr_get_free(struct radix_tree_root *root, | 2120 | void **idr_get_free(struct radix_tree_root *root, |
2084 | struct radix_tree_iter *iter, gfp_t gfp, int end) | 2121 | struct radix_tree_iter *iter, gfp_t gfp, int end) |
2085 | { | 2122 | { |
@@ -2219,6 +2256,8 @@ static int radix_tree_cpu_dead(unsigned int cpu) | |||
2219 | kmem_cache_free(radix_tree_node_cachep, node); | 2256 | kmem_cache_free(radix_tree_node_cachep, node); |
2220 | rtp->nr--; | 2257 | rtp->nr--; |
2221 | } | 2258 | } |
2259 | kfree(per_cpu(ida_bitmap, cpu)); | ||
2260 | per_cpu(ida_bitmap, cpu) = NULL; | ||
2222 | return 0; | 2261 | return 0; |
2223 | } | 2262 | } |
2224 | 2263 | ||