Re: [PATCH net-2.6] Re: rib_trie / Fix inflate_threshold_root. Now=15 size=11 bits
From: Paweł Staszewski <hidden>
Date: 2009-06-29 16:24:47
Jarek Poplawski pisze:
On Mon, Jun 29, 2009 at 11:51:52AM +0200, Paweł Staszewski wrote:quoted
I apply this patch fib_triestats in attached file :)Great! But it would be nice to check if this (accidentally ;-) might fix the previous problem, so I attach below the patch with "manual RCU", which btw. (or even more important) should verify RCU use here.
After this patches all is OK now i don't see Fix inflate_threshold_root. Even if i make "clear ip bgp * " Before this patches when i make clear ip bgp there was always info in dmesg about "Fix inflate_threshold_root"
It should be applied on top of this last "Fix..., part3". And again: it's quite probable it can fail, so with caution, no hurry (it can wait for quiet time)...
After apply this last patch - traffic is not forwarded again :) i was fast and have only some fib_triestats in attached file before failover switch routers. This stats are from machine with this last patch that makes kernel to stop forwarding
quoted hunk ↗ jump to hunk
Many thanks, Jarek P. --------------------> (synchronize_rcu take 4) diff -Nurp a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c--- a/net/ipv4/fib_trie.c 2009-06-29 10:00:14.000000000 +0000 +++ b/net/ipv4/fib_trie.c 2009-06-29 10:04:22.000000000 +0000@@ -366,6 +366,17 @@ static void __tnode_vfree(struct work_st vfree(tn); } +static void __tnode_free(struct tnode *tn) +{ + size_t size = sizeof(struct tnode) + + (sizeof(struct node *) << tn->bits); + + if (size <= PAGE_SIZE) + kfree(tn); + else + vfree(tn); +} + static void __tnode_free_rcu(struct rcu_head *head) { struct tnode *tn = container_of(head, struct tnode, rcu);@@ -402,7 +413,7 @@ static void tnode_free_flush(void) while ((tn = tnode_free_head)) { tnode_free_head = tn->tnode_free; tn->tnode_free = NULL; - tnode_free(tn); + __tnode_free(tn); } }@@ -1021,21 +1032,27 @@ static void trie_rebalance(struct trie * (struct node *)tn, wasfull); tp = node_parent((struct node *) tn); - if (!tp) + if (!tp) { rcu_assign_pointer(t->trie, (struct node *)tn); - - tnode_free_flush(); - if (!tp) break; + } tn = tp; } + if (tnode_free_head) { + synchronize_rcu(); + tnode_free_flush(); + } + /* Handle last (top) tnode */ - if (IS_TNODE(tn)) + if (IS_TNODE(tn)) { tn = (struct tnode *)resize(t, (struct tnode *)tn); - - rcu_assign_pointer(t->trie, (struct node *)tn); - tnode_free_flush(); + rcu_assign_pointer(t->trie, (struct node *)tn); + synchronize_rcu(); + tnode_free_flush(); + } else { + rcu_assign_pointer(t->trie, (struct node *)tn); + } return; } --To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Attachments
- fib_triestats.txt [text/plain] 890 bytes · preview