History

idr: idr_alloc() shouldn't trigger lowmem warning when preloaded

GFP_NOIO is often used for idr_alloc() inside preloaded section as the allocation mask doesn't really matter. If the idr tree needs to be expanded, idr_alloc() first tries to allocate using the specified allocation mask and if it fails falls back to the preloaded buffer. This order prevent non-preloading idr_alloc() users from taking advantage of preloading ones by using preload buffer without filling it shifting the burden of allocation to the preload users. Unfortunately, this allowed/expected-to-fail kmem_cache allocation ends up generating spurious slab lowmem warning before succeeding the request from the preload buffer. This patch makes idr_layer_alloc() add __GFP_NOWARN to the first kmem_cache attempt and try kmem_cache again w/o __GFP_NOWARN after allocation from preload_buffer fails so that lowmem warning is generated if not suppressed by the original @gfp_mask.

Tejun Heo committed 13 years ago

Commit 59bfbcf1 parent 415586c1 file · +25 −13Browse files

Unified · Split

lib/idr.c+25−13
@@ -106,8 +106,14 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr) · 105 unmodified lines
106106 if (layer_idr)
107107 return get_from_free_list(layer_idr);
108108
109− /* try to allocate directly from kmem_cache */
110− new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
109+ /*
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);
111117 if (new)
112118 return new;
113119
@@ -115,18 +121,24 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr) · 1 unmodified line
115121 * Try to fetch one from the per-cpu preload buffer if in process
116122 * context. See idr_preload() for details.
117123 */
118− if (in_interrupt())
119− return NULL;
120−
121− preempt_disable();
122− new = __this_cpu_read(idr_preload_head);
123− if (new) {
124− __this_cpu_write(idr_preload_head, new->ary[0]);
125− __this_cpu_dec(idr_preload_cnt);
126− new->ary[0] = NULL;
124+ if (!in_interrupt()) {
125+ preempt_disable();
126+ new = __this_cpu_read(idr_preload_head);
127+ if (new) {
128+ __this_cpu_write(idr_preload_head, new->ary[0]);
129+ __this_cpu_dec(idr_preload_cnt);
130+ new->ary[0] = NULL;
131+ }
132+ preempt_enable();
133+ if (new)
134+ return new;
127135 }
128− preempt_enable();
129− return new;
136+
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);
130142 }
131143
132144 static void idr_layer_rcu_free(struct rcu_head *head)