aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@redhat.com>2015-01-22 18:51:26 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-25 17:47:16 -0500
commit95f60ea3e99aef5967d1566979f4ade7be386e34 (patch)
treee4e0bf113455421a25f11275f25a9bf0dda2aae8 /net/ipv4/fib_trie.c
parenta80e89d4c650a7c3ab74f0b2d133cc2ce9738994 (diff)
fib_trie: Add collapse() and should_collapse() to resize
This patch really does two things. First it pulls the logic for determining if we should collapse one node out of the tree and the actual code doing the collapse into a separate pair of functions. This helps to make the changes to these areas more readable. Second it encodes the upper 32b of the empty_children value onto the full_children value in the case of bits == KEYLENGTH. By doing this we are able to handle the case of a 32b node where empty_children would appear to be 0 when it was actually 1ul << 32. 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.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