diff options
Diffstat (limited to 'lib/radix-tree.c')
-rw-r--r-- | lib/radix-tree.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 48c250fe2233..65f0e758ec38 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -95,14 +95,17 @@ static inline gfp_t root_gfp_mask(struct radix_tree_root *root) | |||
95 | static struct radix_tree_node * | 95 | static struct radix_tree_node * |
96 | radix_tree_node_alloc(struct radix_tree_root *root) | 96 | radix_tree_node_alloc(struct radix_tree_root *root) |
97 | { | 97 | { |
98 | struct radix_tree_node *ret; | 98 | struct radix_tree_node *ret = NULL; |
99 | gfp_t gfp_mask = root_gfp_mask(root); | 99 | gfp_t gfp_mask = root_gfp_mask(root); |
100 | 100 | ||
101 | ret = kmem_cache_alloc(radix_tree_node_cachep, | 101 | if (!(gfp_mask & __GFP_WAIT)) { |
102 | set_migrateflags(gfp_mask, __GFP_RECLAIMABLE)); | ||
103 | if (ret == NULL && !(gfp_mask & __GFP_WAIT)) { | ||
104 | struct radix_tree_preload *rtp; | 102 | struct radix_tree_preload *rtp; |
105 | 103 | ||
104 | /* | ||
105 | * Provided the caller has preloaded here, we will always | ||
106 | * succeed in getting a node here (and never reach | ||
107 | * kmem_cache_alloc) | ||
108 | */ | ||
106 | rtp = &__get_cpu_var(radix_tree_preloads); | 109 | rtp = &__get_cpu_var(radix_tree_preloads); |
107 | if (rtp->nr) { | 110 | if (rtp->nr) { |
108 | ret = rtp->nodes[rtp->nr - 1]; | 111 | ret = rtp->nodes[rtp->nr - 1]; |
@@ -110,6 +113,10 @@ radix_tree_node_alloc(struct radix_tree_root *root) | |||
110 | rtp->nr--; | 113 | rtp->nr--; |
111 | } | 114 | } |
112 | } | 115 | } |
116 | if (ret == NULL) | ||
117 | ret = kmem_cache_alloc(radix_tree_node_cachep, | ||
118 | set_migrateflags(gfp_mask, __GFP_RECLAIMABLE)); | ||
119 | |||
113 | BUG_ON(radix_tree_is_indirect_ptr(ret)); | 120 | BUG_ON(radix_tree_is_indirect_ptr(ret)); |
114 | return ret; | 121 | return ret; |
115 | } | 122 | } |