Skip to content
  • Zhang, Jun's avatar
    rcu: Do RCU GP kthread self-wakeup from softirq and interrupt · 61cc5315
    Zhang, Jun authored
    commit 1d1f898d upstream.
    
    The rcu_gp_kthread_wake() function is invoked when it might be necessary
    to wake the RCU grace-period kthread.  Because self-wakeups are normally
    a useless waste of CPU cycles, if rcu_gp_kthread_wake() is invoked from
    this kthread, it naturally refuses to do the wakeup.
    
    Unfortunately, natural though it might be, this heuristic fails when
    rcu_gp_kthread_wake() is invoked from an interrupt or softirq handler
    that interrupted the grace-period kthread just after the final check of
    the wait-event condition but just before the schedule() call.  In this
    case, a wakeup is required, even though the call to rcu_gp_kthread_wake()
    is within the RCU grace-period kthread's context.  Failing to provide
    this wakeup can result in grace periods failing to start, which in turn
    results in out-of-memory conditions.
    
    This race window is quite narrow, but it actually did happen during real
    testing.  It would of course need to be fixed even if it was strictly
    theoretical in nature.
    
    This patch does not Cc stable because it does not apply cleanly to
    earlier kernel versions.
    
    Fixes: 48a7639c
    
     ("rcu: Make callers awaken grace-period kthread")
    Reported-by: default avatar"He, Bo" <bo.he@intel.com>
    Co-developed-by: default avatar"Zhang, Jun" <jun.zhang@intel.com>
    Co-developed-by: default avatar"He, Bo" <bo.he@intel.com>
    Co-developed-by: default avatar"xiao, jin" <jin.xiao@intel.com>
    Co-developed-by: default avatarBai, Jie A <jie.a.bai@intel.com>
    Signed-off: "Zhang, Jun" <jun.zhang@intel.com>
    Signed-off: "He, Bo" <bo.he@intel.com>
    Signed-off: "xiao, jin" <jin.xiao@intel.com>
    Signed-off: Bai, Jie A <jie.a.bai@intel.com>
    Signed-off-by: default avatar"Zhang, Jun" <jun.zhang@intel.com>
    [ paulmck: Switch from !in_softirq() to "!in_interrupt() &&
      !in_serving_softirq() to avoid redundant wakeups and to also handle the
      interrupt-handler scenario as well as the softirq-handler scenario that
      actually occurred in testing. ]
    Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.ibm.com>
    Link: https://lkml.kernel.org/r/CD6925E8781EFD4D8E11882D20FC406D52A11F61@SHSMSX104.ccr.corp.intel.com
    
    
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    
    61cc5315