From 714b8171af9c930a59a0da8f6fe50518e70ab035 Mon Sep 17 00:00:00 2001
From: Pekka Enberg <penberg@cs.helsinki.fi>
Date: Sun, 6 May 2007 14:49:03 -0700
Subject: [PATCH] slab: ensure cache_alloc_refill terminates

If slab->inuse is corrupted, cache_alloc_refill can enter an infinite
loop as detailed by Michael Richardson in the following post:
<http://lkml.org/lkml/2007/2/16/292>. This adds a BUG_ON to catch
those cases.

Cc: Michael Richardson <mcr@sandelman.ca>
Acked-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 mm/slab.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/mm/slab.c b/mm/slab.c
index 8b71a9c3daa4a..21b2aef25254c 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2990,6 +2990,14 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)
 		slabp = list_entry(entry, struct slab, list);
 		check_slabp(cachep, slabp);
 		check_spinlock_acquired(cachep);
+
+		/*
+		 * The slab was either on partial or free list so
+		 * there must be at least one object available for
+		 * allocation.
+		 */
+		BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
+
 		while (slabp->inuse < cachep->num && batchcount--) {
 			STATS_INC_ALLOCED(cachep);
 			STATS_INC_ACTIVE(cachep);
-- 
GitLab