diff options
author | Alexander Duyck <alexander.h.duyck@redhat.com> | 2014-12-31 13:56:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-31 18:25:54 -0500 |
commit | f05a48198bf742efd9d36553c51e98a648dbe807 (patch) | |
tree | b507ffa2ec5a895c13733063725d6b6153976138 | |
parent | cf3637bb8f07fb3b6791708f1d5118afb5446061 (diff) |
fib_trie: Add functions should_inflate and should_halve
This change pulls the logic for if we should inflate/halve the nodes out
into separate functions. It also addresses what I believe is a bug where 1
full node is all that is needed to keep a node from ever being halved.
Simple script to reproduce the issue:
modprobe dummy; ifconfig dummy0 up
for i in `seq 0 255`; do ifconfig dummy0:$i 10.0.${i}.1/24 up; done
ifconfig dummy0:256 10.0.255.33/16 up
for i in `seq 0 254`; do ifconfig dummy0:$i down; done
Results from /proc/net/fib_triestat
Before:
Local:
Aver depth: 3.00
Max depth: 4
Leaves: 17
Prefixes: 18
Internal nodes: 11
1: 8 2: 2 10: 1
Pointers: 1048
Null ptrs: 1021
Total size: 11 kB
After:
Local:
Aver depth: 3.41
Max depth: 5
Leaves: 17
Prefixes: 18
Internal nodes: 12
1: 8 2: 3 3: 1
Pointers: 36
Null ptrs: 8
Total size: 3 kB
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/fib_trie.c | 175 |
1 files changed, 89 insertions, 86 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index d044fa355f69..58e1224786fa 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -647,12 +647,94 @@ nomem: | |||
647 | return ERR_PTR(-ENOMEM); | 647 | return ERR_PTR(-ENOMEM); |
648 | } | 648 | } |
649 | 649 | ||
650 | /* From "Implementing a dynamic compressed trie" by Stefan Nilsson of | ||
651 | * the Helsinki University of Technology and Matti Tikkanen of Nokia | ||
652 | * Telecommunications, page 6: | ||
653 | * "A node is doubled if the ratio of non-empty children to all | ||
654 | * children in the *doubled* node is at least 'high'." | ||
655 | * | ||
656 | * 'high' in this instance is the variable 'inflate_threshold'. It | ||
657 | * is expressed as a percentage, so we multiply it with | ||
658 | * tnode_child_length() and instead of multiplying by 2 (since the | ||
659 | * child array will be doubled by inflate()) and multiplying | ||
660 | * the left-hand side by 100 (to handle the percentage thing) we | ||
661 | * multiply the left-hand side by 50. | ||
662 | * | ||
663 | * The left-hand side may look a bit weird: tnode_child_length(tn) | ||
664 | * - tn->empty_children is of course the number of non-null children | ||
665 | * in the current node. tn->full_children is the number of "full" | ||
666 | * children, that is non-null tnodes with a skip value of 0. | ||
667 | * All of those will be doubled in the resulting inflated tnode, so | ||
668 | * we just count them one extra time here. | ||
669 | * | ||
670 | * A clearer way to write this would be: | ||
671 | * | ||
672 | * to_be_doubled = tn->full_children; | ||
673 | * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - | ||
674 | * tn->full_children; | ||
675 | * | ||
676 | * new_child_length = tnode_child_length(tn) * 2; | ||
677 | * | ||
678 | * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / | ||
679 | * new_child_length; | ||
680 | * if (new_fill_factor >= inflate_threshold) | ||
681 | * | ||
682 | * ...and so on, tho it would mess up the while () loop. | ||
683 | * | ||
684 | * anyway, | ||
685 | * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= | ||
686 | * inflate_threshold | ||
687 | * | ||
688 | * avoid a division: | ||
689 | * 100 * (not_to_be_doubled + 2*to_be_doubled) >= | ||
690 | * inflate_threshold * new_child_length | ||
691 | * | ||
692 | * expand not_to_be_doubled and to_be_doubled, and shorten: | ||
693 | * 100 * (tnode_child_length(tn) - tn->empty_children + | ||
694 | * tn->full_children) >= inflate_threshold * new_child_length | ||
695 | * | ||
696 | * expand new_child_length: | ||
697 | * 100 * (tnode_child_length(tn) - tn->empty_children + | ||
698 | * tn->full_children) >= | ||
699 | * inflate_threshold * tnode_child_length(tn) * 2 | ||
700 | * | ||
701 | * shorten again: | ||
702 | * 50 * (tn->full_children + tnode_child_length(tn) - | ||
703 | * tn->empty_children) >= inflate_threshold * | ||
704 | * tnode_child_length(tn) | ||
705 | * | ||
706 | */ | ||
707 | static bool should_inflate(const struct tnode *tn) | ||
708 | { | ||
709 | unsigned long used = tnode_child_length(tn); | ||
710 | unsigned long threshold = used; | ||
711 | |||
712 | /* Keep root node larger */ | ||
713 | threshold *= node_parent(tn) ? inflate_threshold : | ||
714 | inflate_threshold_root; | ||
715 | used += tn->full_children; | ||
716 | used -= tn->empty_children; | ||
717 | |||
718 | return tn->pos && ((50 * used) >= threshold); | ||
719 | } | ||
720 | |||
721 | static bool should_halve(const struct tnode *tn) | ||
722 | { | ||
723 | unsigned long used = tnode_child_length(tn); | ||
724 | unsigned long threshold = used; | ||
725 | |||
726 | /* Keep root node larger */ | ||
727 | threshold *= node_parent(tn) ? halve_threshold : | ||
728 | halve_threshold_root; | ||
729 | used -= tn->empty_children; | ||
730 | |||
731 | return (tn->bits > 1) && ((100 * used) < threshold); | ||
732 | } | ||
733 | |||
650 | #define MAX_WORK 10 | 734 | #define MAX_WORK 10 |
651 | static struct tnode *resize(struct trie *t, struct tnode *tn) | 735 | static struct tnode *resize(struct trie *t, struct tnode *tn) |
652 | { | 736 | { |
653 | struct tnode *old_tn, *n = NULL; | 737 | struct tnode *old_tn, *n = NULL; |
654 | int inflate_threshold_use; | ||
655 | int halve_threshold_use; | ||
656 | int max_work; | 738 | int max_work; |
657 | 739 | ||
658 | if (!tn) | 740 | if (!tn) |
@@ -668,86 +750,12 @@ static struct tnode *resize(struct trie *t, struct tnode *tn) | |||
668 | /* One child */ | 750 | /* One child */ |
669 | if (tn->empty_children == (tnode_child_length(tn) - 1)) | 751 | if (tn->empty_children == (tnode_child_length(tn) - 1)) |
670 | goto one_child; | 752 | goto one_child; |
671 | /* | ||
672 | * Double as long as the resulting node has a number of | ||
673 | * nonempty nodes that are above the threshold. | ||
674 | */ | ||
675 | 753 | ||
676 | /* | 754 | /* Double as long as the resulting node has a number of |
677 | * From "Implementing a dynamic compressed trie" by Stefan Nilsson of | 755 | * nonempty nodes that are above the threshold. |
678 | * the Helsinki University of Technology and Matti Tikkanen of Nokia | ||
679 | * Telecommunications, page 6: | ||
680 | * "A node is doubled if the ratio of non-empty children to all | ||
681 | * children in the *doubled* node is at least 'high'." | ||
682 | * | ||
683 | * 'high' in this instance is the variable 'inflate_threshold'. It | ||
684 | * is expressed as a percentage, so we multiply it with | ||
685 | * tnode_child_length() and instead of multiplying by 2 (since the | ||
686 | * child array will be doubled by inflate()) and multiplying | ||
687 | * the left-hand side by 100 (to handle the percentage thing) we | ||
688 | * multiply the left-hand side by 50. | ||
689 | * | ||
690 | * The left-hand side may look a bit weird: tnode_child_length(tn) | ||
691 | * - tn->empty_children is of course the number of non-null children | ||
692 | * in the current node. tn->full_children is the number of "full" | ||
693 | * children, that is non-null tnodes with a skip value of 0. | ||
694 | * All of those will be doubled in the resulting inflated tnode, so | ||
695 | * we just count them one extra time here. | ||
696 | * | ||
697 | * A clearer way to write this would be: | ||
698 | * | ||
699 | * to_be_doubled = tn->full_children; | ||
700 | * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - | ||
701 | * tn->full_children; | ||
702 | * | ||
703 | * new_child_length = tnode_child_length(tn) * 2; | ||
704 | * | ||
705 | * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / | ||
706 | * new_child_length; | ||
707 | * if (new_fill_factor >= inflate_threshold) | ||
708 | * | ||
709 | * ...and so on, tho it would mess up the while () loop. | ||
710 | * | ||
711 | * anyway, | ||
712 | * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= | ||
713 | * inflate_threshold | ||
714 | * | ||
715 | * avoid a division: | ||
716 | * 100 * (not_to_be_doubled + 2*to_be_doubled) >= | ||
717 | * inflate_threshold * new_child_length | ||
718 | * | ||
719 | * expand not_to_be_doubled and to_be_doubled, and shorten: | ||
720 | * 100 * (tnode_child_length(tn) - tn->empty_children + | ||
721 | * tn->full_children) >= inflate_threshold * new_child_length | ||
722 | * | ||
723 | * expand new_child_length: | ||
724 | * 100 * (tnode_child_length(tn) - tn->empty_children + | ||
725 | * tn->full_children) >= | ||
726 | * inflate_threshold * tnode_child_length(tn) * 2 | ||
727 | * | ||
728 | * shorten again: | ||
729 | * 50 * (tn->full_children + tnode_child_length(tn) - | ||
730 | * tn->empty_children) >= inflate_threshold * | ||
731 | * tnode_child_length(tn) | ||
732 | * | ||
733 | */ | 756 | */ |
734 | |||
735 | /* Keep root node larger */ | ||
736 | |||
737 | if (!node_parent(tn)) { | ||
738 | inflate_threshold_use = inflate_threshold_root; | ||
739 | halve_threshold_use = halve_threshold_root; | ||
740 | } else { | ||
741 | inflate_threshold_use = inflate_threshold; | ||
742 | halve_threshold_use = halve_threshold; | ||
743 | } | ||
744 | |||
745 | max_work = MAX_WORK; | 757 | max_work = MAX_WORK; |
746 | while ((tn->full_children > 0 && max_work-- && | 758 | while (should_inflate(tn) && max_work--) { |
747 | 50 * (tn->full_children + tnode_child_length(tn) | ||
748 | - tn->empty_children) | ||
749 | >= inflate_threshold_use * tnode_child_length(tn))) { | ||
750 | |||
751 | old_tn = tn; | 759 | old_tn = tn; |
752 | tn = inflate(t, tn); | 760 | tn = inflate(t, tn); |
753 | 761 | ||
@@ -764,16 +772,11 @@ static struct tnode *resize(struct trie *t, struct tnode *tn) | |||
764 | if (max_work != MAX_WORK) | 772 | if (max_work != MAX_WORK) |
765 | return tn; | 773 | return tn; |
766 | 774 | ||
767 | /* | 775 | /* Halve as long as the number of empty children in this |
768 | * Halve as long as the number of empty children in this | ||
769 | * node is above threshold. | 776 | * node is above threshold. |
770 | */ | 777 | */ |
771 | |||
772 | max_work = MAX_WORK; | 778 | max_work = MAX_WORK; |
773 | while (tn->bits > 1 && max_work-- && | 779 | while (should_halve(tn) && max_work--) { |
774 | 100 * (tnode_child_length(tn) - tn->empty_children) < | ||
775 | halve_threshold_use * tnode_child_length(tn)) { | ||
776 | |||
777 | old_tn = tn; | 780 | old_tn = tn; |
778 | tn = halve(t, tn); | 781 | tn = halve(t, tn); |
779 | if (IS_ERR(tn)) { | 782 | if (IS_ERR(tn)) { |