[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20090629104703.GC4712@ff.dom.local>
Date: Mon, 29 Jun 2009 10:47:03 +0000
From: Jarek Poplawski <jarkao2@...il.com>
To: Paweł Staszewski <pstaszewski@...are.pl>
Cc: David Miller <davem@...emloft.net>,
Robert Olsson <robert@...ur.slu.se>,
Robert Olsson <Robert.Olsson@...a.slu.se>,
"Jorge Boncompte [DTI2]" <jorge@...2.net>,
Eric Dumazet <dada1@...mosbay.com>,
Robert Olsson <robert.olsson@....uu.se>,
Linux Network Development list <netdev@...r.kernel.org>
Subject: Re: [PATCH net-2.6] Re: rib_trie / Fix inflate_threshold_root.
Now=15 size=11 bits
On Mon, Jun 29, 2009 at 11:51:52AM +0200, Paweł Staszewski wrote:
> 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.
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)...
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@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists