From: Kunwu Chan <[email protected]>

call_srcu() is forbidden on atomic srcu_struct, so srcu_gp_end() never
has callbacks to invoke for them.  Yet it schedules callback invocation,
which for atomic SRCU's SRCU_SIZE_SMALL state arms the boot CPU's
->delay_work timer every grace period, only for srcu_invoke_callbacks()
to find nothing to do.

Skip this for atomic SRCU.

Signed-off-by: Kunwu Chan <[email protected]>
---
 kernel/rcu/srcutree.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index 2d2a12f86115..c19f59725706 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -1018,10 +1018,10 @@ static void srcu_gp_end(struct srcu_struct *ssp, bool 
is_atomic)
 
        /* Initiate callback invocation as needed. */
        ss_state = smp_load_acquire(&sup->srcu_size_state);
-       if (ss_state < SRCU_SIZE_WAIT_BARRIER) {
+       if (!is_atomic && ss_state < SRCU_SIZE_WAIT_BARRIER) {
                srcu_schedule_cbs_sdp(per_cpu_ptr(ssp->sda, get_boot_cpu_id()),
                                        cbdelay);
-       } else {
+       } else if (!is_atomic) {
                idx = rcu_seq_ctr(gpseq) % ARRAY_SIZE(snp->srcu_have_cbs);
                srcu_for_each_node_breadth_first(ssp, snp) {
                        raw_spin_lock_irq_rcu_node(snp);
-- 
2.43.0


Reply via email to