aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2008-02-28 14:51:07 -0500
committerIngo Molnar <mingo@elte.hu>2008-02-29 14:21:13 -0500
commitc9e71002aacc9821e99531dcc130db88bbc8ad05 (patch)
tree2446b59e33eccc53ff8a04179588296bc43c0f0f /kernel
parentae778869ae4549628b9e83efe958c3aaa63ed1b9 (diff)
rcupreempt: remove never-migrates assumption from rcu_process_callbacks()
This patch fixes a potentially invalid access to a per-CPU variable in rcu_process_callbacks(). This per-CPU access needs to be done in such a way as to guarantee that the code using it cannot move to some other CPU before all uses of the value accessed have completed. Even though this code is currently only invoked from softirq context, which currrently cannot migrate to some other CPU, life would be better if this code did not silently make such an assumption. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/rcupreempt.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c
index 845abcd472b0..e9517014b57c 100644
--- a/kernel/rcupreempt.c
+++ b/kernel/rcupreempt.c
@@ -952,9 +952,11 @@ static void rcu_process_callbacks(struct softirq_action *unused)
952{ 952{
953 unsigned long flags; 953 unsigned long flags;
954 struct rcu_head *next, *list; 954 struct rcu_head *next, *list;
955 struct rcu_data *rdp = RCU_DATA_ME(); 955 struct rcu_data *rdp;
956 956
957 spin_lock_irqsave(&rdp->lock, flags); 957 local_irq_save(flags);
958 rdp = RCU_DATA_ME();
959 spin_lock(&rdp->lock);
958 list = rdp->donelist; 960 list = rdp->donelist;
959 if (list == NULL) { 961 if (list == NULL) {
960 spin_unlock_irqrestore(&rdp->lock, flags); 962 spin_unlock_irqrestore(&rdp->lock, flags);