--- include/linux/mm.h | 31 +++++++++++++++++++++++++------ mm/internal.h | 2 +- mm/page_alloc.c | 3 +-- 3 files changed, 27 insertions(+), 9 deletions(-) Index: linux-2.6/include/linux/mm.h =================================================================== --- linux-2.6.orig/include/linux/mm.h 2007-11-14 21:13:42.000000000 -0800 +++ linux-2.6/include/linux/mm.h 2007-11-14 21:22:21.000000000 -0800 @@ -288,14 +288,12 @@ static inline compound_page_dtor *get_co static inline int compound_order(struct page *page) { - if (!PageHead(page)) - return 0; - return (unsigned long)page[1].lru.prev; + return page_to_order(page); } static inline void set_compound_order(struct page *page, unsigned long order) { - page[1].lru.prev = (void *)order; + set_page_order(page, order); } /* @@ -392,6 +390,12 @@ static inline void set_compound_order(st #define NODES_WIDTH 0 #endif +#if CONFIG_64BIT +#define ORDER_WIDTH 6 +#else +#define ORDER_WIDTH 0 +#endif + /* Page flags: | [SECTION] | [NODE] | ZONE | ... | FLAGS | */ #define SECTIONS_PGOFF ((sizeof(unsigned long)*8) - SECTIONS_WIDTH) #define NODES_PGOFF (SECTIONS_PGOFF - NODES_WIDTH) @@ -429,16 +433,20 @@ static inline void set_compound_order(st NODES_PGOFF : ZONES_PGOFF) #endif +#define ORDER_SHIFT 6 +#define ORDER_PGOFF (ZONEID_PGFOFF + ZONEID_SHIFT) + #define ZONEID_PGSHIFT (ZONEID_PGOFF * (ZONEID_SHIFT != 0)) -#if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED -#error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED +#if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH+ORDER_WIDTH > FLAGS_RESERVED +#error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH+ORDER_WIDTH > FLAGS_RESERVED #endif #define ZONES_MASK ((1UL << ZONES_WIDTH) - 1) #define NODES_MASK ((1UL << NODES_WIDTH) - 1) #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) #define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1) +#define ORDER_MASK ((1UL << ORDER_SHIFT) - 1) static inline enum zone_type page_zonenum(struct page *page) { @@ -486,6 +494,11 @@ static inline unsigned long page_to_sect return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK; } +static inline unsigned long page_to_order(struct page *page) +{ + return (page->flags >> ORDER_PGSHIFT) & ORDER_MASK; +} + static inline void set_page_zone(struct page *page, enum zone_type zone) { page->flags &= ~(ZONES_MASK << ZONES_PGSHIFT); @@ -504,6 +517,12 @@ static inline void set_page_section(stru page->flags |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT; } +static inline void set_page_order(struct page *page, unsigned long order) +{ + page->flags &= ~(ORDER_MASK << ORDER_PGSHIFT); + page->flags |= (order & ORDER_MASK) << ORDER_PGSHIFT; +} + static inline void set_page_links(struct page *page, enum zone_type zone, unsigned long node, unsigned long pfn) { Index: linux-2.6/mm/internal.h =================================================================== --- linux-2.6.orig/mm/internal.h 2007-11-14 21:22:41.000000000 -0800 +++ linux-2.6/mm/internal.h 2007-11-14 21:23:30.000000000 -0800 @@ -45,6 +45,6 @@ extern void fastcall __init __free_pages static inline unsigned long page_order(struct page *page) { VM_BUG_ON(!PageBuddy(page)); - return page_private(page); + return page_to_order(page); } #endif Index: linux-2.6/mm/page_alloc.c =================================================================== --- linux-2.6.orig/mm/page_alloc.c 2007-11-14 21:22:28.000000000 -0800 +++ linux-2.6/mm/page_alloc.c 2007-11-14 21:24:51.000000000 -0800 @@ -317,14 +317,13 @@ static inline void prep_zero_page(struct static inline void set_page_order(struct page *page, int order) { - set_page_private(page, order); + set_page_order(page, order); __SetPageBuddy(page); } static inline void rmv_page_order(struct page *page) { __ClearPageBuddy(page); - set_page_private(page, 0); } /*