aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@redhat.com>2015-02-25 18:31:31 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-27 16:37:06 -0500
commit56315f9e6e3a0ba0483c2e1f53333d5275268cb1 (patch)
tree2fd33299033b341fc9b655a9f35b3e86dc09b09a /net/ipv4/fib_trie.c
parent7705f730372d65f73599f0b49e3249433bba55e8 (diff)
fib_trie: Convert fib_alias to hlist from list
There isn't any advantage to having it as a list and by making it an hlist we make the fib_alias more compatible with the list_info in terms of the type of list used. Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.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.c80
1 files changed, 44 insertions, 36 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 3daf0224ff2e..f17e2239b7b9 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -116,7 +116,7 @@ struct leaf_info {
116 struct hlist_node hlist; 116 struct hlist_node hlist;
117 int plen; 117 int plen;
118 u32 mask_plen; /* ntohl(inet_make_mask(plen)) */ 118 u32 mask_plen; /* ntohl(inet_make_mask(plen)) */
119 struct list_head falh; 119 struct hlist_head falh;
120 struct rcu_head rcu; 120 struct rcu_head rcu;
121}; 121};
122 122
@@ -339,7 +339,7 @@ static struct leaf_info *leaf_info_new(int plen)
339 if (li) { 339 if (li) {
340 li->plen = plen; 340 li->plen = plen;
341 li->mask_plen = ntohl(inet_make_mask(plen)); 341 li->mask_plen = ntohl(inet_make_mask(plen));
342 INIT_LIST_HEAD(&li->falh); 342 INIT_HLIST_HEAD(&li->falh);
343 } 343 }
344 return li; 344 return li;
345} 345}
@@ -881,7 +881,7 @@ static struct leaf_info *find_leaf_info(struct tnode *l, int plen)
881 return NULL; 881 return NULL;
882} 882}
883 883
884static inline struct list_head *get_fa_head(struct tnode *l, int plen) 884static inline struct hlist_head *get_fa_head(struct tnode *l, int plen)
885{ 885{
886 struct leaf_info *li = find_leaf_info(l, plen); 886 struct leaf_info *li = find_leaf_info(l, plen);
887 887
@@ -994,14 +994,15 @@ static struct tnode *fib_find_node(struct trie *t, u32 key)
994/* Return the first fib alias matching TOS with 994/* Return the first fib alias matching TOS with
995 * priority less than or equal to PRIO. 995 * priority less than or equal to PRIO.
996 */ 996 */
997static struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio) 997static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 tos,
998 u32 prio)
998{ 999{
999 struct fib_alias *fa; 1000 struct fib_alias *fa;
1000 1001
1001 if (!fah) 1002 if (!fah)
1002 return NULL; 1003 return NULL;
1003 1004
1004 list_for_each_entry(fa, fah, fa_list) { 1005 hlist_for_each_entry(fa, fah, fa_list) {
1005 if (fa->fa_tos > tos) 1006 if (fa->fa_tos > tos)
1006 continue; 1007 continue;
1007 if (fa->fa_info->fib_priority >= prio || fa->fa_tos < tos) 1008 if (fa->fa_info->fib_priority >= prio || fa->fa_tos < tos)
@@ -1027,9 +1028,9 @@ static void trie_rebalance(struct trie *t, struct tnode *tn)
1027 1028
1028/* only used from updater-side */ 1029/* only used from updater-side */
1029 1030
1030static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) 1031static struct hlist_head *fib_insert_node(struct trie *t, u32 key, int plen)
1031{ 1032{
1032 struct list_head *fa_head = NULL; 1033 struct hlist_head *fa_head = NULL;
1033 struct tnode *l, *n, *tp = NULL; 1034 struct tnode *l, *n, *tp = NULL;
1034 struct leaf_info *li; 1035 struct leaf_info *li;
1035 1036
@@ -1130,7 +1131,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
1130{ 1131{
1131 struct trie *t = (struct trie *) tb->tb_data; 1132 struct trie *t = (struct trie *) tb->tb_data;
1132 struct fib_alias *fa, *new_fa; 1133 struct fib_alias *fa, *new_fa;
1133 struct list_head *fa_head = NULL; 1134 struct hlist_head *fa_head = NULL;
1134 struct fib_info *fi; 1135 struct fib_info *fi;
1135 int plen = cfg->fc_dst_len; 1136 int plen = cfg->fc_dst_len;
1136 u8 tos = cfg->fc_tos; 1137 u8 tos = cfg->fc_tos;
@@ -1171,10 +1172,8 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
1171 * exists or to the node before which we will insert new one. 1172 * exists or to the node before which we will insert new one.
1172 * 1173 *
1173 * If fa is NULL, we will need to allocate a new one and 1174 * If fa is NULL, we will need to allocate a new one and
1174 * insert to the head of f. 1175 * insert to the tail of the section matching the suffix length
1175 * 1176 * of the new alias.
1176 * If f is NULL, no fib node matched the destination key
1177 * and we need to allocate a new one of those as well.
1178 */ 1177 */
1179 1178
1180 if (fa && fa->fa_tos == tos && 1179 if (fa && fa->fa_tos == tos &&
@@ -1192,8 +1191,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
1192 */ 1191 */
1193 fa_match = NULL; 1192 fa_match = NULL;
1194 fa_first = fa; 1193 fa_first = fa;
1195 fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); 1194 hlist_for_each_entry_from(fa, fa_list) {
1196 list_for_each_entry_continue(fa, fa_head, fa_list) {
1197 if (fa->fa_tos != tos) 1195 if (fa->fa_tos != tos)
1198 break; 1196 break;
1199 if (fa->fa_info->fib_priority != fi->fib_priority) 1197 if (fa->fa_info->fib_priority != fi->fib_priority)
@@ -1227,7 +1225,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
1227 state = fa->fa_state; 1225 state = fa->fa_state;
1228 new_fa->fa_state = state & ~FA_S_ACCESSED; 1226 new_fa->fa_state = state & ~FA_S_ACCESSED;
1229 1227
1230 list_replace_rcu(&fa->fa_list, &new_fa->fa_list); 1228 hlist_replace_rcu(&fa->fa_list, &new_fa->fa_list);
1231 alias_free_mem_rcu(fa); 1229 alias_free_mem_rcu(fa);
1232 1230
1233 fib_release_info(fi_drop); 1231 fib_release_info(fi_drop);
@@ -1276,8 +1274,19 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
1276 if (!plen) 1274 if (!plen)
1277 tb->tb_num_default++; 1275 tb->tb_num_default++;
1278 1276
1279 list_add_tail_rcu(&new_fa->fa_list, 1277 if (fa) {
1280 (fa ? &fa->fa_list : fa_head)); 1278 hlist_add_before_rcu(&new_fa->fa_list, &fa->fa_list);
1279 } else {
1280 struct fib_alias *last;
1281
1282 hlist_for_each_entry(last, fa_head, fa_list)
1283 fa = last;
1284
1285 if (fa)
1286 hlist_add_behind_rcu(&new_fa->fa_list, &fa->fa_list);
1287 else
1288 hlist_add_head_rcu(&new_fa->fa_list, fa_head);
1289 }
1281 1290
1282 rt_cache_flush(cfg->fc_nlinfo.nl_net); 1291 rt_cache_flush(cfg->fc_nlinfo.nl_net);
1283 rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, 1292 rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
@@ -1419,7 +1428,7 @@ found:
1419 if ((key ^ n->key) & li->mask_plen) 1428 if ((key ^ n->key) & li->mask_plen)
1420 continue; 1429 continue;
1421 1430
1422 list_for_each_entry_rcu(fa, &li->falh, fa_list) { 1431 hlist_for_each_entry_rcu(fa, &li->falh, fa_list) {
1423 struct fib_info *fi = fa->fa_info; 1432 struct fib_info *fi = fa->fa_info;
1424 int nhsel, err; 1433 int nhsel, err;
1425 1434
@@ -1501,7 +1510,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
1501 int plen = cfg->fc_dst_len; 1510 int plen = cfg->fc_dst_len;
1502 u8 tos = cfg->fc_tos; 1511 u8 tos = cfg->fc_tos;
1503 struct fib_alias *fa, *fa_to_delete; 1512 struct fib_alias *fa, *fa_to_delete;
1504 struct list_head *fa_head; 1513 struct hlist_head *fa_head;
1505 struct tnode *l; 1514 struct tnode *l;
1506 struct leaf_info *li; 1515 struct leaf_info *li;
1507 1516
@@ -1534,8 +1543,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
1534 pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t); 1543 pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
1535 1544
1536 fa_to_delete = NULL; 1545 fa_to_delete = NULL;
1537 fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); 1546 hlist_for_each_entry_from(fa, fa_list) {
1538 list_for_each_entry_continue(fa, fa_head, fa_list) {
1539 struct fib_info *fi = fa->fa_info; 1547 struct fib_info *fi = fa->fa_info;
1540 1548
1541 if (fa->fa_tos != tos) 1549 if (fa->fa_tos != tos)
@@ -1561,12 +1569,12 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
1561 rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, 1569 rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id,
1562 &cfg->fc_nlinfo, 0); 1570 &cfg->fc_nlinfo, 0);
1563 1571
1564 list_del_rcu(&fa->fa_list); 1572 hlist_del_rcu(&fa->fa_list);
1565 1573
1566 if (!plen) 1574 if (!plen)
1567 tb->tb_num_default--; 1575 tb->tb_num_default--;
1568 1576
1569 if (list_empty(fa_head)) { 1577 if (hlist_empty(fa_head)) {
1570 remove_leaf_info(l, li); 1578 remove_leaf_info(l, li);
1571 free_leaf_info(li); 1579 free_leaf_info(li);
1572 } 1580 }
@@ -1582,16 +1590,17 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
1582 return 0; 1590 return 0;
1583} 1591}
1584 1592
1585static int trie_flush_list(struct list_head *head) 1593static int trie_flush_list(struct hlist_head *head)
1586{ 1594{
1587 struct fib_alias *fa, *fa_node; 1595 struct hlist_node *tmp;
1596 struct fib_alias *fa;
1588 int found = 0; 1597 int found = 0;
1589 1598
1590 list_for_each_entry_safe(fa, fa_node, head, fa_list) { 1599 hlist_for_each_entry_safe(fa, tmp, head, fa_list) {
1591 struct fib_info *fi = fa->fa_info; 1600 struct fib_info *fi = fa->fa_info;
1592 1601
1593 if (fi && (fi->fib_flags & RTNH_F_DEAD)) { 1602 if (fi && (fi->fib_flags & RTNH_F_DEAD)) {
1594 list_del_rcu(&fa->fa_list); 1603 hlist_del_rcu(&fa->fa_list);
1595 fib_release_info(fa->fa_info); 1604 fib_release_info(fa->fa_info);
1596 alias_free_mem_rcu(fa); 1605 alias_free_mem_rcu(fa);
1597 found++; 1606 found++;
@@ -1603,15 +1612,14 @@ static int trie_flush_list(struct list_head *head)
1603static int trie_flush_leaf(struct tnode *l) 1612static int trie_flush_leaf(struct tnode *l)
1604{ 1613{
1605 int found = 0; 1614 int found = 0;
1606 struct hlist_head *lih = &l->list;
1607 struct hlist_node *tmp; 1615 struct hlist_node *tmp;
1608 struct leaf_info *li = NULL; 1616 struct leaf_info *li;
1609 unsigned char plen = KEYLENGTH; 1617 unsigned char plen = KEYLENGTH;
1610 1618
1611 hlist_for_each_entry_safe(li, tmp, lih, hlist) { 1619 hlist_for_each_entry_safe(li, tmp, &l->list, hlist) {
1612 found += trie_flush_list(&li->falh); 1620 found += trie_flush_list(&li->falh);
1613 1621
1614 if (list_empty(&li->falh)) { 1622 if (hlist_empty(&li->falh)) {
1615 hlist_del_rcu(&li->hlist); 1623 hlist_del_rcu(&li->hlist);
1616 free_leaf_info(li); 1624 free_leaf_info(li);
1617 continue; 1625 continue;
@@ -1731,7 +1739,7 @@ void fib_free_table(struct fib_table *tb)
1731 kfree(tb); 1739 kfree(tb);
1732} 1740}
1733 1741
1734static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, 1742static int fn_trie_dump_fa(t_key key, int plen, struct hlist_head *fah,
1735 struct fib_table *tb, 1743 struct fib_table *tb,
1736 struct sk_buff *skb, struct netlink_callback *cb) 1744 struct sk_buff *skb, struct netlink_callback *cb)
1737{ 1745{
@@ -1744,7 +1752,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
1744 1752
1745 /* rcu_read_lock is hold by caller */ 1753 /* rcu_read_lock is hold by caller */
1746 1754
1747 list_for_each_entry_rcu(fa, fah, fa_list) { 1755 hlist_for_each_entry_rcu(fa, fah, fa_list) {
1748 if (i < s_i) { 1756 if (i < s_i) {
1749 i++; 1757 i++;
1750 continue; 1758 continue;
@@ -1787,7 +1795,7 @@ static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb,
1787 if (i > s_i) 1795 if (i > s_i)
1788 cb->args[5] = 0; 1796 cb->args[5] = 0;
1789 1797
1790 if (list_empty(&li->falh)) 1798 if (hlist_empty(&li->falh))
1791 continue; 1799 continue;
1792 1800
1793 if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 0) { 1801 if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 0) {
@@ -2272,7 +2280,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
2272 hlist_for_each_entry_rcu(li, &n->list, hlist) { 2280 hlist_for_each_entry_rcu(li, &n->list, hlist) {
2273 struct fib_alias *fa; 2281 struct fib_alias *fa;
2274 2282
2275 list_for_each_entry_rcu(fa, &li->falh, fa_list) { 2283 hlist_for_each_entry_rcu(fa, &li->falh, fa_list) {
2276 char buf1[32], buf2[32]; 2284 char buf1[32], buf2[32];
2277 2285
2278 seq_indent(seq, iter->depth+1); 2286 seq_indent(seq, iter->depth+1);
@@ -2429,7 +2437,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
2429 mask = inet_make_mask(li->plen); 2437 mask = inet_make_mask(li->plen);
2430 prefix = htonl(l->key); 2438 prefix = htonl(l->key);
2431 2439
2432 list_for_each_entry_rcu(fa, &li->falh, fa_list) { 2440 hlist_for_each_entry_rcu(fa, &li->falh, fa_list) {
2433 const struct fib_info *fi = fa->fa_info; 2441 const struct fib_info *fi = fa->fa_info;
2434 unsigned int flags = fib_flag_trans(fa->fa_type, mask, fi); 2442 unsigned int flags = fib_flag_trans(fa->fa_type, mask, fi);
2435 2443