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-14 03:00:55.605132088 -0800 +++ 25-akpm/mm/page_alloc.c 2004-03-14 03:00:55.617130264 -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-14 03:00:55.606131936 -0800 +++ 25-akpm/include/linux/mm.h 2004-03-14 03:00:55.618130112 -0800 @@ -239,24 +239,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-14 03:00:55.608131632 -0800 +++ 25-akpm/arch/i386/mm/hugetlbpage.c 2004-03-14 03:00:55.618130112 -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-14 03:00:55.609131480 -0800 +++ 25-akpm/arch/ia64/mm/hugetlbpage.c 2004-03-14 03:00:55.619129960 -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-14 03:00:55.611131176 -0800 +++ 25-akpm/arch/ppc64/mm/hugetlbpage.c 2004-03-14 03:00:55.620129808 -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-14 03:00:55.613130872 -0800 +++ 25-akpm/arch/sparc64/mm/hugetlbpage.c 2004-03-14 03:00:55.620129808 -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); _