The compound page logic is using page->lru, and these get will scribbled on
in various places so switch the Compound page logic over to using ->mapping
and ->private.


---

 25-akpm/arch/i386/mm/hugetlbpage.c    |    1 -
 25-akpm/arch/ia64/mm/hugetlbpage.c    |    1 -
 25-akpm/arch/ppc64/mm/hugetlbpage.c   |    1 -
 25-akpm/arch/sparc64/mm/hugetlbpage.c |    1 -
 25-akpm/include/linux/mm.h            |   10 +++++-----
 25-akpm/mm/page_alloc.c               |   31 ++++++++++++++++---------------
 6 files changed, 21 insertions(+), 24 deletions(-)

diff -puN mm/page_alloc.c~compound-pages-stop-using-lru mm/page_alloc.c
--- 25/mm/page_alloc.c~compound-pages-stop-using-lru	2004-03-26 12:36:42.003714088 -0800
+++ 25-akpm/mm/page_alloc.c	2004-03-26 12:36:42.013712568 -0800
@@ -71,13 +71,14 @@ static int bad_range(struct zone *zone, 
 
 static void bad_page(const char *function, struct page *page)
 {
-	printk("Bad page state at %s (in process '%s', page %p)\n", function, current->comm, page);
-	printk("flags:0x%08lx mapping:%p mapped:%d count:%d\n",
+	printk(KERN_EMERG "Bad page state at %s (in process '%s', page %p)\n",
+		function, current->comm, page);
+	printk(KERN_EMERG "flags:0x%08lx mapping:%p mapped:%d count:%d\n",
 		(unsigned long)page->flags, page->mapping,
 		page_mapped(page), page_count(page));
-	printk("Backtrace:\n");
+	printk(KERN_EMERG "Backtrace:\n");
 	dump_stack();
-	printk("Trying to fix it up, but a reboot is needed\n");
+	printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n");
 	page->flags &= ~(1 << PG_private	|
 			1 << PG_locked	|
 			1 << PG_lru	|
@@ -99,13 +100,13 @@ static void bad_page(const char *functio
  *
  * The remaining PAGE_SIZE pages are called "tail pages".
  *
- * All pages have PG_compound set.  All pages have their lru.next pointing at
+ * All pages have PG_compound set.  All pages have their ->private pointing at
  * the head page (even the head page has this).
  *
- * The head page's lru.prev, if non-zero, holds the address of the compound
- * page's put_page() function.
+ * The first tail page's ->mapping, if non-zero, holds the address of the
+ * compound page's put_page() function.
  *
- * The order of the allocation is stored in the first tail page's lru.prev.
+ * The order of the allocation is stored in the first tail page's ->index
  * This is only for debug at present.  This usage means that zero-order pages
  * may not be compound.
  */
@@ -114,13 +115,13 @@ static void prep_compound_page(struct pa
 	int i;
 	int nr_pages = 1 << order;
 
-	page->lru.prev = NULL;
-	page[1].lru.prev = (void *)order;
+	page[1].mapping = 0;
+	page[1].index = order;
 	for (i = 0; i < nr_pages; i++) {
 		struct page *p = page + i;
 
 		SetPageCompound(p);
-		p->lru.next = (void *)page;
+		p->private = (unsigned long)page;
 	}
 }
 
@@ -129,7 +130,7 @@ static void destroy_compound_page(struct
 	int i;
 	int nr_pages = 1 << order;
 
-	if (page[1].lru.prev != (void *)order)
+	if (page[1].index != order)
 		bad_page(__FUNCTION__, page);
 
 	for (i = 0; i < nr_pages; i++) {
@@ -137,7 +138,7 @@ static void destroy_compound_page(struct
 
 		if (!PageCompound(p))
 			bad_page(__FUNCTION__, page);
-		if (p->lru.next != (void *)page)
+		if (p->private != (unsigned long)page)
 			bad_page(__FUNCTION__, page);
 		ClearPageCompound(p);
 	}
@@ -512,14 +513,14 @@ static struct page *buffered_rmqueue(str
 		spin_lock_irqsave(&zone->lock, flags);
 		page = __rmqueue(zone, order);
 		spin_unlock_irqrestore(&zone->lock, flags);
-		if (order && page)
-			prep_compound_page(page, order);
 	}
 
 	if (page != NULL) {
 		BUG_ON(bad_range(zone, page));
 		mod_page_state_zone(zone, pgalloc, 1 << order);
 		prep_new_page(page, order);
+		if (order)
+			prep_compound_page(page, order);
 	}
 	return page;
 }
diff -puN include/linux/mm.h~compound-pages-stop-using-lru include/linux/mm.h
--- 25/include/linux/mm.h~compound-pages-stop-using-lru	2004-03-26 12:36:42.004713936 -0800
+++ 25-akpm/include/linux/mm.h	2004-03-26 12:36:42.014712416 -0800
@@ -242,24 +242,24 @@ extern void FASTCALL(__page_cache_releas
 static inline int page_count(struct page *p)
 {
 	if (PageCompound(p))
-		p = (struct page *)p->lru.next;
+		p = (struct page *)p->private;
 	return atomic_read(&(p)->count);
 }
 
 static inline void get_page(struct page *page)
 {
 	if (PageCompound(page))
-		page = (struct page *)page->lru.next;
+		page = (struct page *)page->private;
 	atomic_inc(&page->count);
 }
 
 static inline void put_page(struct page *page)
 {
 	if (PageCompound(page)) {
-		page = (struct page *)page->lru.next;
+		page = (struct page *)page->private;
 		if (put_page_testzero(page)) {
-			if (page->lru.prev) {	/* destructor? */
-				(*(void (*)(struct page *))page->lru.prev)(page);
+			if (page[1].mapping) {	/* destructor? */
+				(*(void (*)(struct page *))page[1].mapping)(page);
 			} else {
 				__page_cache_release(page);
 			}
diff -puN arch/i386/mm/hugetlbpage.c~compound-pages-stop-using-lru arch/i386/mm/hugetlbpage.c
--- 25/arch/i386/mm/hugetlbpage.c~compound-pages-stop-using-lru	2004-03-26 12:36:42.005713784 -0800
+++ 25-akpm/arch/i386/mm/hugetlbpage.c	2004-03-26 12:36:42.015712264 -0800
@@ -299,7 +299,6 @@ follow_huge_pmd(struct mm_struct *mm, un
 static void free_huge_page(struct page *page)
 {
 	BUG_ON(page_count(page));
-	BUG_ON(page->mapping);
 
 	INIT_LIST_HEAD(&page->lru);
 
diff -puN arch/ia64/mm/hugetlbpage.c~compound-pages-stop-using-lru arch/ia64/mm/hugetlbpage.c
--- 25/arch/ia64/mm/hugetlbpage.c~compound-pages-stop-using-lru	2004-03-26 12:36:42.007713480 -0800
+++ 25-akpm/arch/ia64/mm/hugetlbpage.c	2004-03-26 12:36:42.016712112 -0800
@@ -246,7 +246,6 @@ follow_huge_pmd(struct mm_struct *mm, un
 void free_huge_page(struct page *page)
 {
 	BUG_ON(page_count(page));
-	BUG_ON(page->mapping);
 
 	INIT_LIST_HEAD(&page->lru);
 
diff -puN arch/ppc64/mm/hugetlbpage.c~compound-pages-stop-using-lru arch/ppc64/mm/hugetlbpage.c
--- 25/arch/ppc64/mm/hugetlbpage.c~compound-pages-stop-using-lru	2004-03-26 12:36:42.008713328 -0800
+++ 25-akpm/arch/ppc64/mm/hugetlbpage.c	2004-03-26 12:36:42.016712112 -0800
@@ -407,7 +407,6 @@ follow_huge_pmd(struct mm_struct *mm, un
 static void free_huge_page(struct page *page)
 {
 	BUG_ON(page_count(page));
-	BUG_ON(page->mapping);
 
 	INIT_LIST_HEAD(&page->lru);
 
diff -puN arch/sparc64/mm/hugetlbpage.c~compound-pages-stop-using-lru arch/sparc64/mm/hugetlbpage.c
--- 25/arch/sparc64/mm/hugetlbpage.c~compound-pages-stop-using-lru	2004-03-26 12:36:42.010713024 -0800
+++ 25-akpm/arch/sparc64/mm/hugetlbpage.c	2004-03-26 12:36:42.017711960 -0800
@@ -248,7 +248,6 @@ struct page *follow_huge_pmd(struct mm_s
 static void free_huge_page(struct page *page)
 {
 	BUG_ON(page_count(page));
-	BUG_ON(page->mapping);
 
 	INIT_LIST_HEAD(&page->lru);
 

_