46 lines
1.4 KiB
Diff
46 lines
1.4 KiB
Diff
From: Nick Piggin <npiggin@suse.de>
|
|
Subject: Fix almost-infinite slab cache growing
|
|
References: bnc#554081
|
|
Patch-mainline: never
|
|
|
|
If we get into cache_alloc_refill() with must_refill set, we end up in an
|
|
almost endless loop adding more and more pages to the slab. The loop can be
|
|
broken only by a failure to allocate more pages or an interrupt refilling the
|
|
slab's allocation cache.
|
|
|
|
Fix the issue by jumping to a more appropriate place when the allocation cache
|
|
is not refilled by an interrupt.
|
|
|
|
Signed-off-by: Nick Piggin <npiggin@suse.de
|
|
Acked-by: Jan Kara <jack@suse.cz>
|
|
|
|
Index: linux-2.6.38-master/mm/slab.c
|
|
===================================================================
|
|
--- linux-2.6.38-master.orig/mm/slab.c
|
|
+++ linux-2.6.38-master/mm/slab.c
|
|
@@ -3104,11 +3104,11 @@ static void *cache_alloc_refill(struct k
|
|
struct array_cache *ac;
|
|
int node;
|
|
|
|
-retry:
|
|
check_irq_off();
|
|
node = numa_slab_nid(cachep, flags);
|
|
if (unlikely(must_refill))
|
|
goto force_grow;
|
|
+retry:
|
|
ac = cpu_cache_get(cachep);
|
|
batchcount = ac->batchcount;
|
|
if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
|
|
@@ -3188,8 +3188,10 @@ force_grow:
|
|
if (!x && (ac->avail == 0 || must_refill))
|
|
return NULL;
|
|
|
|
- if (!ac->avail) /* objects refilled by interrupt? */
|
|
+ if (!ac->avail) { /* objects refilled by interrupt? */
|
|
+ node = numa_node_id();
|
|
goto retry;
|
|
+ }
|
|
}
|
|
ac->touched = 1;
|
|
return ac->entry[--ac->avail];
|