Skip to content

Commit 16c6cf8

Browse files
Stephen Hemmingerdavem330
authored andcommitted
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>
1 parent 9777500 commit 16c6cf8

File tree

5 files changed

+48
-56
lines changed

5 files changed

+48
-56
lines changed

include/net/ip_fib.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,21 @@ struct fib_table {
144144
struct hlist_node tb_hlist;
145145
u32 tb_id;
146146
int tb_default;
147-
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
148-
int (*tb_insert)(struct fib_table *, struct fib_config *);
149-
int (*tb_delete)(struct fib_table *, struct fib_config *);
150-
int (*tb_dump)(struct fib_table *table, struct sk_buff *skb,
151-
struct netlink_callback *cb);
152-
int (*tb_flush)(struct fib_table *table);
153-
void (*tb_select_default)(struct fib_table *table,
154-
const struct flowi *flp, struct fib_result *res);
155-
156147
unsigned char tb_data[0];
157148
};
158149

150+
extern int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
151+
struct fib_result *res);
152+
extern int fib_table_insert(struct fib_table *, struct fib_config *);
153+
extern int fib_table_delete(struct fib_table *, struct fib_config *);
154+
extern int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
155+
struct netlink_callback *cb);
156+
extern int fib_table_flush(struct fib_table *table);
157+
extern void fib_table_select_default(struct fib_table *table,
158+
const struct flowi *flp,
159+
struct fib_result *res);
160+
161+
159162
#ifndef CONFIG_IP_MULTIPLE_TABLES
160163

161164
#define TABLE_LOCAL_INDEX 0
@@ -182,11 +185,11 @@ static inline int fib_lookup(struct net *net, const struct flowi *flp,
182185
struct fib_table *table;
183186

184187
table = fib_get_table(net, RT_TABLE_LOCAL);
185-
if (!table->tb_lookup(table, flp, res))
188+
if (!fib_table_lookup(table, flp, res))
186189
return 0;
187190

188191
table = fib_get_table(net, RT_TABLE_MAIN);
189-
if (!table->tb_lookup(table, flp, res))
192+
if (!fib_table_lookup(table, flp, res))
190193
return 0;
191194
return -ENETUNREACH;
192195
}

net/ipv4/fib_frontend.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ void fib_select_default(struct net *net,
125125
#endif
126126
tb = fib_get_table(net, table);
127127
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);
129129
}
130130

131131
static void fib_flush(struct net *net)
@@ -139,7 +139,7 @@ static void fib_flush(struct net *net)
139139
for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
140140
head = &net->ipv4.fib_table_hash[h];
141141
hlist_for_each_entry(tb, node, head, tb_hlist)
142-
flushed += tb->tb_flush(tb);
142+
flushed += fib_table_flush(tb);
143143
}
144144

145145
if (flushed)
@@ -162,7 +162,7 @@ struct net_device * ip_dev_find(struct net *net, __be32 addr)
162162
#endif
163163

164164
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))
166166
return NULL;
167167
if (res.type != RTN_LOCAL)
168168
goto out;
@@ -200,7 +200,7 @@ static inline unsigned __inet_dev_addr_type(struct net *net,
200200
local_table = fib_get_table(net, RT_TABLE_LOCAL);
201201
if (local_table) {
202202
ret = RTN_UNICAST;
203-
if (!local_table->tb_lookup(local_table, &fl, &res)) {
203+
if (!fib_table_lookup(local_table, &fl, &res)) {
204204
if (!dev || dev == res.fi->fib_dev)
205205
ret = res.type;
206206
fib_res_put(&res);
@@ -473,13 +473,13 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
473473
if (cmd == SIOCDELRT) {
474474
tb = fib_get_table(net, cfg.fc_table);
475475
if (tb)
476-
err = tb->tb_delete(tb, &cfg);
476+
err = fib_table_delete(tb, &cfg);
477477
else
478478
err = -ESRCH;
479479
} else {
480480
tb = fib_new_table(net, cfg.fc_table);
481481
if (tb)
482-
err = tb->tb_insert(tb, &cfg);
482+
err = fib_table_insert(tb, &cfg);
483483
else
484484
err = -ENOBUFS;
485485
}
@@ -594,7 +594,7 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *ar
594594
goto errout;
595595
}
596596

597-
err = tb->tb_delete(tb, &cfg);
597+
err = fib_table_delete(tb, &cfg);
598598
errout:
599599
return err;
600600
}
@@ -616,7 +616,7 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *ar
616616
goto errout;
617617
}
618618

619-
err = tb->tb_insert(tb, &cfg);
619+
err = fib_table_insert(tb, &cfg);
620620
errout:
621621
return err;
622622
}
@@ -647,7 +647,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
647647
if (dumped)
648648
memset(&cb->args[2], 0, sizeof(cb->args) -
649649
2 * sizeof(cb->args[0]));
650-
if (tb->tb_dump(tb, skb, cb) < 0)
650+
if (fib_table_dump(tb, skb, cb) < 0)
651651
goto out;
652652
dumped = 1;
653653
next:
@@ -701,9 +701,9 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad
701701
cfg.fc_scope = RT_SCOPE_HOST;
702702

703703
if (cmd == RTM_NEWROUTE)
704-
tb->tb_insert(tb, &cfg);
704+
fib_table_insert(tb, &cfg);
705705
else
706-
tb->tb_delete(tb, &cfg);
706+
fib_table_delete(tb, &cfg);
707707
}
708708

709709
void 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 )
832832
local_bh_disable();
833833

834834
frn->tb_id = tb->tb_id;
835-
frn->err = tb->tb_lookup(tb, &fl, &res);
835+
frn->err = fib_table_lookup(tb, &fl, &res);
836836

