openwrtv4/target/linux/generic/patches-3.18/080-21-fib_trie-Fall-back-to-slen-update-on-inflate-halve-f.patch
Felix Fietkau 944612680d kernel: backport fib_trie improvements/fixes from 4.0-rc
Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 44695
2015-03-12 15:27:44 +00:00

61 lines
1.9 KiB
Diff

From: Alexander Duyck <alexander.h.duyck@redhat.com>
Date: Thu, 22 Jan 2015 15:51:20 -0800
Subject: [PATCH] fib_trie: Fall back to slen update on inflate/halve failure
This change corrects an issue where if inflate or halve fails we were
exiting the resize function without at least updating the slen for the
node. To correct this I have moved the update of max_size into the while
loop so that it is only decremented on a successful call to either inflate
or halve.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -752,7 +752,7 @@ static void resize(struct trie *t, struc
{
struct tnode *tp = node_parent(tn), *n = NULL;
struct tnode __rcu **cptr;
- int max_work;
+ int max_work = MAX_WORK;
pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n",
tn, inflate_threshold, halve_threshold);
@@ -775,8 +775,7 @@ static void resize(struct trie *t, struc
/* Double as long as the resulting node has a number of
* nonempty nodes that are above the threshold.
*/
- max_work = MAX_WORK;
- while (should_inflate(tp, tn) && max_work--) {
+ while (should_inflate(tp, tn) && max_work) {
if (inflate(t, tn)) {
#ifdef CONFIG_IP_FIB_TRIE_STATS
this_cpu_inc(t->stats->resize_node_skipped);
@@ -784,6 +783,7 @@ static void resize(struct trie *t, struc
break;
}
+ max_work--;
tn = rtnl_dereference(*cptr);
}
@@ -794,8 +794,7 @@ static void resize(struct trie *t, struc
/* Halve as long as the number of empty children in this
* node is above threshold.
*/
- max_work = MAX_WORK;
- while (should_halve(tp, tn) && max_work--) {
+ while (should_halve(tp, tn) && max_work) {
if (halve(t, tn)) {
#ifdef CONFIG_IP_FIB_TRIE_STATS
this_cpu_inc(t->stats->resize_node_skipped);
@@ -803,6 +802,7 @@ static void resize(struct trie *t, struc
break;
}
+ max_work--;
tn = rtnl_dereference(*cptr);
}