• Dmitry Vyukov's avatar
    rcu: Fix warning in rcu_seq_end() · f010ed82
    Dmitry Vyukov authored
    The rcu_seq_end() function increments seq signifying completion
    of a grace period, after that checks that the seq is even and wakes
    _synchronize_rcu_expedited().  The _synchronize_rcu_expedited() function
    uses wait_event() to wait for even seq.  The problem is that wait_event()
    can return as soon as seq becomes even without waiting for the wakeup.
    In such case the warning in rcu_seq_end() can falsely fire if the next
    expedited grace period starts before the check.
    
    Check that seq has good value before incrementing it.
    Signed-off-by: default avatarDmitry Vyukov <dvyukov@google.com>
    Cc: syzkaller@googlegroups.com
    Cc: linux-kernel@vger.kernel.org
    Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
    Cc: josh@joshtriplett.org
    Cc: jiangshanlai@gmail.com
    Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
    
    ---
    
    syzkaller-triggered warning:
    
    WARNING: CPU: 0 PID: 4832 at kernel/rcu/tree.c:3533
    rcu_seq_end+0x110/0x140 kernel/rcu/tree.c:3533
    CPU: 0 PID: 4832 Comm: kworker/0:3 Not tainted 4.10.0+ #276
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
    Workqueue: events wait_rcu_exp_gp
    Call Trace:
     __dump_stack lib/dump_stack.c:15 [inline]
     dump_stack+0x2ee/0x3ef lib/dump_stack.c:51
     panic+0x1fb/0x412 kernel/panic.c:179
     __warn+0x1c4/0x1e0 kernel/panic.c:540
     warn_slowpath_null+0x2c/0x40 kernel/panic.c:583
     rcu_seq_end+0x110/0x140 kernel/rcu/tree.c:3533
     rcu_exp_gp_seq_end kernel/rcu/tree_exp.h:36 [inline]
     rcu_exp_wait_wake+0x8a9/0x1330 kernel/rcu/tree_exp.h:517
     rcu_exp_sel_wait_wake kernel/rcu/tree_exp.h:559 [inline]
     wait_rcu_exp_gp+0x83/0xc0 kernel/rcu/tree_exp.h:570
     process_one_work+0xc06/0x1c20 kernel/workqueue.c:2096
     worker_thread+0x223/0x19c0 kernel/workqueue.c:2230
     kthread+0x326/0x3f0 kernel/kthread.c:227
     ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430
    ---
    f010ed82
rcu.h 5.74 KB