diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2009-06-30 15:47:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-30 15:48:38 -0400 |
commit | 008440e3ad4b72f5048d1b1f6f5ed894fdc5ad08 (patch) | |
tree | bcf7771cd07562b258aaa032f85c29eaa00b9b6c /net/ipv4 | |
parent | 01e532981460594fffbf9b992ecfc96a78369924 (diff) |
ipv4: Fix fib_trie rebalancing, part 3
Alas current delaying of freeing old tnodes by RCU in trie_rebalance
is still not enough because we can free a top tnode before updating a
t->trie pointer.
Reported-by: Pawel Staszewski <pstaszewski@itcare.pl>
Tested-by: Pawel Staszewski <pstaszewski@itcare.pl>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/fib_trie.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 012cf5a68581..00a54b246dfe 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1021,6 +1021,9 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) | |||
1021 | (struct node *)tn, wasfull); | 1021 | (struct node *)tn, wasfull); |
1022 | 1022 | ||
1023 | tp = node_parent((struct node *) tn); | 1023 | tp = node_parent((struct node *) tn); |
1024 | if (!tp) | ||
1025 | rcu_assign_pointer(t->trie, (struct node *)tn); | ||
1026 | |||
1024 | tnode_free_flush(); | 1027 | tnode_free_flush(); |
1025 | if (!tp) | 1028 | if (!tp) |
1026 | break; | 1029 | break; |