aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/fib_trie.c95
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)
325static const int halve_threshold = 25; 325static const int halve_threshold = 25;
326static const int inflate_threshold = 50; 326static const int inflate_threshold = 50;
327static const int halve_threshold_root = 15; 327static const int halve_threshold_root = 15;
328static const int inflate_threshold_root = 25; 328static const int inflate_threshold_root = 30;
329
330static int inflate_threshold_root_fix;
331#define INFLATE_FIX_MAX 10 /* a comment in resize() */
332 329
333static void __alias_free_mem(struct rcu_head *head) 330static 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
519static struct node *resize(struct trie *t, struct tnode *tn) 517static 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) {
664one_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