diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-07-18 03:16:33 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-18 10:41:18 -0700 |
commit | 5c74501f76360ce6f410730b9b5e5976f38e8504 (patch) | |
tree | 4965fe06affeaa121afa4a18b0644cbeb9e7d639 /net | |
parent | d3aaeb38c40e5a6c08dd31a1b64da65c4352be36 (diff) | |
download | linux-5c74501f76360ce6f410730b9b5e5976f38e8504.tar.bz2 |
ipv4: save cpu cycles from check_leaf()
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/fib_trie.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 58c25ea5a5c1..de9e2978476f 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -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; } } |