Original Note: From e6f2ff1e4763212f1dcc945db76fb744b951ac53 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 13 May 2007 15:21:39 -0700 Subject: [PATCH] Lengthen and align background timers to decrease wakeups This patch changes a few background timers in the Linux kernel to 1) be aligned to full seconds so that multiple timers get handled in one processor wakeup 2) have longer timeouts for those timers that can use such longer timeouts Some of these are a bit crude, but it's effective. Signed-off-by: Arjan van de Ven [Josh: Updates for 2.6.22-rc1] Signed-off-by: Josh Triplett --- kernel/time/clocksource.c | 10 ++++++++-- mm/page-writeback.c | 8 ++++---- mm/slab.c | 6 +++--- net/core/neighbour.c | 4 ++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff -Naur linux-2.6.26/kernel/time/clocksource.c linux-2.6.26-magellan/kernel/time/clocksource.c --- linux-2.6.26/kernel/time/clocksource.c 2008-07-13 23:51:29.000000000 +0200 +++ linux-2.6.26-magellan/kernel/time/clocksource.c 2008-08-24 20:11:45.000000000 +0200 @@ -79,11 +79,17 @@ /* * Interval: 0.5sec Threshold: 0.0625s */ -#define WATCHDOG_INTERVAL (HZ >> 1) +#define WATCHDOG_INTERVAL (HZ*10) #define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4) +static int secondtime; + static void clocksource_ratewd(struct clocksource *cs, int64_t delta) { + if (!secondtime) { + secondtime = 1; + return; + }; if (delta > -WATCHDOG_THRESHOLD && delta < WATCHDOG_THRESHOLD) return; @@ -149,7 +155,7 @@ if (next_cpu >= NR_CPUS) next_cpu = first_cpu(cpu_online_map); - watchdog_timer.expires += WATCHDOG_INTERVAL; + round_jiffies(watchdog_timer.expires + WATCHDOG_INTERVAL); add_timer_on(&watchdog_timer, next_cpu); } spin_unlock(&watchdog_lock); diff -Naur linux-2.6.26/mm/page-writeback.c linux-2.6.26-magellan/mm/page-writeback.c --- linux-2.6.26/mm/page-writeback.c 2008-07-13 23:51:29.000000000 +0200 +++ linux-2.6.26-magellan/mm/page-writeback.c 2008-08-24 20:13:16.000000000 +0200 @@ -82,7 +82,7 @@ /* * The interval between `kupdate'-style writebacks, in jiffies */ -int dirty_writeback_interval = 5 * HZ; +int dirty_writeback_interval = 15 * HZ; /* * The longest number of jiffies for which data is allowed to remain dirty @@ -702,7 +702,7 @@ oldest_jif = jiffies - dirty_expire_interval; start_jif = jiffies; - next_jif = start_jif + dirty_writeback_interval; + next_jif = round_jiffies(start_jif + dirty_writeback_interval); nr_to_write = global_page_state(NR_FILE_DIRTY) + global_page_state(NR_UNSTABLE_NFS) + (inodes_stat.nr_inodes - inodes_stat.nr_unused); @@ -720,7 +720,7 @@ nr_to_write -= MAX_WRITEBACK_PAGES - wbc.nr_to_write; } if (time_before(next_jif, jiffies + HZ)) - next_jif = jiffies + HZ; + next_jif = round_jiffies(jiffies + HZ); if (dirty_writeback_interval) mod_timer(&wb_timer, next_jif); } @@ -742,7 +742,7 @@ static void wb_timer_fn(unsigned long unused) { if (pdflush_operation(wb_kupdate, 0) < 0) - mod_timer(&wb_timer, jiffies + HZ); /* delay 1 second */ + mod_timer(&wb_timer, round_jiffies(jiffies + HZ)); /* delay 1 second */ } static void laptop_flush(unsigned long unused) diff -Naur linux-2.6.26/mm/slab.c linux-2.6.26-magellan/mm/slab.c --- linux-2.6.26/mm/slab.c 2008-07-13 23:51:29.000000000 +0200 +++ linux-2.6.26-magellan/mm/slab.c 2008-08-24 20:14:42.000000000 +0200 @@ -463,8 +463,8 @@ * OTOH the cpuarrays can contain lots of objects, * which could lock up otherwise freeable slabs. */ -#define REAPTIMEOUT_CPUC (2*HZ) -#define REAPTIMEOUT_LIST3 (4*HZ) +#define REAPTIMEOUT_CPUC (12*HZ) +#define REAPTIMEOUT_LIST3 (20*HZ) #if STATS #define STATS_INC_ACTIVE(x) ((x)->num_active++) @@ -943,7 +943,7 @@ init_reap_node(cpu); INIT_DELAYED_WORK(reap_work, cache_reap); schedule_delayed_work_on(cpu, reap_work, - __round_jiffies_relative(HZ, cpu)); + __round_jiffies_relative(HZ*4, cpu)); } } diff -Naur linux-2.6.26/net/core/neighbour.c linux-2.6.26-magellan/net/core/neighbour.c --- linux-2.6.26/net/core/neighbour.c 2008-07-13 23:51:29.000000000 +0200 +++ linux-2.6.26-magellan/net/core/neighbour.c 2008-08-24 20:15:41.000000000 +0200 @@ -757,10 +757,10 @@ if (!expire) expire = 1; - if (expire>HZ) + if (expire>4*HZ) mod_timer(&tbl->gc_timer, round_jiffies(now + expire)); else - mod_timer(&tbl->gc_timer, now + expire); + mod_timer(&tbl->gc_timer, round_jiffies(now + 4*HZ)); write_unlock(&tbl->lock); }