| From ff5d6176c88f139ea8820a5d4ad8aee9c06d87a2 Mon Sep 17 00:00:00 2001 |
| From: "Paul E. McKenney" <paulmck@kernel.org> |
| Date: Mon, 4 Nov 2019 08:08:30 -0800 |
| Subject: [PATCH] srcu: Apply *_ONCE() to ->srcu_last_gp_end |
| |
| commit 844a378de3372c923909681706d62336d702531e upstream. |
| |
| The ->srcu_last_gp_end field is accessed from any CPU at any time |
| by synchronize_srcu(), so non-initialization references need to use |
| READ_ONCE() and WRITE_ONCE(). This commit therefore makes that change. |
| |
| Reported-by: syzbot+08f3e9d26e5541e1ecf2@syzkaller.appspotmail.com |
| Acked-by: Marco Elver <elver@google.com> |
| Signed-off-by: Paul E. McKenney <paulmck@kernel.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c |
| index 9b761e546de8..58c178e2b394 100644 |
| --- a/kernel/rcu/srcutree.c |
| +++ b/kernel/rcu/srcutree.c |
| @@ -530,7 +530,7 @@ static void srcu_gp_end(struct srcu_struct *ssp) |
| idx = rcu_seq_state(ssp->srcu_gp_seq); |
| WARN_ON_ONCE(idx != SRCU_STATE_SCAN2); |
| cbdelay = srcu_get_delay(ssp); |
| - ssp->srcu_last_gp_end = ktime_get_mono_fast_ns(); |
| + WRITE_ONCE(ssp->srcu_last_gp_end, ktime_get_mono_fast_ns()); |
| rcu_seq_end(&ssp->srcu_gp_seq); |
| gpseq = rcu_seq_current(&ssp->srcu_gp_seq); |
| if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, gpseq)) |
| @@ -762,6 +762,7 @@ static bool srcu_might_be_idle(struct srcu_struct *ssp) |
| unsigned long flags; |
| struct srcu_data *sdp; |
| unsigned long t; |
| + unsigned long tlast; |
| |
| /* If the local srcu_data structure has callbacks, not idle. */ |
| local_irq_save(flags); |
| @@ -780,9 +781,9 @@ static bool srcu_might_be_idle(struct srcu_struct *ssp) |
| |
| /* First, see if enough time has passed since the last GP. */ |
| t = ktime_get_mono_fast_ns(); |
| + tlast = READ_ONCE(ssp->srcu_last_gp_end); |
| if (exp_holdoff == 0 || |
| - time_in_range_open(t, ssp->srcu_last_gp_end, |
| - ssp->srcu_last_gp_end + exp_holdoff)) |
| + time_in_range_open(t, tlast, tlast + exp_holdoff)) |
| return false; /* Too soon after last GP. */ |
| |
| /* Next, check for probable idleness. */ |
| -- |
| 2.7.4 |
| |