diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2006-09-12 20:35:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-13 07:32:14 -0700 |
commit | dd9daa221e77f642954849a795fa7c59533a9b2f (patch) | |
tree | 6b207a5296063e1a773f36fb724402ea7cbab7eb | |
parent | 7fbb36451a91de6e8f9ece4f1f1ee9bd8ebf838a (diff) |
[PATCH] rcu_do_batch: make ->qlen decrement irq safe
rcu_do_batch() decrements rdp->qlen with irqs enabled. This is not good,
it can also be modified by call_rcu() from interrupt.
Decrement ->qlen once with irqs disabled, after a main loop.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Dipankar Sarma <dipankar@in.ibm.com>
Cc: "Paul E. McKenney" <paulmck@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | kernel/rcupdate.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 436ab35f6fa7..523e46483b99 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -241,12 +241,16 @@ static void rcu_do_batch(struct rcu_data *rdp) next = rdp->donelist = list->next; list->func(list); list = next; - rdp->qlen--; if (++count >= rdp->blimit) break; } + + local_irq_disable(); + rdp->qlen -= count; + local_irq_enable(); if (rdp->blimit == INT_MAX && rdp->qlen <= qlowmark) rdp->blimit = blimit; + if (!rdp->donelist) rdp->donetail = &rdp->donelist; else |