aboutsummaryrefslogtreecommitdiffstats
path: root/lib/radix-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/radix-tree.c')
-rw-r--r--lib/radix-tree.c45
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 */
75struct radix_tree_preload { 83struct radix_tree_preload {
@@ -346,9 +354,8 @@ static void dump_ida_node(void *entry, unsigned long index)
346static void ida_dump(struct ida *ida) 354static 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}
2081EXPORT_SYMBOL(idr_preload); 2088EXPORT_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 */
2098int 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}
2118EXPORT_SYMBOL(ida_pre_get);
2119
2083void **idr_get_free(struct radix_tree_root *root, 2120void **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