diff options
| -rw-r--r-- | kernel/rcu/tree.c | 20 |
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 | */ |
| 1602 | static void rcu_gp_kthread_wake(void) | 1609 | static 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; |
