--- lib/Kconfig.debug | 11 +++++++++++ mm/page_alloc.c | 20 ++++++++++++++++++-- mm/vmalloc.c | 4 ++++ 3 files changed, 33 insertions(+), 2 deletions(-) Index: linux-2.6/mm/page_alloc.c =================================================================== --- linux-2.6.orig/mm/page_alloc.c 2007-09-18 13:29:15.000000000 -0700 +++ linux-2.6/mm/page_alloc.c 2007-09-18 13:30:34.000000000 -0700 @@ -1159,6 +1159,13 @@ get_page_from_freelist(gfp_t gfp_mask, u int did_zlc_setup = 0; /* just call zlc_setup() one time */ enum zone_type highest_zoneidx = -1; /* Gets set for policy zonelists */ + /* Force use of vmalloc */ + if (order >= 2 && (gfp_mask & __GFP_VFALLBACK) && + (gfp_mask & __GFP_WAIT) && + system_state == SYSTEM_RUNNING && + !test_thread_flag(TIF_MEMDIE)) + return NULL; + zonelist_scan: /* * Scan zonelist, looking for a zone with enough free. @@ -1205,7 +1212,12 @@ zonelist_scan: goto this_zone_full; } } - +#ifdef CONFIG_VFALLBACK_ALWAYS + if (gfp_mask & __GFP_VFALLBACK) + page = vcompound_alloc(gfp_mask, order, + zonelist, alloc_flags); + else +#endif page = buffered_rmqueue(zonelist, zone, order, gfp_mask); if (page) break; @@ -1441,6 +1453,10 @@ nofail_alloc: reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; + if (order >= 2 && (gfp_mask & (__GFP_VFALLBACK|__GFP_WAIT)) + == (__GFP_VFALLBACK|__GFP_WAIT)) + did_some_progress = 0; + else did_some_progress = try_to_free_pages(zonelist->zones, order, gfp_mask); p->reclaim_state = NULL; @@ -1486,7 +1502,7 @@ nofail_alloc: * <= 3, but that may not be true in other implementations. */ do_retry = 0; - if (!(gfp_mask & __GFP_NORETRY)) { + if (!(gfp_mask & __GFP_NORETRY) && !(gfp_mask && __GFP_VFALLBACK)) { if ((order <= PAGE_ALLOC_COSTLY_ORDER) || (gfp_mask & __GFP_REPEAT)) do_retry = 1; Index: linux-2.6/mm/vmalloc.c =================================================================== --- linux-2.6.orig/mm/vmalloc.c 2007-09-18 13:23:44.000000000 -0700 +++ linux-2.6/mm/vmalloc.c 2007-09-18 13:30:34.000000000 -0700 @@ -268,6 +268,10 @@ void *vmalloc_address(struct page *page) if (n) return (void *)n; } while (pgd++, addr = next, addr < VMALLOC_END); + + printk("vmalloc_address failed! page=%p flags=%x\n", page, page->flags); + WARN_ON(1); + return NULL; } EXPORT_SYMBOL(vmalloc_address); Index: linux-2.6/lib/Kconfig.debug =================================================================== --- linux-2.6.orig/lib/Kconfig.debug 2007-09-18 13:18:20.000000000 -0700 +++ linux-2.6/lib/Kconfig.debug 2007-09-18 13:30:34.000000000 -0700 @@ -105,6 +105,17 @@ config DETECT_SOFTLOCKUP can be detected via the NMI-watchdog, on platforms that support it.) +config VFALLBACK_ALWAYS + bool "Always fall back to Virtual Compound pages" + default y + help + Virtual compound pages are only allocated if there is no linear + memory available. They are a fallback and errors created by the + use of virtual mappings instead of linear ones may not surface + because of their infrequent use. This option makes every + allocation that allows a fallback to a virtual mapping use + the virtual mapping. May have a significant performance impact. + config SCHED_DEBUG bool "Collect scheduler debugging info" depends on DEBUG_KERNEL && PROC_FS