diff options
Diffstat (limited to 'kernel/rcutree_plugin.h')
-rw-r--r-- | kernel/rcutree_plugin.h | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 130c97b027f2..2c15d7c10684 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -1630,17 +1630,23 @@ module_param(rcu_idle_lazy_gp_delay, int, 0644); | |||
1630 | extern int tick_nohz_enabled; | 1630 | extern int tick_nohz_enabled; |
1631 | 1631 | ||
1632 | /* | 1632 | /* |
1633 | * Try to advance callbacks for all flavors of RCU on the current CPU. | 1633 | * Try to advance callbacks for all flavors of RCU on the current CPU, but |
1634 | * Afterwards, if there are any callbacks ready for immediate invocation, | 1634 | * only if it has been awhile since the last time we did so. Afterwards, |
1635 | * return true. | 1635 | * if there are any callbacks ready for immediate invocation, return true. |
1636 | */ | 1636 | */ |
1637 | static bool rcu_try_advance_all_cbs(void) | 1637 | static bool rcu_try_advance_all_cbs(void) |
1638 | { | 1638 | { |
1639 | bool cbs_ready = false; | 1639 | bool cbs_ready = false; |
1640 | struct rcu_data *rdp; | 1640 | struct rcu_data *rdp; |
1641 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); | ||
1641 | struct rcu_node *rnp; | 1642 | struct rcu_node *rnp; |
1642 | struct rcu_state *rsp; | 1643 | struct rcu_state *rsp; |
1643 | 1644 | ||
1645 | /* Exit early if we advanced recently. */ | ||
1646 | if (jiffies == rdtp->last_advance_all) | ||
1647 | return 0; | ||
1648 | rdtp->last_advance_all = jiffies; | ||
1649 | |||
1644 | for_each_rcu_flavor(rsp) { | 1650 | for_each_rcu_flavor(rsp) { |
1645 | rdp = this_cpu_ptr(rsp->rda); | 1651 | rdp = this_cpu_ptr(rsp->rda); |
1646 | rnp = rdp->mynode; | 1652 | rnp = rdp->mynode; |
@@ -1739,6 +1745,8 @@ static void rcu_prepare_for_idle(int cpu) | |||
1739 | */ | 1745 | */ |
1740 | if (rdtp->all_lazy && | 1746 | if (rdtp->all_lazy && |
1741 | rdtp->nonlazy_posted != rdtp->nonlazy_posted_snap) { | 1747 | rdtp->nonlazy_posted != rdtp->nonlazy_posted_snap) { |
1748 | rdtp->all_lazy = false; | ||
1749 | rdtp->nonlazy_posted_snap = rdtp->nonlazy_posted; | ||
1742 | invoke_rcu_core(); | 1750 | invoke_rcu_core(); |
1743 | return; | 1751 | return; |
1744 | } | 1752 | } |
@@ -1768,17 +1776,11 @@ static void rcu_prepare_for_idle(int cpu) | |||
1768 | */ | 1776 | */ |
1769 | static void rcu_cleanup_after_idle(int cpu) | 1777 | static void rcu_cleanup_after_idle(int cpu) |
1770 | { | 1778 | { |
1771 | struct rcu_data *rdp; | ||
1772 | struct rcu_state *rsp; | ||
1773 | 1779 | ||
1774 | if (rcu_is_nocb_cpu(cpu)) | 1780 | if (rcu_is_nocb_cpu(cpu)) |
1775 | return; | 1781 | return; |
1776 | rcu_try_advance_all_cbs(); | 1782 | if (rcu_try_advance_all_cbs()) |
1777 | for_each_rcu_flavor(rsp) { | 1783 | invoke_rcu_core(); |
1778 | rdp = per_cpu_ptr(rsp->rda, cpu); | ||
1779 | if (cpu_has_callbacks_ready_to_invoke(rdp)) | ||
1780 | invoke_rcu_core(); | ||
1781 | } | ||
1782 | } | 1784 | } |
1783 | 1785 | ||
1784 | /* | 1786 | /* |