--- mm/vmscan.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) Index: linux-2.6/mm/vmscan.c =================================================================== --- linux-2.6.orig/mm/vmscan.c 2007-08-13 23:01:25.000000000 -0700 +++ linux-2.6/mm/vmscan.c 2007-08-13 23:09:48.000000000 -0700 @@ -132,6 +132,12 @@ void unregister_shrinker(struct shrinker } EXPORT_SYMBOL(unregister_shrinker); +/* + * Min freekbytes is 2m. 3000 pages give us 12M which is + * able to exhaust the reserves + */ +#define NR_TEST 3000 + #define SHRINK_BATCH 128 /* * Call the shrink functions to age shrinkable caches @@ -1153,8 +1159,34 @@ unsigned long try_to_free_pages(struct z if (gfp_mask & __GFP_WAIT) { sc.may_writepage = !laptop_mode; sc.may_swap = 1; + } else { + struct page **base; + int i; + static unsigned long lasttime = 0; + + /* Every 2 minutes */ + if (time_after(jiffies, lasttime + (120 * HZ))) { + lasttime += 120 * HZ; + printk(KERN_CRIT "Reclaim: Excessive GFP_KERNEL allocs\n"); + /* Force memory to become exhausted */ + base = kzalloc(NR_TEST * sizeof(void *), GFP_KERNEL); + + for (i = 0; i < NR_TEST; i++) { + base[i] = alloc_page(GFP_KERNEL); + if (!base[i]) { + printk("Alloc failed at %d\n", i); + break; + } + } + for (i = 0; i < NR_TEST; i++) + if (base[i]) + put_page(base[i]); + kfree(base); + printk(KERN_CRIT "Reclaim: Memory freed\n"); + } } + for (i = 0; zones[i] != NULL; i++) { struct zone *zone = zones[i];