ipv4: Fix inflate_threshold_root automatically
authorJarek Poplawski <jarkao2@gmail.com>
Tue, 14 Jul 2009 09:41:00 +0000 (09:41 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Jul 2009 14:39:29 +0000 (07:39 -0700)
During large updates there could be triggered warnings like: "Fix
inflate_threshold_root. Now=25 size=11 bits" if inflate() of the root
node isn't finished in 10 loops. It should be much rarer now, after
changing the threshold from 15 to 25, and a temporary problem, so
this patch tries to handle it automatically using a fix variable to
increase by one inflate threshold for next root resizes (up to the 35
limit, max fix = 10). The fix variable is decreased when root's
inflate() finishes below 7 loops (even if some other, smaller table/
trie is updated -- for simplicity the fix variable is global for now).

Reported-by: Pawel Staszewski <pstaszewski@itcare.pl>
Reported-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Tested-by: Pawel Staszewski <pstaszewski@itcare.pl>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: Robert Olsson <robert.olsson@its.uu.se>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/fib_trie.c

index 58ba9f4f2c92eade0c84b5b14c84e2754d0bbccb..5741d1306cc5af5e74f14f64f242fc98dafc6b60 100644 (file)
@@ -327,6 +327,8 @@ static const int inflate_threshold = 50;
 static const int halve_threshold_root = 15;
 static const int inflate_threshold_root = 25;
 
+static int inflate_threshold_root_fix;
+#define INFLATE_FIX_MAX 10     /* a comment in resize() */
 
 static void __alias_free_mem(struct rcu_head *head)
 {
@@ -617,7 +619,8 @@ static struct node *resize(struct trie *t, struct tnode *tn)
        /* Keep root node larger  */
 
        if (!tn->parent)
-               inflate_threshold_use = inflate_threshold_root;
+               inflate_threshold_use = inflate_threshold_root +
+                                       inflate_threshold_root_fix;
        else
                inflate_threshold_use = inflate_threshold;
 
@@ -641,15 +644,27 @@ static struct node *resize(struct trie *t, struct tnode *tn)
        }
 
        if (max_resize < 0) {
-               if (!tn->parent)
-                       pr_warning("Fix inflate_threshold_root."
-                                  " Now=%d size=%d bits\n",
-                                  inflate_threshold_root, tn->bits);
-               else
+               if (!tn->parent) {
+                       /*
+                        * It was observed that during large updates even
+                        * inflate_threshold_root = 35 might be needed to avoid
+                        * this warning; but it should be temporary, so let's
+                        * try to handle this automatically.
+                        */
+                       if (inflate_threshold_root_fix < INFLATE_FIX_MAX)
+                               inflate_threshold_root_fix++;
+                       else
+                               pr_warning("Fix inflate_threshold_root."
+                                          " Now=%d size=%d bits fix=%d\n",
+                                          inflate_threshold_root, tn->bits,
+                                          inflate_threshold_root_fix);
+               } else {
                        pr_warning("Fix inflate_threshold."
                                   " Now=%d size=%d bits\n",
                                   inflate_threshold, tn->bits);
-       }
+               }
+       } else if (max_resize > 3 && !tn->parent && inflate_threshold_root_fix)
+               inflate_threshold_root_fix--;
 
        check_tnode(tn);