Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8d3f099abe25c21670cb5728178a1f286952782d
Commit:     8d3f099abe25c21670cb5728178a1f286952782d
Parent:     49d85c502ec5e6d5998c1a04394c5b24e8f7d32d
Author:     Eric Dumazet <[EMAIL PROTECTED]>
AuthorDate: Fri Jan 18 04:30:21 2008 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Sun Jan 20 20:31:39 2008 -0800

    [IPV4] FIB_HASH : Avoid unecessary loop in fn_hash_dump_zone()
    
    I noticed "ip route list" was slower than "cat /proc/net/route" on a
    machine with a full Internet routing table (214392 entries : Special
    thanks to Robert ;) )
    
    This is similar to problem reported in commit
    d8c9283089287341c85a0a69de32c2287a990e71 ("[IPV4] ROUTE: ip_rt_dump()
    is unecessary slow")
    
    Fix is to avoid scanning the begining of fz_hash table, but directly
    seek to the right offset.
    
    Before patch :
    
    time ip route >/tmp/ROUTE
    
    real    0m1.285s
    user    0m0.712s
    sys     0m0.436s
    
    After patch
    
    # time ip route >/tmp/ROUTE
    
    real    0m0.835s
    user    0m0.692s
    sys     0m0.124s
    
    Signed-off-by: Eric Dumazet <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/ipv4/fib_hash.c |   20 +++++++++-----------
 1 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 99071d7..0dfee27 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -721,19 +721,18 @@ fn_hash_dump_zone(struct sk_buff *skb, struct 
netlink_callback *cb,
 {
        int h, s_h;
 
+       if (fz->fz_hash == NULL)
+               return skb->len;
        s_h = cb->args[3];
-       for (h=0; h < fz->fz_divisor; h++) {
-               if (h < s_h) continue;
-               if (h > s_h)
-                       memset(&cb->args[4], 0,
-                              sizeof(cb->args) - 4*sizeof(cb->args[0]));
-               if (fz->fz_hash == NULL ||
-                   hlist_empty(&fz->fz_hash[h]))
+       for (h = s_h; h < fz->fz_divisor; h++) {
+               if (hlist_empty(&fz->fz_hash[h]))
                        continue;
-               if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h])<0) {
+               if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h]) < 0) {
                        cb->args[3] = h;
                        return -1;
                }
+               memset(&cb->args[4], 0,
+                      sizeof(cb->args) - 4*sizeof(cb->args[0]));
        }
        cb->args[3] = h;
        return skb->len;
@@ -749,14 +748,13 @@ static int fn_hash_dump(struct fib_table *tb, struct 
sk_buff *skb, struct netlin
        read_lock(&fib_hash_lock);
        for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) {
                if (m < s_m) continue;
-               if (m > s_m)
-                       memset(&cb->args[3], 0,
-                              sizeof(cb->args) - 3*sizeof(cb->args[0]));
                if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) {
                        cb->args[2] = m;
                        read_unlock(&fib_hash_lock);
                        return -1;
                }
+               memset(&cb->args[3], 0,
+                      sizeof(cb->args) - 3*sizeof(cb->args[0]));
        }
        read_unlock(&fib_hash_lock);
        cb->args[2] = m;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to