Add PageVmalloc() If one wants to determine the address of a page struct then a different method may have to be used if it is a Vmalloc'ed page. Add a page flag to mark pages as vmalloced. This is not using an additional page flag since we recycle the PG_swapcache bit. Vmalloc'd pages are higher order pages and so have PG_compound also set. Compound pages are not on the LRU (at least not until the large buffersize patchset) and so we can use that bit for now. (This is wrong!) Signed-off-by: Christoph Lameter --- include/linux/page-flags.h | 18 ++++++++++++++++++ mm/vmalloc.c | 2 ++ 2 files changed, 20 insertions(+) Index: linux-2.6/include/linux/page-flags.h =================================================================== --- linux-2.6.orig/include/linux/page-flags.h 2007-09-18 01:01:52.000000000 -0700 +++ linux-2.6/include/linux/page-flags.h 2007-09-18 03:05:37.000000000 -0700 @@ -248,6 +248,24 @@ static inline void __ClearPageTail(struc #define __SetPageHead(page) __SetPageCompound(page) #define __ClearPageHead(page) __ClearPageCompound(page) +/* + * PG_swapcache is used in combination with PG_compound to indicate + * that a compound page was allocated via vmalloc. + */ +#define PG_vmalloc_mask ((1L << PG_compound) | (1L << PG_swapcache)) +#define PageVmalloc(page) ((page->flags & PG_vmalloc_mask) \ + == PG_vmalloc_mask) + +static inline void __SetPageVmalloc(struct page *page) +{ + page->flags |= PG_vmalloc_mask; +} + +static inline void __ClearPageVmalloc(struct page *page) +{ + page->flags &= ~PG_vmalloc_mask; +} + #ifdef CONFIG_SWAP #define PageSwapCache(page) test_bit(PG_swapcache, &(page)->flags) #define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags) Index: linux-2.6/mm/vmalloc.c =================================================================== --- linux-2.6.orig/mm/vmalloc.c 2007-09-18 03:05:32.000000000 -0700 +++ linux-2.6/mm/vmalloc.c 2007-09-18 03:05:37.000000000 -0700 @@ -463,6 +463,7 @@ static void __vunmap(const void *addr, i struct page *page = area->pages[i]; BUG_ON(!page); + __ClearPageVmalloc(page); __free_page(page); } @@ -579,6 +580,7 @@ void *__vmalloc_area_node(struct vm_stru area->nr_pages = i; goto fail; } + __SetPageVmalloc(page); area->pages[i] = page; }