diff options
| -rw-r--r-- | arch/i386/mm/hugetlbpage.c | 1 | ||||
| -rw-r--r-- | arch/ia64/mm/hugetlbpage.c | 1 | ||||
| -rw-r--r-- | arch/ppc64/mm/hugetlbpage.c | 1 | ||||
| -rw-r--r-- | arch/sparc64/mm/hugetlbpage.c | 1 | ||||
| -rw-r--r-- | include/linux/mm.h | 10 | ||||
| -rw-r--r-- | mm/page_alloc.c | 31 |
6 files changed, 21 insertions, 24 deletions
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index 1777966f0186..0c73f414b5b1 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c @@ -278,7 +278,6 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, static void free_huge_page(struct page *page) { BUG_ON(page_count(page)); - BUG_ON(page->mapping); INIT_LIST_HEAD(&page->lru); diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index d75ec2bfdb41..aa2a1945d2c2 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -246,7 +246,6 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int wri void free_huge_page(struct page *page) { BUG_ON(page_count(page)); - BUG_ON(page->mapping); INIT_LIST_HEAD(&page->lru); diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index 3b67759defe1..032a1c9c5766 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c @@ -450,7 +450,6 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, static void free_huge_page(struct page *page) { BUG_ON(page_count(page)); - BUG_ON(page->mapping); INIT_LIST_HEAD(&page->lru); diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index 867d8b788e6b..dd2a7549caef 100644 --- a/arch/sparc64/mm/hugetlbpage.c +++ b/arch/sparc64/mm/hugetlbpage.c @@ -248,7 +248,6 @@ struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, static void free_huge_page(struct page *page) { BUG_ON(page_count(page)); - BUG_ON(page->mapping); INIT_LIST_HEAD(&page->lru); diff --git a/include/linux/mm.h b/include/linux/mm.h index af18e1da3bd5..fa7beaefd038 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -242,24 +242,24 @@ extern void FASTCALL(__page_cache_release(struct page *)); 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 --git a/mm/page_alloc.c b/mm/page_alloc.c index b79b7907e734..6cb630fec60e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -71,13 +71,14 @@ static int bad_range(struct zone *zone, struct page *page) 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 *function, struct page *page) * * 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 page *page, unsigned long order) 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 page *page, unsigned long order) 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 page *page, unsigned long order) 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(struct zone *zone, int order, int cold) 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; } |
