cache_grow() will call kmem_freepages() if the call to alloc_slabmgmt()
fails.  But the pages have not been marked PageSlab at this stage, so
kmem_freepages() goes BUG.

It is more symmetrical to mark the pages as PageSlab in kmem_getpages().

The patch also prunes a bunch of incorrect comments.

(PageSlab doesn't actually do anything: its only value is as a debug check. 
I think the LKCD patch uses it).


 mm/slab.c |   47 +++++++++++++++++++++++------------------------
 1 files changed, 23 insertions(+), 24 deletions(-)

diff -puN mm/slab.c~kmem_freepages-BUG-fix mm/slab.c
--- 25/mm/slab.c~kmem_freepages-BUG-fix	2003-10-18 18:28:19.000000000 -0700
+++ 25-akpm/mm/slab.c	2003-10-18 18:28:19.000000000 -0700
@@ -793,42 +793,42 @@ int __init cpucache_init(void)
 
 __initcall(cpucache_init);
 
-/* Interface to system's page allocator. No need to hold the cache-lock.
+/*
+ * Interface to system's page allocator. No need to hold the cache-lock.
+ *
+ * If we requested dmaable memory, we will get it. Even if we
+ * did not request dmaable memory, we might get it, but that
+ * would be relatively rare and ignorable.
  */
-static inline void * kmem_getpages (kmem_cache_t *cachep, unsigned long flags)
+static inline void *kmem_getpages(kmem_cache_t *cachep, unsigned long flags)
 {
-	void	*addr;
+	void *addr;
 
-	/*
-	 * If we requested dmaable memory, we will get it. Even if we
-	 * did not request dmaable memory, we might get it, but that
-	 * would be relatively rare and ignorable.
-	 */
 	flags |= cachep->gfpflags;
-	if ( cachep->flags & SLAB_RECLAIM_ACCOUNT) 
+	if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
 		atomic_add(1<<cachep->gfporder, &slab_reclaim_pages);
-	addr = (void*) __get_free_pages(flags, cachep->gfporder);
-	/* Assume that now we have the pages no one else can legally
-	 * messes with the 'struct page's.
-	 * However vm_scan() might try to test the structure to see if
-	 * it is a named-page or buffer-page.  The members it tests are
-	 * of no interest here.....
-	 */
+	addr = (void*)__get_free_pages(flags, cachep->gfporder);
+	if (addr) {
+		int i = (1 << cachep->gfporder);
+		struct page *page = virt_to_page(addr);
+
+		while (i--) {
+			SetPageSlab(page);
+			page++;
+		}
+	}
 	return addr;
 }
 
-/* Interface to system's page release. */
-static inline void kmem_freepages (kmem_cache_t *cachep, void *addr)
+/*
+ * Interface to system's page release.
+ */
+static inline void kmem_freepages(kmem_cache_t *cachep, void *addr)
 {
 	unsigned long i = (1<<cachep->gfporder);
 	struct page *page = virt_to_page(addr);
 	const unsigned long nr_freed = i;
 
-	/* free_pages() does not clear the type bit - we do that.
-	 * The pages have been unlinked from their cache-slab,
-	 * but their 'struct page's might be accessed in
-	 * vm_scan(). Shouldn't be a worry.
-	 */
 	while (i--) {
 		if (!TestClearPageSlab(page))
 			BUG();
@@ -1608,7 +1608,6 @@ static int cache_grow (kmem_cache_t * ca
 	do {
 		SET_PAGE_CACHE(page, cachep);
 		SET_PAGE_SLAB(page, slabp);
-		SetPageSlab(page);
 		inc_page_state(nr_slab);
 		page++;
 	} while (--i);

_