• Paul E. McKenney's avatar
    rcu: Prevent expedited GP from enabling tick on offline CPU · 147f04b1
    Paul E. McKenney authored
    If an RCU expedited grace period starts just when a CPU is in the process
    of going offline, so that the outgoing CPU has completed its pass through
    stop-machine but has not yet completed its final dive into the idle loop,
    RCU will attempt to enable that CPU's scheduling-clock tick via a call
    to tick_dep_set_cpu().  For this to happen, that CPU has to have been
    online when the expedited grace period completed its CPU-selection phase.
    
    This is pointless:  The outgoing CPU has interrupts disabled, so it cannot
    take a scheduling-clock tick anyway.  In addition, the tick_dep_set_cpu()
    function's eventual call to irq_work_queue_on() will splat as follows:
    
    smpboot: CPU 1 is now offline
    WARNING: CPU: 6 PID: 124 at kernel/irq_work.c:95
    +irq_work_queue_on+0x57/0x60
    Modules linked in:
    CPU: 6 PID: 124 Comm: kworker/6:2 Not tainted 5.15.0-rc1+ #3
    Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
    +rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014
    Workqueue: rcu_gp wait_rcu_exp_gp
    RIP: 0010:irq_work_queue_on+0x57/0x60
    Code: 8b 05 1d c7 ea 62 a9 00 00 f0 00 75 21 4c 89 ce 44 89 c7 e8
    +9b 37 fa ff ba 01 00 00 00 89 d0 c3 4c 89 cf e8 3b ff ff ff eb ee <0f> 0b eb b7
    +0f 0b eb db 90 48 c7 c0 98 2a 02 00 65 48 03 05 91
     6f
    RSP: 0000:ffffb12cc038fe48 EFLAGS: 00010282
    RAX: 0000000000000001 RBX: 0000000000005208 RCX: 0000000000000020
    RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffff9ad01f45a680
    RBP: 000000000004c990 R08: 0000000000000001 R09: ffff9ad01f45a680
    R10: ffffb12cc0317db0 R11: 0000000000000001 R12: 00000000fffecee8
    R13: 0000000000000001 R14: 0000000000026980 R15: ffffffff9e53ae00
    FS:  0000000000000000(0000) GS:ffff9ad01f580000(0000)
    +knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000000000000 CR3: 000000000de0c000 CR4: 00000000000006e0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
     tick_nohz_dep_set_cpu+0x59/0x70
     rcu_exp_wait_wake+0x54e/0x870
     ? sync_rcu_exp_select_cpus+0x1fc/0x390
     process_one_work+0x1ef/0x3c0
     ? process_one_work+0x3c0/0x3c0
     worker_thread+0x28/0x3c0
     ? process_one_work+0x3c0/0x3c0
     kthread+0x115/0x140
     ? set_kthread_struct+0x40/0x40
     ret_from_fork+0x22/0x30
    ---[ end trace c5bf75eb6aa80bc6 ]---
    
    This commit therefore avoids invoking tick_dep_set_cpu() on offlined
    CPUs to limit both futility and false-positive splats.
    Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    147f04b1
tree_exp.h 25.3 KB