diff options
author | Alexander Duyck <alexander.h.duyck@redhat.com> | 2015-02-25 18:31:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-27 16:37:06 -0500 |
commit | 56315f9e6e3a0ba0483c2e1f53333d5275268cb1 (patch) | |
tree | 2fd33299033b341fc9b655a9f35b3e86dc09b09a | |
parent | 7705f730372d65f73599f0b49e3249433bba55e8 (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>
-rw-r--r-- | include/net/ip_fib.h | 2 | ||||
-rw-r--r-- | net/ipv4/fib_lookup.h | 2 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 4 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 80 |
4 files changed, 48 insertions, 40 deletions
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 5bd120e4bc0a..cba4b7c32935 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h | |||
@@ -136,7 +136,7 @@ struct fib_result { | |||
136 | u32 tclassid; | 136 | u32 tclassid; |
137 | struct fib_info *fi; | 137 | struct fib_info *fi; |
138 | struct fib_table *table; | 138 | struct fib_table *table; |
139 | struct list_head *fa_head; | 139 | struct hlist_head *fa_head; |
140 | }; | 140 | }; |
141 | 141 | ||
142 | struct fib_result_nl { | 142 | struct fib_result_nl { |
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 825981b1049a..3cd444f4e0f6 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h | |||
@@ -6,7 +6,7 @@ | |||
6 | #include <net/ip_fib.h> | 6 | #include <net/ip_fib.h> |
7 | 7 | ||
8 | struct fib_alias { | 8 | struct fib_alias { |
9 | struct list_head fa_list; | 9 | struct hlist_node fa_list; |
10 | struct fib_info *fa_info; | 10 | struct fib_info *fa_info; |
11 | u8 fa_tos; | 11 | u8 fa_tos; |
12 | u8 fa_type; | 12 | u8 fa_type; |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 1e2090ea663e..c6d267442dac 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -1163,12 +1163,12 @@ int fib_sync_down_dev(struct net_device *dev, int force) | |||
1163 | void fib_select_default(struct fib_result *res) | 1163 | void fib_select_default(struct fib_result *res) |
1164 | { | 1164 | { |
1165 | struct fib_info *fi = NULL, *last_resort = NULL; | 1165 | struct fib_info *fi = NULL, *last_resort = NULL; |
1166 | struct list_head *fa_head = res->fa_head; | 1166 | struct hlist_head *fa_head = res->fa_head; |
1167 | struct fib_table *tb = res->table; | 1167 | struct fib_table *tb = res->table; |
1168 | int order = -1, last_idx = -1; | 1168 | int order = -1, last_idx = -1; |
1169 | struct fib_alias *fa; | 1169 | struct fib_alias *fa; |
1170 | 1170 | ||
1171 | list_for_each_entry_rcu(fa, fa_head, fa_list) { | 1171 | hlist_for_each_entry_rcu(fa, fa_head, fa_list) { |
1172 | struct fib_info *next_fi = fa->fa_info; | 1172 | struct fib_info *next_fi = fa->fa_info; |
1173 | 1173 | ||
1174 | if (next_fi->fib_scope != res->scope || | 1174 | if (next_fi->fib_scope != res->scope || |
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 | ||
884 | static inline struct list_head *get_fa_head(struct tnode *l, int plen) | 884 | static 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 | */ |
997 | static struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio) | 997 | static 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 | ||
1030 | static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) | 1031 | static 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 | ||
1585 | static int trie_flush_list(struct list_head *head) | 1593 | static 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) | |||
1603 | static int trie_flush_leaf(struct tnode *l) | 1612 | static 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 | ||
1734 | static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, | 1742 | static 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 | ||