aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/idr.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/lib/idr.c b/lib/idr.c
index c6fb8295507b..322e2816f2fb 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -106,8 +106,14 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
106 if (layer_idr) 106 if (layer_idr)
107 return get_from_free_list(layer_idr); 107 return get_from_free_list(layer_idr);
108 108
109 /* try to allocate directly from kmem_cache */ 109 /*
110 new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); 110 * Try to allocate directly from kmem_cache. We want to try this
111 * before preload buffer; otherwise, non-preloading idr_alloc()
112 * users will end up taking advantage of preloading ones. As the
113 * following is allowed to fail for preloaded cases, suppress
114 * warning this time.
115 */
116 new = kmem_cache_zalloc(idr_layer_cache, gfp_mask | __GFP_NOWARN);
111 if (new) 117 if (new)
112 return new; 118 return new;
113 119
@@ -115,18 +121,24 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
115 * Try to fetch one from the per-cpu preload buffer if in process 121 * Try to fetch one from the per-cpu preload buffer if in process
116 * context. See idr_preload() for details. 122 * context. See idr_preload() for details.
117 */ 123 */
118 if (in_interrupt()) 124 if (!in_interrupt()) {
119 return NULL; 125 preempt_disable();
120 126 new = __this_cpu_read(idr_preload_head);
121 preempt_disable(); 127 if (new) {
122 new = __this_cpu_read(idr_preload_head); 128 __this_cpu_write(idr_preload_head, new->ary[0]);
123 if (new) { 129 __this_cpu_dec(idr_preload_cnt);
124 __this_cpu_write(idr_preload_head, new->ary[0]); 130 new->ary[0] = NULL;
125 __this_cpu_dec(idr_preload_cnt); 131 }
126 new->ary[0] = NULL; 132 preempt_enable();
133 if (new)
134 return new;
127 } 135 }
128 preempt_enable(); 136
129 return new; 137 /*
138 * Both failed. Try kmem_cache again w/o adding __GFP_NOWARN so
139 * that memory allocation failure warning is printed as intended.
140 */
141 return kmem_cache_zalloc(idr_layer_cache, gfp_mask);
130} 142}
131 143
132static void idr_layer_rcu_free(struct rcu_head *head) 144static void idr_layer_rcu_free(struct rcu_head *head)