ipv4: Inline fib_semantic_match into check_leaf

This elimiates a lot of pure overhead due to parameter
passing.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2011-03-07 15:01:10 -08:00
parent 4c8237cd76
commit 3be0686b6e
3 changed files with 51 additions and 75 deletions

View File

@@ -1349,23 +1349,58 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
struct hlist_node *node;
hlist_for_each_entry_rcu(li, node, hhead, hlist) {
int err;
struct fib_alias *fa;
int plen = li->plen;
__be32 mask = inet_make_mask(plen);
if (l->key != (key & ntohl(mask)))
continue;
err = fib_semantic_match(tb, &li->falh, flp, res, plen, fib_flags);
list_for_each_entry_rcu(fa, &li->falh, fa_list) {
struct fib_info *fi = fa->fa_info;
int nhsel, err;
if (fa->fa_tos && fa->fa_tos != flp->fl4_tos)
continue;
if (fa->fa_scope < flp->fl4_scope)
continue;
fib_alias_accessed(fa);
err = fib_props[fa->fa_type].error;
if (err) {
#ifdef CONFIG_IP_FIB_TRIE_STATS
t->stats.semantic_match_miss++;
#endif
return 1;
}
if (fi->fib_flags & RTNH_F_DEAD)
continue;
for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
const struct fib_nh *nh = &fi->fib_nh[nhsel];
if (nh->nh_flags & RTNH_F_DEAD)
continue;
if (flp->oif && flp->oif != nh->nh_oif)
continue;
#ifdef CONFIG_IP_FIB_TRIE_STATS
if (err <= 0)
t->stats.semantic_match_passed++;
else
t->stats.semantic_match_miss++;
t->stats.semantic_match_passed++;
#endif
res->prefixlen = plen;
res->nh_sel = nhsel;
res->type = fa->fa_type;
res->scope = fa->fa_scope;
res->fi = fi;
res->table = tb;
res->fa_head = &li->falh;
if (!(fib_flags & FIB_LOOKUP_NOREF))
atomic_inc(&res->fi->fib_clntref);
return 0;
}
}
#ifdef CONFIG_IP_FIB_TRIE_STATS
t->stats.semantic_match_miss++;
#endif
if (err <= 0)
return err;
}
return 1;