ipv4: save cpu cycles from check_leaf()
authorEric Dumazet <eric.dumazet@gmail.com>
Mon, 18 Jul 2011 03:16:33 +0000 (03:16 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 18 Jul 2011 17:41:18 +0000 (10:41 -0700)
Compiler is not smart enough to avoid double BSWAP instructions in
ntohl(inet_make_mask(plen)).

Lets cache this value in struct leaf_info, (fill a hole on 64bit arches)

With route cache disabled, this saves ~2% of cpu in udpflood bench on
x86_64 machine.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/fib_trie.c

index 58c25ea..de9e297 100644 (file)
@@ -110,9 +110,10 @@ struct leaf {
 
 struct leaf_info {
        struct hlist_node hlist;
-       struct rcu_head rcu;
        int plen;
+       u32 mask_plen; /* ntohl(inet_make_mask(plen)) */
        struct list_head falh;
+       struct rcu_head rcu;
 };
 
 struct tnode {
@@ -451,6 +452,7 @@ static struct leaf_info *leaf_info_new(int plen)
        struct leaf_info *li = kmalloc(sizeof(struct leaf_info),  GFP_KERNEL);
        if (li) {
                li->plen = plen;
+               li->mask_plen = ntohl(inet_make_mask(plen));
                INIT_LIST_HEAD(&li->falh);
        }
        return li;
@@ -1359,10 +1361,8 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
 
        hlist_for_each_entry_rcu(li, node, hhead, hlist) {
                struct fib_alias *fa;
-               int plen = li->plen;
-               __be32 mask = inet_make_mask(plen);
 
-               if (l->key != (key & ntohl(mask)))
+               if (l->key != (key & li->mask_plen))
                        continue;
 
                list_for_each_entry_rcu(fa, &li->falh, fa_list) {
@@ -1394,7 +1394,7 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
 #ifdef CONFIG_IP_FIB_TRIE_STATS
                                t->stats.semantic_match_passed++;
 #endif
-                               res->prefixlen = plen;
+                               res->prefixlen = li->plen;
                                res->nh_sel = nhsel;
                                res->type = fa->fa_type;
                                res->scope = fa->fa_info->fib_scope;
@@ -1402,7 +1402,7 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
                                res->table = tb;
                                res->fa_head = &li->falh;
                                if (!(fib_flags & FIB_LOOKUP_NOREF))
-                                       atomic_inc(&res->fi->fib_clntref);
+                                       atomic_inc(&fi->fib_clntref);
                                return 0;
                        }
                }