Subject: Re: [IPV4] ROUTE: ip_rt_dump() is unecessary slow

From: Eric Dumazet <[email-masked]>
Date: Tue, 08 Jan 2008 07:11:30 +0100

David Miller a écrit :
> From: Eric Dumazet <[email-masked]>
> Date: Mon, 7 Jan 2008 19:30:02 +0100
> 
>> I noticed "ip route list cache x.y.z.t" can be *very* slow.
>>
>> While strace-ing -T it I also noticed that first part of route cache is
>> fetched quite fast :
>  ...
>> The following patch corrects this performance/latency problem, removing quadratic behavior.
>>
>> Signed-off-by: Eric Dumazet <[email-masked]>
> 
> I think removing quadratic behavior is a bug fix, thus applied
> to net-2.6, thanks Eric :-)

You are the boss :)

I had another patch to submit, so I based it no net-2.6, please just say me if 
you prefer a net-2/6.25 one, as it's not a critical bug fix...

Thank you

[IPV4] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache

Signed-off-by: Eric Dumazet <[email-masked]>

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d337706..3b7562f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -278,7 +278,7 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq)
 
 	for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
 		rcu_read_lock_bh();
-		r = rt_hash_table[st->bucket].chain;
+		r = rcu_dereference(rt_hash_table[st->bucket].chain);
 		if (r)
 			break;
 		rcu_read_unlock_bh();
@@ -288,15 +288,15 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq)
 
 static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
 {
-	struct rt_cache_iter_state *st = rcu_dereference(seq->private);
+	struct rt_cache_iter_state *st = seq->private;
 
-	r = r->u.dst.rt_next;
+	r = rcu_dereference(r->u.dst.rt_next);
 	while (!r) {
 		rcu_read_unlock_bh();
 		if (--st->bucket < 0)
 			break;
 		rcu_read_lock_bh();
-		r = rt_hash_table[st->bucket].chain;
+		r = rcu_dereference(rt_hash_table[st->bucket].chain);
 	}
 	return r;
 }