aboutsummaryrefslogtreecommitdiff
path: root/kernel/rcutree.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2015-06-22 01:07:29 +0530
committerMister Oyster <oysterized@gmail.com>2017-04-11 10:59:13 +0200
commit9305c5c56034122d22b5b2a8c2ce4e0358f28366 (patch)
tree62eb5b595a9baecd9f28a368d8747c70d3d41d0b /kernel/rcutree.c
parentc873d392b1c911e75aada1586d073d05cbbc6ed8 (diff)
rcu: Protect ->gp_flags accesses with ACCESS_ONCE()
A number of ->gp_flags accesses don't have ACCESS_ONCE(), but all of the can race against other loads or stores. This commit therefore applies ACCESS_ONCE() to the unprotected ->gp_flags accesses. Reported-by: Alexey Roytman <alexey.roytman@oracle.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org> Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Git-commit: 91dc95427a0d30ac2c58d6e943c7f40a3f25d908 [kishank@codeaurora.org resolve trivial conflicts] Signed-off-by: Kishan Kumar <kishank@codeaurora.org> Signed-off-by: Pranav Vashi <neobuddy89@gmail.com> Change-Id: I2ed581b545fb9c93468658fa621e71c091ec250b
Diffstat (limited to 'kernel/rcutree.c')
-rw-r--r--kernel/rcutree.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 847b69efe..c0986f312 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1348,7 +1348,7 @@ static int rcu_gp_init(struct rcu_state *rsp)
struct rcu_node *rnp = rcu_get_root(rsp);
raw_spin_lock_irq(&rnp->lock);
- rsp->gp_flags = 0; /* Clear all flags: New grace period. */
+ ACCESS_ONCE(rsp->gp_flags) = 0; /* Clear all flags: New grace period. */
if (rcu_gp_in_progress(rsp)) {
/* Grace period already in progress, don't start another. */
@@ -1425,7 +1425,7 @@ int rcu_gp_fqs(struct rcu_state *rsp, int fqs_state_in)
/* Clear flag to prevent immediate re-entry. */
if (ACCESS_ONCE(rsp->gp_flags) & RCU_GP_FLAG_FQS) {
raw_spin_lock_irq(&rnp->lock);
- rsp->gp_flags &= ~RCU_GP_FLAG_FQS;
+ ACCESS_ONCE(rsp->gp_flags) &= ~RCU_GP_FLAG_FQS;
raw_spin_unlock_irq(&rnp->lock);
}
return fqs_state;
@@ -1485,7 +1485,7 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)
rdp = this_cpu_ptr(rsp->rda);
rcu_advance_cbs(rsp, rnp, rdp); /* Reduce false positives below. */
if (cpu_needs_another_gp(rsp, rdp))
- rsp->gp_flags = 1;
+ ACCESS_ONCE(rsp->gp_flags) = 1;
raw_spin_unlock_irq(&rnp->lock);
}
@@ -1508,7 +1508,7 @@ static int __noreturn rcu_gp_kthread(void *arg)
wait_event_interruptible(rsp->gp_wq,
ACCESS_ONCE(rsp->gp_flags) &
RCU_GP_FLAG_INIT);
- if ((rsp->gp_flags & RCU_GP_FLAG_INIT) &&
+ if ((ACCESS_ONCE(rsp->gp_flags) & RCU_GP_FLAG_INIT) &&
rcu_gp_init(rsp))
break;
cond_resched();
@@ -1591,8 +1591,7 @@ rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp,
*/
return;
}
- rsp->gp_flags = RCU_GP_FLAG_INIT;
-
+ ACCESS_ONCE(rsp->gp_flags) = RCU_GP_FLAG_INIT;
/*
* We can't do wakeups while holding the rnp->lock, as that
* could cause possible deadlocks with the rq->lock. Defer
@@ -2203,7 +2202,7 @@ static void force_quiescent_state(struct rcu_state *rsp)
raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
return; /* Someone beat us to it. */
}
- rsp->gp_flags |= RCU_GP_FLAG_FQS;
+ ACCESS_ONCE(rsp->gp_flags) |= RCU_GP_FLAG_FQS;
raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
wake_up(&rsp->gp_wq); /* Memory barrier implied by wake_up() path. */
}