aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-07-17 23:16:33 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-18 13:41:18 -0400
commit5c74501f76360ce6f410730b9b5e5976f38e8504 (patch)
tree4965fe06affeaa121afa4a18b0644cbeb9e7d639 /net/ipv4/fib_trie.c
parentd3aaeb38c40e5a6c08dd31a1b64da65c4352be36 (diff)
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/ipv4/fib_trie.c')
-rw-r--r--net/ipv4/fib_trie.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 58c25ea5a5c..de9e2978476 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -110,9 +110,10 @@ struct leaf {
110 110
111struct leaf_info { 111struct leaf_info {
112 struct hlist_node hlist; 112 struct hlist_node hlist;
113 struct rcu_head rcu;
114 int plen; 113 int plen;
114 u32 mask_plen; /* ntohl(inet_make_mask(plen)) */
115 struct list_head falh; 115 struct list_head falh;
116 struct rcu_head rcu;
116}; 117};
117 118
118struct tnode { 119struct tnode {
@@ -451,6 +452,7 @@ static struct leaf_info *leaf_info_new(int plen)
451 struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); 452 struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL);
452 if (li) { 453 if (li) {
453 li->plen = plen; 454 li->plen = plen;
455 li->mask_plen = ntohl(inet_make_mask(plen));
454 INIT_LIST_HEAD(&li->falh); 456 INIT_LIST_HEAD(&li->falh);
455 } 457 }
456 return li; 458 return li;
@@ -1359,10 +1361,8 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
1359 1361
1360 hlist_for_each_entry_rcu(li, node, hhead, hlist) { 1362 hlist_for_each_entry_rcu(li, node, hhead, hlist) {
1361 struct fib_alias *fa; 1363 struct fib_alias *fa;
1362 int plen = li->plen;
1363 __be32 mask = inet_make_mask(plen);
1364 1364
1365 if (l->key != (key & ntohl(mask))) 1365 if (l->key != (key & li->mask_plen))
1366 continue; 1366 continue;
1367 1367
1368 list_for_each_entry_rcu(fa, &li->falh, fa_list) { 1368 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,
1394#ifdef CONFIG_IP_FIB_TRIE_STATS 1394#ifdef CONFIG_IP_FIB_TRIE_STATS
1395 t->stats.semantic_match_passed++; 1395 t->stats.semantic_match_passed++;
1396#endif 1396#endif
1397 res->prefixlen = plen; 1397 res->prefixlen = li->plen;
1398 res->nh_sel = nhsel; 1398 res->nh_sel = nhsel;
1399 res->type = fa->fa_type; 1399 res->type = fa->fa_type;
1400 res->scope = fa->fa_info->fib_scope; 1400 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,
1402 res->table = tb; 1402 res->table = tb;
1403 res->fa_head = &li->falh; 1403 res->fa_head = &li->falh;
1404 if (!(fib_flags & FIB_LOOKUP_NOREF)) 1404 if (!(fib_flags & FIB_LOOKUP_NOREF))
1405 atomic_inc(&res->fi->fib_clntref); 1405 atomic_inc(&fi->fib_clntref);
1406 return 0; 1406 return 0;
1407 } 1407 }
1408 } 1408 }