aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2006-09-12 23:35:55 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-13 10:32:14 -0400
commitdd9daa221e77f642954849a795fa7c59533a9b2f (patch)
tree6b207a5296063e1a773f36fb724402ea7cbab7eb
parent7fbb36451a91de6e8f9ece4f1f1ee9bd8ebf838a (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.c6
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)
241 next = rdp->donelist = list->next; 241 next = rdp->donelist = list->next;
242 list->func(list); 242 list->func(list);
243 list = next; 243 list = next;
244 rdp->qlen--;
245 if (++count >= rdp->blimit) 244 if (++count >= rdp->blimit)
246 break; 245 break;
247 } 246 }
247
248 local_irq_disable();
249 rdp->qlen -= count;
250 local_irq_enable();
248 if (rdp->blimit == INT_MAX && rdp->qlen <= qlowmark) 251 if (rdp->blimit == INT_MAX && rdp->qlen <= qlowmark)
249 rdp->blimit = blimit; 252 rdp->blimit = blimit;
253
250 if (!rdp->donelist) 254 if (!rdp->donelist)
251 rdp->donetail = &rdp->donelist; 255 rdp->donetail = &rdp->donelist;
252 else 256 else