Message ID | 19013.12045.576790.95151@robur.slu.se |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
On Fri, Jun 26, 2009 at 10:26:53PM +0200, Robert Olsson wrote: > > > Yes looks like a good solution but maybe it safest to synchronize unconditionally? Hmm... I lost around half an hour for this doubt... Sure! (Unless there are some strange cases which very often create and destroy very small tables?) Thanks, Jarek P. > > > diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c > index 012cf5a..9cb8623 100644 > --- a/net/ipv4/fib_trie.c > +++ b/net/ipv4/fib_trie.c > @@ -1028,8 +1028,11 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) > } > > /* Handle last (top) tnode */ > - if (IS_TNODE(tn)) > + if (IS_TNODE(tn)) { > + /* force memory freeing after last changes */ > + synchronize_rcu(); > tn = (struct tnode *)resize(t, (struct tnode *)tn); > + } > > rcu_assign_pointer(t->trie, (struct node *)tn); > tnode_free_flush(); > > Cheers > --ro > > Jarek Poplawski writes: > > > net/ipv4/fib_trie.c | 8 ++++++-- > > 1 files changed, 6 insertions(+), 2 deletions(-) > > > > diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c > > index 012cf5a..98b31a1 100644 > > --- a/net/ipv4/fib_trie.c > > +++ b/net/ipv4/fib_trie.c > > @@ -1008,7 +1008,7 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) > > { > > int wasfull; > > t_key cindex, key; > > - struct tnode *tp; > > + struct tnode *tp, *oldtnode = tn; > > > > key = tn->key; > > > > @@ -1028,8 +1028,12 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) > > } > > > > /* Handle last (top) tnode */ > > - if (IS_TNODE(tn)) > > + if (IS_TNODE(tn)) { > > + /* force memory freeing after last changes */ > > + if (oldtnode != tn) > > + synchronize_rcu(); > > tn = (struct tnode *)resize(t, (struct tnode *)tn); > > + } > > > > rcu_assign_pointer(t->trie, (struct node *)tn); > > tnode_free_flush(); > > -- > > 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 -- 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
On Fri, Jun 26, 2009 at 10:37:13PM +0200, Jarek Poplawski wrote: > On Fri, Jun 26, 2009 at 10:26:53PM +0200, Robert Olsson wrote: > > > > > > Yes looks like a good solution but maybe it safest to synchronize unconditionally? > > Hmm... I lost around half an hour for this doubt... Sure! (Unless > there are some strange cases which very often create and destroy very > small tables?) ...or maybe even only updating such small tables very often? Btw., Robert, I wondered about some design details lately, especially about pointer to a parent. I didn't see it in the basic docs, so it seems it could be avoided. It seems to be a problem with RCU, unless I miss something: if there were no going back from children to parents it seems we could free those "temporary" (created by inflate() and halve() and destroyed before resize() has finished) earlier. Another problem with this, it seems, are possibly false lookups (if we go back to the new parent which doesn't have it's parent or other nodes updated). So, was there so much performance gain to introduce this? Thanks, Jarek P. -- 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
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 012cf5a..9cb8623 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1028,8 +1028,11 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) } /* Handle last (top) tnode */ - if (IS_TNODE(tn)) + if (IS_TNODE(tn)) { + /* force memory freeing after last changes */ + synchronize_rcu(); tn = (struct tnode *)resize(t, (struct tnode *)tn); + } rcu_assign_pointer(t->trie, (struct node *)tn); tnode_free_flush();