diff options
-rw-r--r-- | net/ipv4/fib_trie.c | 95 |
1 files changed, 23 insertions, 72 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index fe3c846b99a6..291bdf50a21f 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -48,7 +48,7 @@ | |||
48 | * Patrick McHardy <kaber@trash.net> | 48 | * Patrick McHardy <kaber@trash.net> |
49 | */ | 49 | */ |
50 | 50 | ||
51 | #define VERSION "0.408" | 51 | #define VERSION "0.409" |
52 | 52 | ||
53 | #include <asm/uaccess.h> | 53 | #include <asm/uaccess.h> |
54 | #include <asm/system.h> | 54 | #include <asm/system.h> |
@@ -325,10 +325,7 @@ static inline void check_tnode(const struct tnode *tn) | |||
325 | static const int halve_threshold = 25; | 325 | static const int halve_threshold = 25; |
326 | static const int inflate_threshold = 50; | 326 | static const int inflate_threshold = 50; |
327 | static const int halve_threshold_root = 15; | 327 | static const int halve_threshold_root = 15; |
328 | static const int inflate_threshold_root = 25; | 328 | static const int inflate_threshold_root = 30; |
329 | |||
330 | static int inflate_threshold_root_fix; | ||
331 | #define INFLATE_FIX_MAX 10 /* a comment in resize() */ | ||
332 | 329 | ||
333 | static void __alias_free_mem(struct rcu_head *head) | 330 | static void __alias_free_mem(struct rcu_head *head) |
334 | { | 331 | { |
@@ -516,14 +513,14 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, | |||
516 | rcu_assign_pointer(tn->child[i], n); | 513 | rcu_assign_pointer(tn->child[i], n); |
517 | } | 514 | } |
518 | 515 | ||
516 | #define MAX_WORK 10 | ||
519 | static struct node *resize(struct trie *t, struct tnode *tn) | 517 | static struct node *resize(struct trie *t, struct tnode *tn) |
520 | { | 518 | { |
521 | int i; | 519 | int i; |
522 | int err = 0; | ||
523 | struct tnode *old_tn; | 520 | struct tnode *old_tn; |
524 | int inflate_threshold_use; | 521 | int inflate_threshold_use; |
525 | int halve_threshold_use; | 522 | int halve_threshold_use; |
526 | int max_resize; | 523 | int max_work; |
527 | 524 | ||
528 | if (!tn) | 525 | if (!tn) |
529 | return NULL; | 526 | return NULL; |
@@ -538,18 +535,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
538 | } | 535 | } |
539 | /* One child */ | 536 | /* One child */ |
540 | if (tn->empty_children == tnode_child_length(tn) - 1) | 537 | if (tn->empty_children == tnode_child_length(tn) - 1) |
541 | for (i = 0; i < tnode_child_length(tn); i++) { | 538 | goto one_child; |
542 | struct node *n; | ||
543 | |||
544 | n = tn->child[i]; | ||
545 | if (!n) | ||
546 | continue; | ||
547 | |||
548 | /* compress one level */ | ||
549 | node_set_parent(n, NULL); | ||
550 | tnode_free_safe(tn); | ||
551 | return n; | ||
552 | } | ||
553 | /* | 539 | /* |
554 | * Double as long as the resulting node has a number of | 540 | * Double as long as the resulting node has a number of |
555 | * nonempty nodes that are above the threshold. | 541 | * nonempty nodes that are above the threshold. |
@@ -618,15 +604,17 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
618 | 604 | ||
619 | /* Keep root node larger */ | 605 | /* Keep root node larger */ |
620 | 606 | ||
621 | if (!tn->parent) | 607 | if (!node_parent((struct node*) tn)) { |
622 | inflate_threshold_use = inflate_threshold_root + | 608 | inflate_threshold_use = inflate_threshold_root; |
623 | inflate_threshold_root_fix; | 609 | halve_threshold_use = halve_threshold_root; |
624 | else | 610 | } |
611 | else { | ||
625 | inflate_threshold_use = inflate_threshold; | 612 | inflate_threshold_use = inflate_threshold; |
613 | halve_threshold_use = halve_threshold; | ||
614 | } | ||
626 | 615 | ||
627 | err = 0; | 616 | max_work = MAX_WORK; |
628 | max_resize = 10; | 617 | while ((tn->full_children > 0 && max_work-- && |
629 | while ((tn->full_children > 0 && max_resize-- && | ||
630 | 50 * (tn->full_children + tnode_child_length(tn) | 618 | 50 * (tn->full_children + tnode_child_length(tn) |
631 | - tn->empty_children) | 619 | - tn->empty_children) |
632 | >= inflate_threshold_use * tnode_child_length(tn))) { | 620 | >= inflate_threshold_use * tnode_child_length(tn))) { |
@@ -643,47 +631,19 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
643 | } | 631 | } |
644 | } | 632 | } |
645 | 633 | ||
646 | if (max_resize < 0) { | ||
647 | if (!tn->parent) { | ||
648 | /* | ||
649 | * It was observed that during large updates even | ||
650 | * inflate_threshold_root = 35 might be needed to avoid | ||
651 | * this warning; but it should be temporary, so let's | ||
652 | * try to handle this automatically. | ||
653 | */ | ||
654 | if (inflate_threshold_root_fix < INFLATE_FIX_MAX) | ||
655 | inflate_threshold_root_fix++; | ||
656 | else | ||
657 | pr_warning("Fix inflate_threshold_root." | ||
658 | " Now=%d size=%d bits fix=%d\n", | ||
659 | inflate_threshold_root, tn->bits, | ||
660 | inflate_threshold_root_fix); | ||
661 | } else { | ||
662 | pr_warning("Fix inflate_threshold." | ||
663 | " Now=%d size=%d bits\n", | ||
664 | inflate_threshold, tn->bits); | ||
665 | } | ||
666 | } else if (max_resize > 3 && !tn->parent && inflate_threshold_root_fix) | ||
667 | inflate_threshold_root_fix--; | ||
668 | |||
669 | check_tnode(tn); | 634 | check_tnode(tn); |
670 | 635 | ||
636 | /* Return if at least one inflate is run */ | ||
637 | if( max_work != MAX_WORK) | ||
638 | return (struct node *) tn; | ||
639 | |||
671 | /* | 640 | /* |
672 | * Halve as long as the number of empty children in this | 641 | * Halve as long as the number of empty children in this |
673 | * node is above threshold. | 642 | * node is above threshold. |
674 | */ | 643 | */ |
675 | 644 | ||
676 | 645 | max_work = MAX_WORK; | |
677 | /* Keep root node larger */ | 646 | while (tn->bits > 1 && max_work-- && |
678 | |||
679 | if (!tn->parent) | ||
680 | halve_threshold_use = halve_threshold_root; | ||
681 | else | ||
682 | halve_threshold_use = halve_threshold; | ||
683 | |||
684 | err = 0; | ||
685 | max_resize = 10; | ||
686 | while (tn->bits > 1 && max_resize-- && | ||
687 | 100 * (tnode_child_length(tn) - tn->empty_children) < | 647 | 100 * (tnode_child_length(tn) - tn->empty_children) < |
688 | halve_threshold_use * tnode_child_length(tn)) { | 648 | halve_threshold_use * tnode_child_length(tn)) { |
689 | 649 | ||
@@ -698,19 +658,10 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
698 | } | 658 | } |
699 | } | 659 | } |
700 | 660 | ||
701 | if (max_resize < 0) { | ||
702 | if (!tn->parent) | ||
703 | pr_warning("Fix halve_threshold_root." | ||
704 | " Now=%d size=%d bits\n", | ||
705 | halve_threshold_root, tn->bits); | ||
706 | else | ||
707 | pr_warning("Fix halve_threshold." | ||
708 | " Now=%d size=%d bits\n", | ||
709 | halve_threshold, tn->bits); | ||
710 | } | ||
711 | 661 | ||
712 | /* Only one child remains */ | 662 | /* Only one child remains */ |
713 | if (tn->empty_children == tnode_child_length(tn) - 1) | 663 | if (tn->empty_children == tnode_child_length(tn) - 1) { |
664 | one_child: | ||
714 | for (i = 0; i < tnode_child_length(tn); i++) { | 665 | for (i = 0; i < tnode_child_length(tn); i++) { |
715 | struct node *n; | 666 | struct node *n; |
716 | 667 | ||
@@ -724,7 +675,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) | |||
724 | tnode_free_safe(tn); | 675 | tnode_free_safe(tn); |
725 | return n; | 676 | return n; |
726 | } | 677 | } |
727 | 678 | } | |
728 | return (struct node *) tn; | 679 | return (struct node *) tn; |
729 | } | 680 | } |
730 | 681 | ||