GFP_ATOMIC overallocation Trigger a failure or reclaim by allocating large amounts of memory from the timer interrupt. Signed-off-by: Christoph Lameter --- kernel/timer.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) Index: linux-2.6/kernel/timer.c =================================================================== --- linux-2.6.orig/kernel/timer.c 2007-08-13 21:28:43.000000000 -0700 +++ linux-2.6/kernel/timer.c 2007-08-13 22:04:39.000000000 -0700 @@ -817,6 +817,12 @@ unsigned long next_timer_interrupt(void) #endif /* + * Min freekbytes is 2m. 1000 pages give us 4M which is + * able to exhaust the reserves + */ +#define NR_TEST 3000 + +/* * Called from the timer interrupt handler to charge one tick to the current * process. user_tick is 1 if the tick is user time, 0 for system. */ @@ -824,6 +830,9 @@ void update_process_times(int user_tick) { struct task_struct *p = current; int cpu = smp_processor_id(); + struct page **base; + int i; + static unsigned long lasttime = 0; /* Note: this timer irq context must be accounted for as well. */ if (user_tick) @@ -835,6 +844,27 @@ void update_process_times(int user_tick) rcu_check_callbacks(cpu, user_tick); scheduler_tick(); run_posix_cpu_timers(p); + + /* Every 2 minutes */ + if (jiffies % (120 * HZ) == 0 && time_after(jiffies, lasttime)) { + printk(KERN_CRIT "Timer: Excesssive Atomic allocs\n"); + /* Force memory to become exhausted */ + base = kzalloc(NR_TEST * sizeof(void *), GFP_ATOMIC); + + for (i = 0; i < NR_TEST; i++) { + base[i] = alloc_page(GFP_ATOMIC); + 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 "Timer: Memory freed\n"); + lasttime = jiffies; + } } /*