Commit 7197ce26 authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by David S. Miller

[IPV4]: More sane rtcache behavior.

1) More reasonable ip_rt_gc_min_interval default
2) Trim less valuable entries in hash chain during
   rt_intern_hash when such chains grow too long.
parent 3eef54d7
......@@ -111,7 +111,7 @@ int ip_rt_max_delay = 10 * HZ;
int ip_rt_max_size;
int ip_rt_gc_timeout = RT_GC_TIMEOUT;
int ip_rt_gc_interval = 60 * HZ;
int ip_rt_gc_min_interval = 5 * HZ;
int ip_rt_gc_min_interval = HZ / 2;
int ip_rt_redirect_number = 9;
int ip_rt_redirect_load = HZ / 50;
int ip_rt_redirect_silence = ((HZ / 50) << (9 + 1));
......@@ -456,6 +456,25 @@ static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long t
out: return ret;
}
/* Bits of score are:
* 31: very valuable
* 30: not quite useless
* 29..0: usage counter
*/
static inline u32 rt_score(struct rtable *rt)
{
u32 score = rt->u.dst.__use;
if (rt_valuable(rt))
score |= (1<<31);
if (!rt->fl.iif ||
!(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL)))
score |= (1<<30);
return score;
}
/* This runs via a timer and thus is always in BH context. */
static void rt_check_expire(unsigned long dummy)
{
......@@ -721,6 +740,9 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
{
struct rtable *rth, **rthp;
unsigned long now = jiffies;
struct rtable *cand = NULL, **candp = NULL;
u32 min_score = ~(u32)0;
int chain_length = 0;
int attempts = !in_softirq();
restart:
......@@ -755,9 +777,35 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
return 0;
}
if (!atomic_read(&rth->u.dst.__refcnt)) {
u32 score = rt_score(rth);
if (score <= min_score) {
cand = rth;
candp = rthp;
min_score = score;
}
}
chain_length++;
rthp = &rth->u.rt_next;
}
if (cand) {
/* ip_rt_gc_elasticity used to be average length of chain
* length, when exceeded gc becomes really aggressive.
*
* The second limit is less certain. At the moment it allows
* only 2 entries per bucket. We will see.
*/
if (chain_length > ip_rt_gc_elasticity ||
(chain_length > 1 && !(min_score & (1<<31)))) {
*candp = cand->u.rt_next;
rt_free(cand);
}
}
/* Try to bind route to arp only if it is output
route or unicast forwarding path.
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment