diff options
| author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-06-22 01:07:29 +0530 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-04-11 10:59:13 +0200 |
| commit | 9305c5c56034122d22b5b2a8c2ce4e0358f28366 (patch) | |
| tree | 62eb5b595a9baecd9f28a368d8747c70d3d41d0b | |
| parent | c873d392b1c911e75aada1586d073d05cbbc6ed8 (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
| -rw-r--r-- | kernel/rcutree.c | 13 |
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. */ } |
