aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/fib_trie.c100
1 files changed, 65 insertions, 35 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 80892f565030..f874e1811eab 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -83,7 +83,8 @@
83 83
84#define MAX_STAT_DEPTH 32 84#define MAX_STAT_DEPTH 32
85 85
86#define KEYLENGTH (8*sizeof(t_key)) 86#define KEYLENGTH (8*sizeof(t_key))
87#define KEY_MAX ((t_key)~0)
87 88
88typedef unsigned int t_key; 89typedef unsigned int t_key;
89 90
@@ -102,8 +103,8 @@ struct tnode {
102 union { 103 union {
103 /* The fields in this struct are valid if bits > 0 (TNODE) */ 104 /* The fields in this struct are valid if bits > 0 (TNODE) */
104 struct { 105 struct {
105 unsigned int full_children; /* KEYLENGTH bits needed */ 106 t_key empty_children; /* KEYLENGTH bits needed */
106 unsigned int empty_children; /* KEYLENGTH bits needed */ 107 t_key full_children; /* KEYLENGTH bits needed */
107 struct tnode __rcu *child[0]; 108 struct tnode __rcu *child[0];
108 }; 109 };
109 /* This list pointer if valid if bits == 0 (LEAF) */ 110 /* This list pointer if valid if bits == 0 (LEAF) */
@@ -302,6 +303,16 @@ static struct tnode *tnode_alloc(size_t size)
302 return vzalloc(size); 303 return vzalloc(size);
303} 304}
304 305
306static inline void empty_child_inc(struct tnode *n)
307{
308 ++n->empty_children ? : ++n->full_children;
309}
310
311static inline void empty_child_dec(struct tnode *n)
312{
313 n->empty_children-- ? : n->full_children--;
314}
315
305static struct tnode *leaf_new(t_key key) 316static struct tnode *leaf_new(t_key key)
306{ 317{
307 struct tnode *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL); 318 struct tnode *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL);
@@ -335,7 +346,7 @@ static struct leaf_info *leaf_info_new(int plen)
335 346
336static struct tnode *tnode_new(t_key key, int pos, int bits) 347static struct tnode *tnode_new(t_key key, int pos, int bits)
337{ 348{
338 size_t sz = offsetof(struct tnode, child[1 << bits]); 349 size_t sz = offsetof(struct tnode, child[1ul << bits]);
339 struct tnode *tn = tnode_alloc(sz); 350 struct tnode *tn = tnode_alloc(sz);
340 unsigned int shift = pos + bits; 351 unsigned int shift = pos + bits;
341 352
@@ -348,8 +359,10 @@ static struct tnode *tnode_new(t_key key, int pos, int bits)
348 tn->pos = pos; 359 tn->pos = pos;
349 tn->bits = bits; 360 tn->bits = bits;
350 tn->key = (shift < KEYLENGTH) ? (key >> shift) << shift : 0; 361 tn->key = (shift < KEYLENGTH) ? (key >> shift) << shift : 0;
351 tn->full_children = 0; 362 if (bits == KEYLENGTH)
352 tn->empty_children = 1<<bits; 363 tn->full_children = 1;
364 else
365 tn->empty_children = 1ul << bits;
353 } 366 }
354 367
355 pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode), 368 pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode),
@@ -375,11 +388,11 @@ static void put_child(struct tnode *tn, unsigned long i, struct tnode *n)
375 388
376 BUG_ON(i >= tnode_child_length(tn)); 389 BUG_ON(i >= tnode_child_length(tn));
377 390
378 /* update emptyChildren */ 391 /* update emptyChildren, overflow into fullChildren */
379 if (n == NULL && chi != NULL) 392 if (n == NULL && chi != NULL)
380 tn->empty_children++; 393 empty_child_inc(tn);
381 else if (n != NULL && chi == NULL) 394 if (n != NULL && chi == NULL)
382 tn->empty_children--; 395 empty_child_dec(tn);
383 396
384 /* update fullChildren */ 397 /* update fullChildren */
385 wasfull = tnode_full(tn, chi); 398 wasfull = tnode_full(tn, chi);
@@ -630,6 +643,24 @@ static int halve(struct trie *t, struct tnode *oldtnode)
630 return 0; 643 return 0;
631} 644}
632 645
646static void collapse(struct trie *t, struct tnode *oldtnode)
647{
648 struct tnode *n, *tp;
649 unsigned long i;
650
651 /* scan the tnode looking for that one child that might still exist */
652 for (n = NULL, i = tnode_child_length(oldtnode); !n && i;)
653 n = tnode_get_child(oldtnode, --i);
654
655 /* compress one level */
656 tp = node_parent(oldtnode);
657 put_child_root(tp, t, oldtnode->key, n);
658 node_set_parent(n, tp);
659
660 /* drop dead node */
661 node_free(oldtnode);
662}
663
633static unsigned char update_suffix(struct tnode *tn) 664static unsigned char update_suffix(struct tnode *tn)
634{ 665{
635 unsigned char slen = tn->pos; 666 unsigned char slen = tn->pos;
@@ -729,10 +760,12 @@ static bool should_inflate(const struct tnode *tp, const struct tnode *tn)
729 760
730 /* Keep root node larger */ 761 /* Keep root node larger */
731 threshold *= tp ? inflate_threshold : inflate_threshold_root; 762 threshold *= tp ? inflate_threshold : inflate_threshold_root;
732 used += tn->full_children;
733 used -= tn->empty_children; 763 used -= tn->empty_children;
764 used += tn->full_children;
734 765
735 return tn->pos && ((50 * used) >= threshold); 766 /* if bits == KEYLENGTH then pos = 0, and will fail below */
767
768 return (used > 1) && tn->pos && ((50 * used) >= threshold);
736} 769}
737 770
738static bool should_halve(const struct tnode *tp, const struct tnode *tn) 771static bool should_halve(const struct tnode *tp, const struct tnode *tn)
@@ -744,13 +777,29 @@ static bool should_halve(const struct tnode *tp, const struct tnode *tn)
744 threshold *= tp ? halve_threshold : halve_threshold_root; 777 threshold *= tp ? halve_threshold : halve_threshold_root;
745 used -= tn->empty_children; 778 used -= tn->empty_children;
746 779
747 return (tn->bits > 1) && ((100 * used) < threshold); 780 /* if bits == KEYLENGTH then used = 100% on wrap, and will fail below */
781
782 return (used > 1) && (tn->bits > 1) && ((100 * used) < threshold);
783}
784
785static bool should_collapse(const struct tnode *tn)
786{
787 unsigned long used = tnode_child_length(tn);
788
789 used -= tn->empty_children;
790
791 /* account for bits == KEYLENGTH case */
792 if ((tn->bits == KEYLENGTH) && tn->full_children)
793 used -= KEY_MAX;
794
795 /* One child or none, time to drop us from the trie */
796 return used < 2;
748} 797}
749 798
750#define MAX_WORK 10 799#define MAX_WORK 10
751static void resize(struct trie *t, struct tnode *tn) 800static void resize(struct trie *t, struct tnode *tn)
752{ 801{
753 struct tnode *tp = node_parent(tn), *n = NULL; 802 struct tnode *tp = node_parent(tn);
754 struct tnode __rcu **cptr; 803 struct tnode __rcu **cptr;
755 int max_work = MAX_WORK; 804 int max_work = MAX_WORK;
756 805
@@ -764,14 +813,6 @@ static void resize(struct trie *t, struct tnode *tn)
764 cptr = tp ? &tp->child[get_index(tn->key, tp)] : &t->trie; 813 cptr = tp ? &tp->child[get_index(tn->key, tp)] : &t->trie;
765 BUG_ON(tn != rtnl_dereference(*cptr)); 814 BUG_ON(tn != rtnl_dereference(*cptr));
766 815
767 /* No children */
768 if (tn->empty_children > (tnode_child_length(tn) - 1))
769 goto no_children;
770
771 /* One child */
772 if (tn->empty_children == (tnode_child_length(tn) - 1))
773 goto one_child;
774
775 /* Double as long as the resulting node has a number of 816 /* Double as long as the resulting node has a number of
776 * nonempty nodes that are above the threshold. 817 * nonempty nodes that are above the threshold.
777 */ 818 */
@@ -807,19 +848,8 @@ static void resize(struct trie *t, struct tnode *tn)
807 } 848 }
808 849
809 /* Only one child remains */ 850 /* Only one child remains */
810 if (tn->empty_children == (tnode_child_length(tn) - 1)) { 851 if (should_collapse(tn)) {
811 unsigned long i; 852 collapse(t, tn);
812one_child:
813 for (i = tnode_child_length(tn); !n && i;)
814 n = tnode_get_child(tn, --i);
815no_children:
816 /* compress one level */
817 put_child_root(tp, t, tn->key, n);
818 node_set_parent(n, tp);
819
820 /* drop dead node */
821 tnode_free_init(tn);
822 tnode_free(tn);
823 return; 853 return;
824 } 854 }
825 855