net: use a deferred timer in rt_check_expire
authorEric Dumazet <eric.dumazet@gmail.com>
Thu, 11 Jun 2009 20:10:07 +0000 (20:10 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 14 Jun 2009 06:36:31 +0000 (23:36 -0700)
For the sake of power saver lovers, use a deferrable timer to fire
rt_check_expire()

As some big routers cache equilibrium depends on garbage collection
done in time, we take into account elapsed time between two
rt_check_expire() invocations to adjust the amount of slots we have to
check.

Based on an initial idea and patch from Tero Kristo

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/route.c

index a849bb1..cd76b3c 100644 (file)
@@ -131,8 +131,8 @@ static int ip_rt_min_advmss __read_mostly   = 256;
 static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ;
 static int rt_chain_length_max __read_mostly   = 20;
 
-static void rt_worker_func(struct work_struct *work);
-static DECLARE_DELAYED_WORK(expires_work, rt_worker_func);
+static struct delayed_work expires_work;
+static unsigned long expires_ljiffies;
 
 /*
  *     Interface to generic destination cache.
@@ -787,9 +787,12 @@ static void rt_check_expire(void)
        struct rtable *rth, *aux, **rthp;
        unsigned long samples = 0;
        unsigned long sum = 0, sum2 = 0;
+       unsigned long delta;
        u64 mult;
 
-       mult = ((u64)ip_rt_gc_interval) << rt_hash_log;
+       delta = jiffies - expires_ljiffies;
+       expires_ljiffies = jiffies;
+       mult = ((u64)delta) << rt_hash_log;
        if (ip_rt_gc_timeout > 1)
                do_div(mult, ip_rt_gc_timeout);
        goal = (unsigned int)mult;
@@ -3397,6 +3400,8 @@ int __init ip_rt_init(void)
        /* All the timers, started at system startup tend
           to synchronize. Perturb it a bit.
         */
+       INIT_DELAYED_WORK_DEFERRABLE(&expires_work, rt_worker_func);
+       expires_ljiffies = jiffies;
        schedule_delayed_work(&expires_work,
                net_random() % ip_rt_gc_interval + ip_rt_gc_interval);