--- mm/vmalloc.c | 22 +++++++++++++++++----- mm/vmstat.c | 7 +++++++ 2 files changed, 24 insertions(+), 5 deletions(-) Index: linux-2.6.25-rc8-mm2/mm/vmalloc.c =================================================================== --- linux-2.6.25-rc8-mm2.orig/mm/vmalloc.c 2008-04-16 00:11:52.992000591 -0700 +++ linux-2.6.25-rc8-mm2/mm/vmalloc.c 2008-04-16 00:12:07.545741280 -0700 @@ -1035,17 +1035,23 @@ static void __vcompound_free(void *addr) * for the compound and was decremented before we got here. */ set_page_address(pages[0], NULL); + BUG_ON(!PageHead(pages[0]) || PageTail(pages[0]) || !PageVcompound(pages[0])); __ClearPageVcompound(pages[0]); + __ClearPageHead(pages[0]); + printk("FreeHead array=%p p=%p flag=%lx mapping=%lx\n", pages, + pages[0], pages[0]->flags, pages[0]->mapping); free_hot_page(pages[0]); for (i = 1; i < (1 << order); i++) { struct page *page = pages[i]; - BUG_ON(!PageTail(page) || !PageVcompound(page)); + printk("FreeTail=%d\n", i); + BUG_ON(!PageTail(page)); set_page_address(page, NULL); - __ClearPageVcompound(page); + __ClearPageTail(page); __free_page(page); } kfree(pages); + printk("Free Done\n"); } static void vcompound_free_work(struct work_struct *w) @@ -1057,6 +1063,8 @@ static void vcompound_free(void *addr, s { struct work_struct *w = addr; + printk("vcompound_free(%p, %p)\n", addr, page); + BUG_ON((!PageVcompound(page) || !PageHead(page))); if (!put_page_testzero(page)) @@ -1107,6 +1115,7 @@ static struct vm_struct *____alloc_vcomp gfp_mask & GFP_RECLAIM_MASK); struct page **pages2; + printk(KERN_CRIT "___alloc_vcompound(%x, %ld, %p)\n", gfp_mask, order, caller); if (!pages) return NULL; @@ -1115,8 +1124,6 @@ static struct vm_struct *____alloc_vcomp if (!page) goto abort; - /* Sets PageCompound which makes PageHead(page) true */ - __SetPageVcompound(page); pages[i] = page; } @@ -1134,14 +1141,19 @@ static struct vm_struct *____alloc_vcomp goto abort; pages[1]->lru.prev = (void *)order; + __SetPageHead(pages[0]); + __SetPageVcompound(pages[0]); + set_page_address(pages[0], vm->addr); - for (i = 0; i < nr_pages; i++) { + for (i = 1; i < nr_pages; i++) { struct page *page = pages[i]; __SetPageTail(page); page->first_page = pages[0]; set_page_address(page, vm->addr + (i << PAGE_SHIFT)); } + printk(KERN_CRIT "vmlist %p nr_pages=%d caller=%p pages=%p addr=%p\n", + vm, vm->nr_pages, vm->caller, vm->pages, vm->addr); return vm; abort: Index: linux-2.6.25-rc8-mm2/mm/vmstat.c =================================================================== --- linux-2.6.25-rc8-mm2.orig/mm/vmstat.c 2008-04-16 00:11:32.501991067 -0700 +++ linux-2.6.25-rc8-mm2/mm/vmstat.c 2008-04-16 00:12:07.565750173 -0700 @@ -14,6 +14,7 @@ #include #include #include +#include #include "internal.h" #ifdef CONFIG_VM_EVENT_COUNTERS @@ -831,7 +832,13 @@ static void *vmstat_start(struct seq_fil unsigned long *e; #endif int i; + void *p; + + printk(KERN_CRIT "Running tests.... \n"); + p = __alloc_vcompound(GFP_KERNEL, 1); + memset(p, 1, PAGE_SIZE << 1); + __free_vcompound(p); if (*pos >= ARRAY_SIZE(vmstat_text)) return NULL;