aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/rcu/tree.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 9ceb93f848cd..21775eebb8f0 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1593,15 +1593,23 @@ static bool rcu_future_gp_cleanup(struct rcu_node *rnp)
1593} 1593}
1594 1594
1595/* 1595/*
1596 * Awaken the grace-period kthread. Don't do a self-awaken, and don't 1596 * Awaken the grace-period kthread. Don't do a self-awaken (unless in
1597 * bother awakening when there is nothing for the grace-period kthread 1597 * an interrupt or softirq handler), and don't bother awakening when there
1598 * to do (as in several CPUs raced to awaken, and we lost), and finally 1598 * is nothing for the grace-period kthread to do (as in several CPUs raced
1599 * don't try to awaken a kthread that has not yet been created. If 1599 * to awaken, and we lost), and finally don't try to awaken a kthread that
1600 * all those checks are passed, track some debug information and awaken. 1600 * has not yet been created. If all those checks are passed, track some
1601 * debug information and awaken.
1602 *
1603 * So why do the self-wakeup when in an interrupt or softirq handler
1604 * in the grace-period kthread's context? Because the kthread might have
1605 * been interrupted just as it was going to sleep, and just after the final
1606 * pre-sleep check of the awaken condition. In this case, a wakeup really
1607 * is required, and is therefore supplied.
1601 */ 1608 */
1602static void rcu_gp_kthread_wake(void) 1609static void rcu_gp_kthread_wake(void)
1603{ 1610{
1604 if (current == rcu_state.gp_kthread || 1611 if ((current == rcu_state.gp_kthread &&
1612 !in_interrupt() && !in_serving_softirq()) ||
1605 !READ_ONCE(rcu_state.gp_flags) || 1613 !READ_ONCE(rcu_state.gp_flags) ||
1606 !rcu_state.gp_kthread) 1614 !rcu_state.gp_kthread)
1607 return; 1615 return;