837837
if (!frn->err) {
838838
frn->prefixlen = res.prefixlen;
@@ -1009,7 +1009,7 @@ static void __net_exit ip_fib_net_exit(struct net *net)
10091009
head = &net->ipv4.fib_table_hash[i];
10101010
hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) {
10111011
hlist_del(node);
1012-
tb->tb_flush(tb);
1012+
fib_table_flush(tb);
10131013
kfree(tb);
10141014
}
10151015
}

net/ipv4/fib_hash.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ fn_new_zone(struct fn_hash *table, int z)
242242
return fz;
243243
}
244244

245-
static int
246-
fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
245+
int fib_table_lookup(struct fib_table *tb,
246+
const struct flowi *flp, struct fib_result *res)
247247
{
248248
int err;
249249
struct fn_zone *fz;
@@ -274,8 +274,8 @@ fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
274274
return err;
275275
}
276276

277-
static void
278-
fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
277+
void fib_table_select_default(struct fib_table *tb,
278+
const struct flowi *flp, struct fib_result *res)
279279
{
280280
int order, last_idx;
281281
struct hlist_node *node;
@@ -366,7 +366,7 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key)
366366
return NULL;
367367
}
368368

369-
static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
369+
int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
370370
{
371371
struct fn_hash *table = (struct fn_hash *) tb->tb_data;
372372
struct fib_node *new_f = NULL;
@@ -544,8 +544,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
544544
return err;
545545
}
546546

547-
548-
static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg)
547+
int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
549548
{
550549
struct fn_hash *table = (struct fn_hash *)tb->tb_data;
551550
struct fib_node *f;
@@ -662,7 +661,7 @@ static int fn_flush_list(struct fn_zone *fz, int idx)
662661
return found;
663662
}
664663

665-
static int fn_hash_flush(struct fib_table *tb)
664+
int fib_table_flush(struct fib_table *tb)
666665
{
667666
struct fn_hash *table = (struct fn_hash *) tb->tb_data;
668667
struct fn_zone *fz;
@@ -743,7 +742,8 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb,
743742
return skb->len;
744743
}
745744

746-
static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb)
745+
int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
746+
struct netlink_callback *cb)
747747
{
748748
int m, s_m;
749749
struct fn_zone *fz;
@@ -787,12 +787,7 @@ struct fib_table *fib_hash_table(u32 id)
787787

788788
tb->tb_id = id;
789789
tb->tb_default = -1;
790-
tb->tb_lookup = fn_hash_lookup;
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;
790+
796791
memset(tb->tb_data, 0, sizeof(struct fn_hash));
797792
return tb;
798793
}

net/ipv4/fib_rules.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp,
9494
if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL)
9595
goto errout;
9696

97-
err = tbl->tb_lookup(tbl, flp, (struct fib_result *) arg->result);
97+
err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result);
9898
if (err > 0)
9999
err = -EAGAIN;
100100
errout:

net/ipv4/fib_trie.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
11741174
/*
11751175
* Caller must hold RTNL.
11761176
*/
1177-
static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
1177+
int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
11781178
{
11791179
struct trie *t = (struct trie *) tb->tb_data;
11801180
struct fib_alias *fa, *new_fa;
@@ -1373,8 +1373,8 @@ static int check_leaf(struct trie *t, struct leaf *l,
13731373
return 1;
13741374
}
13751375

1376-
static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
1377-
struct fib_result *res)
1376+
int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1377+
struct fib_result *res)
13781378
{
13791379
struct trie *t = (struct trie *) tb->tb_data;
13801380
int ret;
@@ -1595,7 +1595,7 @@ static void trie_leaf_remove(struct trie *t, struct leaf *l)
15951595
/*
15961596
* Caller must hold RTNL.
15971597
*/
1598-
static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
1598+
int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
15991599
{
16001600
struct trie *t = (struct trie *) tb->tb_data;
16011601
u32 key, mask;
@@ -1786,7 +1786,7 @@ static struct leaf *trie_leafindex(struct trie *t, int index)
17861786
/*
17871787
* Caller must hold RTNL.
17881788
*/
1789-
static int fn_trie_flush(struct fib_table *tb)
1789+
int fib_table_flush(struct fib_table *tb)
17901790
{
17911791
struct trie *t = (struct trie *) tb->tb_data;
17921792
struct leaf *l, *ll = NULL;
@@ -1807,9 +1807,9 @@ static int fn_trie_flush(struct fib_table *tb)
18071807
return found;
18081808
}
18091809

1810-
static void fn_trie_select_default(struct fib_table *tb,
1811-
const struct flowi *flp,
1812-
struct fib_result *res)
1810+
void fib_table_select_default(struct fib_table *tb,
1811+
const struct flowi *flp,
1812+
struct fib_result *res)
18131813
{
18141814
struct trie *t = (struct trie *) tb->tb_data;
18151815
int order, last_idx;
@@ -1952,8 +1952,8 @@ static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
19521952
return skb->len;
19531953
}
19541954

1955-
static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb,
1956-
struct netlink_callback *cb)
1955+
int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
1956+
struct netlink_callback *cb)
19571957
{
19581958
struct leaf *l;
19591959
struct trie *t = (struct trie *) tb->tb_data;
@@ -2020,12 +2020,6 @@ struct fib_table *fib_hash_table(u32 id)
20202020

20212021
tb->tb_id = id;
20222022
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;
20292023

20302024
t = (struct trie *) tb->tb_data;
20312025
memset(t, 0, sizeof(*t));

0 commit comments

Comments
 (0)