aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2009-09-20 06:35:36 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-05 03:21:56 -0400
commit16c6cf8bb471392fd09b48b7c27e7d83a446b4bc (patch)
tree6b7c83c37314b54508f6a37613c33610e388d85b /net
parent977750076d98c7ff6cbda51858bb5a5894a9d9ab (diff)
ipv4: fib table algorithm performance improvement
The FIB algorithim for IPV4 is set at compile time, but kernel goes through the overhead of function call indirection at runtime. Save some cycles by turning the indirect calls to direct calls to either hash or trie code. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/fib_frontend.c26
-rw-r--r--net/ipv4/fib_hash.c25
-rw-r--r--net/ipv4/fib_rules.c2
-rw-r--r--net/ipv4/fib_trie.c26
4 files changed, 34 insertions, 45 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index e2f950592566..f73dbed0f0d7 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -125,7 +125,7 @@ void fib_select_default(struct net *net,
125#endif 125#endif
126 tb = fib_get_table(net, table); 126 tb = fib_get_table(net, table);
127 if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) 127 if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
128 tb->tb_select_default(tb, flp, res); 128 fib_table_select_default(tb, flp, res);
129} 129}
130 130
131static void fib_flush(struct net *net) 131static void fib_flush(struct net *net)
@@ -139,7 +139,7 @@ static void fib_flush(struct net *net)
139 for (h = 0; h < FIB_TABLE_HASHSZ; h++) { 139 for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
140 head = &net->ipv4.fib_table_hash[h]; 140 head = &net->ipv4.fib_table_hash[h];
141 hlist_for_each_entry(tb, node, head, tb_hlist) 141 hlist_for_each_entry(tb, node, head, tb_hlist)
142 flushed += tb->tb_flush(tb); 142 flushed += fib_table_flush(tb);
143 } 143 }
144 144
145 if (flushed) 145 if (flushed)
@@ -162,7 +162,7 @@ struct net_device * ip_dev_find(struct net *net, __be32 addr)
162#endif 162#endif
163 163
164 local_table = fib_get_table(net, RT_TABLE_LOCAL); 164 local_table = fib_get_table(net, RT_TABLE_LOCAL);
165 if (!local_table || local_table->tb_lookup(local_table, &fl, &res)) 165 if (!local_table || fib_table_lookup(local_table, &fl, &res))
166 return NULL; 166 return NULL;
167 if (res.type != RTN_LOCAL) 167 if (res.type != RTN_LOCAL)
168 goto out; 168 goto out;
@@ -200,7 +200,7 @@ static inline unsigned __inet_dev_addr_type(struct net *net,
200 local_table = fib_get_table(net, RT_TABLE_LOCAL); 200 local_table = fib_get_table(net, RT_TABLE_LOCAL);
201 if (local_table) { 201 if (local_table) {
202 ret = RTN_UNICAST; 202 ret = RTN_UNICAST;
203 if (!local_table->tb_lookup(local_table, &fl, &res)) { 203 if (!fib_table_lookup(local_table, &fl, &res)) {
204 if (!dev || dev == res.fi->fib_dev) 204 if (!dev || dev == res.fi->fib_dev)
205 ret = res.type; 205 ret = res.type;
206 fib_res_put(&res); 206 fib_res_put(&res);
@@ -473,13 +473,13 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
473 if (cmd == SIOCDELRT) { 473 if (cmd == SIOCDELRT) {
474 tb = fib_get_table(net, cfg.fc_table); 474 tb = fib_get_table(net, cfg.fc_table);
475 if (tb) 475 if (tb)
476 err = tb->tb_delete(tb, &cfg); 476 err = fib_table_delete(tb, &cfg);
477 else 477 else
478 err = -ESRCH; 478 err = -ESRCH;
479 } else { 479 } else {
480 tb = fib_new_table(net, cfg.fc_table); 480 tb = fib_new_table(net, cfg.fc_table);
481 if (tb) 481 if (tb)
482 err = tb->tb_insert(tb, &cfg); 482 err = fib_table_insert(tb, &cfg);
483 else 483 else
484 err = -ENOBUFS; 484 err = -ENOBUFS;
485 } 485 }
@@ -594,7 +594,7 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *ar
594 goto errout; 594 goto errout;
595 } 595 }
596 596
597 err = tb->tb_delete(tb, &cfg); 597 err = fib_table_delete(tb, &cfg);
598errout: 598errout:
599 return err; 599 return err;
600} 600}
@@ -616,7 +616,7 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *ar
616 goto errout; 616 goto errout;
617 } 617 }
618 618
619 err = tb->tb_insert(tb, &cfg); 619 err = fib_table_insert(tb, &cfg);
620errout: 620errout:
621 return err; 621 return err;
622} 622}
@@ -647,7 +647,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
647 if (dumped) 647 if (dumped)
648 memset(&cb->args[2], 0, sizeof(cb->args) - 648 memset(&cb->args[2], 0, sizeof(cb->args) -
649 2 * sizeof(cb->args[0])); 649 2 * sizeof(cb->args[0]));
650 if (tb->tb_dump(tb, skb, cb) < 0) 650 if (fib_table_dump(tb, skb, cb) < 0)
651 goto out; 651 goto out;
652 dumped = 1; 652 dumped = 1;
653next: 653next:
@@ -701,9 +701,9 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad
701 cfg.fc_scope = RT_SCOPE_HOST; 701 cfg.fc_scope = RT_SCOPE_HOST;
702 702
703 if (cmd == RTM_NEWROUTE) 703 if (cmd == RTM_NEWROUTE)
704 tb->tb_insert(tb, &cfg); 704 fib_table_insert(tb, &cfg);
705 else 705 else
706 tb->tb_delete(tb, &cfg); 706 fib_table_delete(tb, &cfg);
707} 707}
708 708
709void fib_add_ifaddr(struct in_ifaddr *ifa) 709void fib_add_ifaddr(struct in_ifaddr *ifa)
@@ -832,7 +832,7 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
832 local_bh_disable(); 832 local_bh_disable();
833 833
834 frn->tb_id = tb->tb_id; 834 frn->tb_id = tb->tb_id;
835 frn->err = tb->tb_lookup(tb, &fl, &res); 835 frn->err = fib_table_lookup(tb, &fl, &res);
836 836
837 if (!frn->err) { 837 if (!frn->err) {
838 frn->prefixlen = res.prefixlen; 838 frn->prefixlen = res.prefixlen;
@@ -1009,7 +1009,7 @@ static void __net_exit ip_fib_net_exit(struct net *net)
1009 head = &net->ipv4.fib_table_hash[i]; 1009 head = &net->ipv4.fib_table_hash[i];
1010 hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) { 1010 hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) {
1011 hlist_del(node); 1011 hlist_del(node);
1012 tb->tb_flush(tb); 1012 fib_table_flush(tb);
1013 kfree(tb); 1013 kfree(tb);
1014 } 1014 }
1015 } 1015 }
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index ecd39454235c..14972017b9c2 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -242,8 +242,8 @@ fn_new_zone(struct fn_hash *table, int z)
242 return fz; 242 return fz;
243} 243}
244 244
245static int 245int fib_table_lookup(struct fib_table *tb,
246fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res) 246 const struct flowi *flp, struct fib_result *res)
247{ 247{
248 int err; 248 int err;
249 struct fn_zone *fz; 249 struct fn_zone *fz;
@@ -274,8 +274,8 @@ out:
274 return err; 274 return err;
275} 275}
276 276
277static void 277void fib_table_select_default(struct fib_table *tb,
278fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res) 278 const struct flowi *flp, struct fib_result *res)
279{ 279{
280 int order, last_idx; 280 int order, last_idx;
281 struct hlist_node *node; 281 struct hlist_node *node;
@@ -366,7 +366,7 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key)
366 return NULL; 366 return NULL;
367} 367}
368 368
369static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) 369int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
370{ 370{
371 struct fn_hash *table = (struct fn_hash *) tb->tb_data; 371 struct fn_hash *table = (struct fn_hash *) tb->tb_data;
372 struct fib_node *new_f = NULL; 372 struct fib_node *new_f = NULL;
@@ -544,8 +544,7 @@ out:
544 return err; 544 return err;
545} 545}
546 546
547 547int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
548static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg)
549{ 548{
550 struct fn_hash *table = (struct fn_hash *)tb->tb_data; 549 struct fn_hash *table = (struct fn_hash *)tb->tb_data;
551 struct fib_node *f; 550 struct fib_node *f;
@@ -662,7 +661,7 @@ static int fn_flush_list(struct fn_zone *fz, int idx)
662 return found; 661 return found;
663} 662}
664 663
665static int fn_hash_flush(struct fib_table *tb) 664int fib_table_flush(struct fib_table *tb)
666{ 665{
667 struct fn_hash *table = (struct fn_hash *) tb->tb_data; 666 struct fn_hash *table = (struct fn_hash *) tb->tb_data;
668 struct fn_zone *fz; 667 struct fn_zone *fz;
@@ -743,7 +742,8 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb,
743 return skb->len; 742 return skb->len;
744} 743}
745 744
746static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) 745int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
746 struct netlink_callback *cb)
747{ 747{
748 int m, s_m; 748 int m, s_m;
749 struct fn_zone *fz; 749 struct fn_zone *fz;
@@ -787,12 +787,7 @@ struct fib_table *fib_hash_table(u32 id)
787 787
788 tb->tb_id = id; 788 tb->tb_id = id;
789 tb->tb_default = -1; 789 tb->tb_default = -1;
790 tb->tb_lookup = fn_hash_lookup; 790
791 tb->tb_insert = fn_hash_insert;
792 tb->tb_delete = fn_hash_delete;
793 tb->tb_flush = fn_hash_flush;
794 tb->tb_select_default = fn_hash_select_default;
795 tb->tb_dump = fn_hash_dump;
796 memset(tb->tb_data, 0, sizeof(struct fn_hash)); 791 memset(tb->tb_data, 0, sizeof(struct fn_hash));
797 return tb; 792 return tb;
798} 793}
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 92d9d97ec5e3..835262c2b867 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -94,7 +94,7 @@ static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp,
94 if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL) 94 if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL)
95 goto errout; 95 goto errout;
96 96
97 err = tbl->tb_lookup(tbl, flp, (struct fib_result *) arg->result); 97 err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result);
98 if (err > 0) 98 if (err > 0)
99 err = -EAGAIN; 99 err = -EAGAIN;
100errout: 100errout:
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 291bdf50a21f..af5d89792860 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1174,7 +1174,7 @@ done:
1174/* 1174/*
1175 * Caller must hold RTNL. 1175 * Caller must hold RTNL.
1176 */ 1176 */
1177static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) 1177int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
1178{ 1178{
1179 struct trie *t = (struct trie *) tb->tb_data; 1179 struct trie *t = (struct trie *) tb->tb_data;
1180 struct fib_alias *fa, *new_fa; 1180 struct fib_alias *fa, *new_fa;
@@ -1373,8 +1373,8 @@ static int check_leaf(struct trie *t, struct leaf *l,
1373 return 1; 1373 return 1;
1374} 1374}
1375 1375
1376static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, 1376int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1377 struct fib_result *res) 1377 struct fib_result *res)
1378{ 1378{
1379 struct trie *t = (struct trie *) tb->tb_data; 1379 struct trie *t = (struct trie *) tb->tb_data;
1380 int ret; 1380 int ret;
@@ -1595,7 +1595,7 @@ static void trie_leaf_remove(struct trie *t, struct leaf *l)
1595/* 1595/*
1596 * Caller must hold RTNL. 1596 * Caller must hold RTNL.
1597 */ 1597 */
1598static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) 1598int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
1599{ 1599{
1600 struct trie *t = (struct trie *) tb->tb_data; 1600 struct trie *t = (struct trie *) tb->tb_data;
1601 u32 key, mask; 1601 u32 key, mask;
@@ -1786,7 +1786,7 @@ static struct leaf *trie_leafindex(struct trie *t, int index)
1786/* 1786/*
1787 * Caller must hold RTNL. 1787 * Caller must hold RTNL.
1788 */ 1788 */
1789static int fn_trie_flush(struct fib_table *tb) 1789int fib_table_flush(struct fib_table *tb)
1790{ 1790{
1791 struct trie *t = (struct trie *) tb->tb_data; 1791 struct trie *t = (struct trie *) tb->tb_data;
1792 struct leaf *l, *ll = NULL; 1792 struct leaf *l, *ll = NULL;
@@ -1807,9 +1807,9 @@ static int fn_trie_flush(struct fib_table *tb)
1807 return found; 1807 return found;
1808} 1808}
1809 1809
1810static void fn_trie_select_default(struct fib_table *tb, 1810void fib_table_select_default(struct fib_table *tb,
1811 const struct flowi *flp, 1811 const struct flowi *flp,
1812 struct fib_result *res) 1812 struct fib_result *res)
1813{ 1813{
1814 struct trie *t = (struct trie *) tb->tb_data; 1814 struct trie *t = (struct trie *) tb->tb_data;
1815 int order, last_idx; 1815 int order, last_idx;
@@ -1952,8 +1952,8 @@ static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
1952 return skb->len; 1952 return skb->len;
1953} 1953}
1954 1954
1955static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb, 1955int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
1956 struct netlink_callback *cb) 1956 struct netlink_callback *cb)
1957{ 1957{
1958 struct leaf *l; 1958 struct leaf *l;
1959 struct trie *t = (struct trie *) tb->tb_data; 1959 struct trie *t = (struct trie *) tb->tb_data;
@@ -2020,12 +2020,6 @@ struct fib_table *fib_hash_table(u32 id)
2020 2020
2021 tb->tb_id = id; 2021 tb->tb_id = id;
2022 tb->tb_default = -1; 2022 tb->tb_default = -1;
2023 tb->tb_lookup = fn_trie_lookup;
2024 tb->tb_insert = fn_trie_insert;
2025 tb->tb_delete = fn_trie_delete;
2026 tb->tb_flush = fn_trie_flush;
2027 tb->tb_select_default = fn_trie_select_default;
2028 tb->tb_dump = fn_trie_dump;
2029 2023
2030 t = (struct trie *) tb->tb_data; 2024 t = (struct trie *) tb->tb_data;
2031 memset(t, 0, sizeof(*t)); 2025 memset(t, 0, sizeof(*t));