aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_trie.c')
-rw-r--r--net/ipv4/fib_trie.c72
1 files changed, 41 insertions, 31 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 1b63b4824164..0093ea08c7f5 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -43,7 +43,7 @@
43 * 2 of the License, or (at your option) any later version. 43 * 2 of the License, or (at your option) any later version.
44 */ 44 */
45 45
46#define VERSION "0.403" 46#define VERSION "0.404"
47 47
48#include <linux/config.h> 48#include <linux/config.h>
49#include <asm/uaccess.h> 49#include <asm/uaccess.h>
@@ -224,7 +224,7 @@ static inline int tkey_mismatch(t_key a, int offset, t_key b)
224 Consider a node 'n' and its parent 'tp'. 224 Consider a node 'n' and its parent 'tp'.
225 225
226 If n is a leaf, every bit in its key is significant. Its presence is 226 If n is a leaf, every bit in its key is significant. Its presence is
227 necessitaded by path compression, since during a tree traversal (when 227 necessitated by path compression, since during a tree traversal (when
228 searching for a leaf - unless we are doing an insertion) we will completely 228 searching for a leaf - unless we are doing an insertion) we will completely
229 ignore all skipped bits we encounter. Thus we need to verify, at the end of 229 ignore all skipped bits we encounter. Thus we need to verify, at the end of
230 a potentially successful search, that we have indeed been walking the 230 a potentially successful search, that we have indeed been walking the
@@ -286,6 +286,8 @@ static inline void check_tnode(const struct tnode *tn)
286 286
287static int halve_threshold = 25; 287static int halve_threshold = 25;
288static int inflate_threshold = 50; 288static int inflate_threshold = 50;
289static int halve_threshold_root = 15;
290static int inflate_threshold_root = 25;
289 291
290 292
291static void __alias_free_mem(struct rcu_head *head) 293static void __alias_free_mem(struct rcu_head *head)
@@ -449,6 +451,8 @@ static struct node *resize(struct trie *t, struct tnode *tn)
449 int i; 451 int i;
450 int err = 0; 452 int err = 0;
451 struct tnode *old_tn; 453 struct tnode *old_tn;
454 int inflate_threshold_use;
455 int halve_threshold_use;
452 456
453 if (!tn) 457 if (!tn)
454 return NULL; 458 return NULL;
@@ -541,10 +545,17 @@ static struct node *resize(struct trie *t, struct tnode *tn)
541 545
542 check_tnode(tn); 546 check_tnode(tn);
543 547
548 /* Keep root node larger */
549
550 if(!tn->parent)
551 inflate_threshold_use = inflate_threshold_root;
552 else
553 inflate_threshold_use = inflate_threshold;
554
544 err = 0; 555 err = 0;
545 while ((tn->full_children > 0 && 556 while ((tn->full_children > 0 &&
546 50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >= 557 50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
547 inflate_threshold * tnode_child_length(tn))) { 558 inflate_threshold_use * tnode_child_length(tn))) {
548 559
549 old_tn = tn; 560 old_tn = tn;
550 tn = inflate(t, tn); 561 tn = inflate(t, tn);
@@ -564,10 +575,18 @@ static struct node *resize(struct trie *t, struct tnode *tn)
564 * node is above threshold. 575 * node is above threshold.
565 */ 576 */
566 577
578
579 /* Keep root node larger */
580
581 if(!tn->parent)
582 halve_threshold_use = halve_threshold_root;
583 else
584 halve_threshold_use = halve_threshold;
585
567 err = 0; 586 err = 0;
568 while (tn->bits > 1 && 587 while (tn->bits > 1 &&
569 100 * (tnode_child_length(tn) - tn->empty_children) < 588 100 * (tnode_child_length(tn) - tn->empty_children) <
570 halve_threshold * tnode_child_length(tn)) { 589 halve_threshold_use * tnode_child_length(tn)) {
571 590
572 old_tn = tn; 591 old_tn = tn;
573 tn = halve(t, tn); 592 tn = halve(t, tn);
@@ -836,11 +855,12 @@ static void trie_init(struct trie *t)
836#endif 855#endif
837} 856}
838 857
839/* readside most use rcu_read_lock currently dump routines 858/* readside must use rcu_read_lock currently dump routines
840 via get_fa_head and dump */ 859 via get_fa_head and dump */
841 860
842static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen) 861static struct leaf_info *find_leaf_info(struct leaf *l, int plen)
843{ 862{
863 struct hlist_head *head = &l->list;
844 struct hlist_node *node; 864 struct hlist_node *node;
845 struct leaf_info *li; 865 struct leaf_info *li;
846 866
@@ -853,7 +873,7 @@ static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)
853 873
854static inline struct list_head * get_fa_head(struct leaf *l, int plen) 874static inline struct list_head * get_fa_head(struct leaf *l, int plen)
855{ 875{
856 struct leaf_info *li = find_leaf_info(&l->list, plen); 876 struct leaf_info *li = find_leaf_info(l, plen);
857 877
858 if (!li) 878 if (!li)
859 return NULL; 879 return NULL;
@@ -1085,7 +1105,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
1085 } 1105 }
1086 1106
1087 if (tp && tp->pos + tp->bits > 32) 1107 if (tp && tp->pos + tp->bits > 32)
1088 printk("ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d\n", 1108 printk(KERN_WARNING "fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
1089 tp, tp->pos, tp->bits, key, plen); 1109 tp, tp->pos, tp->bits, key, plen);
1090 1110
1091 /* Rebalance the trie */ 1111 /* Rebalance the trie */
@@ -1248,7 +1268,7 @@ err:
1248} 1268}
1249 1269
1250 1270
1251/* should be clalled with rcu_read_lock */ 1271/* should be called with rcu_read_lock */
1252static inline int check_leaf(struct trie *t, struct leaf *l, 1272static inline int check_leaf(struct trie *t, struct leaf *l,
1253 t_key key, int *plen, const struct flowi *flp, 1273 t_key key, int *plen, const struct flowi *flp,
1254 struct fib_result *res) 1274 struct fib_result *res)
@@ -1590,7 +1610,7 @@ fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
1590 rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req); 1610 rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req);
1591 1611
1592 l = fib_find_node(t, key); 1612 l = fib_find_node(t, key);
1593 li = find_leaf_info(&l->list, plen); 1613 li = find_leaf_info(l, plen);
1594 1614
1595 list_del_rcu(&fa->fa_list); 1615 list_del_rcu(&fa->fa_list);
1596 1616
@@ -1714,7 +1734,6 @@ static int fn_trie_flush(struct fib_table *tb)
1714 1734
1715 t->revision++; 1735 t->revision++;
1716 1736
1717 rcu_read_lock();
1718 for (h = 0; (l = nextleaf(t, l)) != NULL; h++) { 1737 for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {
1719 found += trie_flush_leaf(t, l); 1738 found += trie_flush_leaf(t, l);
1720 1739
@@ -1722,7 +1741,6 @@ static int fn_trie_flush(struct fib_table *tb)
1722 trie_leaf_remove(t, ll->key); 1741 trie_leaf_remove(t, ll->key);
1723 ll = l; 1742 ll = l;
1724 } 1743 }
1725 rcu_read_unlock();
1726 1744
1727 if (ll && hlist_empty(&ll->list)) 1745 if (ll && hlist_empty(&ll->list))
1728 trie_leaf_remove(t, ll->key); 1746 trie_leaf_remove(t, ll->key);
@@ -1833,16 +1851,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
1833 i++; 1851 i++;
1834 continue; 1852 continue;
1835 } 1853 }
1836 if (fa->fa_info->fib_nh == NULL) { 1854 BUG_ON(!fa->fa_info);
1837 printk("Trie error _fib_nh=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
1838 i++;
1839 continue;
1840 }
1841 if (fa->fa_info == NULL) {
1842 printk("Trie error fa_info=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
1843 i++;
1844 continue;
1845 }
1846 1855
1847 if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid, 1856 if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
1848 cb->nlh->nlmsg_seq, 1857 cb->nlh->nlmsg_seq,
@@ -1965,7 +1974,7 @@ struct fib_table * __init fib_hash_init(int id)
1965 trie_main = t; 1974 trie_main = t;
1966 1975
1967 if (id == RT_TABLE_LOCAL) 1976 if (id == RT_TABLE_LOCAL)
1968 printk("IPv4 FIB: Using LC-trie version %s\n", VERSION); 1977 printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
1969 1978
1970 return tb; 1979 return tb;
1971} 1980}
@@ -2029,7 +2038,7 @@ static struct node *fib_trie_get_first(struct fib_trie_iter *iter,
2029 iter->tnode = (struct tnode *) n; 2038 iter->tnode = (struct tnode *) n;
2030 iter->trie = t; 2039 iter->trie = t;
2031 iter->index = 0; 2040 iter->index = 0;
2032 iter->depth = 0; 2041 iter->depth = 1;
2033 return n; 2042 return n;
2034 } 2043 }
2035 return NULL; 2044 return NULL;
@@ -2274,11 +2283,12 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
2274 seq_puts(seq, "<local>:\n"); 2283 seq_puts(seq, "<local>:\n");
2275 else 2284 else
2276 seq_puts(seq, "<main>:\n"); 2285 seq_puts(seq, "<main>:\n");
2277 } else { 2286 }
2278 seq_indent(seq, iter->depth-1); 2287 seq_indent(seq, iter->depth-1);
2279 seq_printf(seq, " +-- %d.%d.%d.%d/%d\n", 2288 seq_printf(seq, " +-- %d.%d.%d.%d/%d %d %d %d\n",
2280 NIPQUAD(prf), tn->pos); 2289 NIPQUAD(prf), tn->pos, tn->bits, tn->full_children,
2281 } 2290 tn->empty_children);
2291
2282 } else { 2292 } else {
2283 struct leaf *l = (struct leaf *) n; 2293 struct leaf *l = (struct leaf *) n;
2284 int i; 2294 int i;
@@ -2287,7 +2297,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
2287 seq_indent(seq, iter->depth); 2297 seq_indent(seq, iter->depth);
2288 seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val)); 2298 seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val));
2289 for (i = 32; i >= 0; i--) { 2299 for (i = 32; i >= 0; i--) {
2290 struct leaf_info *li = find_leaf_info(&l->list, i); 2300 struct leaf_info *li = find_leaf_info(l, i);
2291 if (li) { 2301 if (li) {
2292 struct fib_alias *fa; 2302 struct fib_alias *fa;
2293 list_for_each_entry_rcu(fa, &li->falh, fa_list) { 2303 list_for_each_entry_rcu(fa, &li->falh, fa_list) {
@@ -2383,7 +2393,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
2383 return 0; 2393 return 0;
2384 2394
2385 for (i=32; i>=0; i--) { 2395 for (i=32; i>=0; i--) {
2386 struct leaf_info *li = find_leaf_info(&l->list, i); 2396 struct leaf_info *li = find_leaf_info(l, i);
2387 struct fib_alias *fa; 2397 struct fib_alias *fa;
2388 u32 mask, prefix; 2398 u32 mask, prefix;
2389 2399