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 cd95efa1da48..8d85a5ce093a 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -1635,17 +1635,23 @@ module_param(rcu_idle_lazy_gp_delay, int, 0644); | |||
1635 | extern int tick_nohz_enabled; | 1635 | extern int tick_nohz_enabled; |
1636 | 1636 | ||
1637 | /* | 1637 | /* |
1638 | * Try to advance callbacks for all flavors of RCU on the current CPU. | 1638 | * Try to advance callbacks for all flavors of RCU on the current CPU, but |
1639 | * Afterwards, if there are any callbacks ready for immediate invocation, | 1639 | * only if it has been awhile since the last time we did so. Afterwards, |
1640 | * return true. | 1640 | * if there are any callbacks ready for immediate invocation, return true. |
1641 | */ | 1641 | */ |
1642 | static bool rcu_try_advance_all_cbs(void) | 1642 | static bool rcu_try_advance_all_cbs(void) |
1643 | { | 1643 | { |
1644 | bool cbs_ready = false; | 1644 | bool cbs_ready = false; |
1645 | struct rcu_data *rdp; | 1645 | struct rcu_data *rdp; |
1646 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); | ||
1646 | struct rcu_node *rnp; | 1647 | struct rcu_node *rnp; |
1647 | struct rcu_state *rsp; | 1648 | struct rcu_state *rsp; |
1648 | 1649 | ||
1650 | /* Exit early if we advanced recently. */ | ||
1651 | if (jiffies == rdtp->last_advance_all) | ||
1652 | return 0; | ||
1653 | rdtp->last_advance_all = jiffies; | ||
1654 | |||
1649 | for_each_rcu_flavor(rsp) { | 1655 | for_each_rcu_flavor(rsp) { |
1650 | rdp = this_cpu_ptr(rsp->rda); | 1656 | rdp = this_cpu_ptr(rsp->rda); |
1651 | rnp = rdp->mynode; | 1657 | rnp = rdp->mynode; |
@@ -1744,6 +1750,8 @@ static void rcu_prepare_for_idle(int cpu) | |||
1744 | */ | 1750 | */ |
1745 | if (rdtp->all_lazy && | 1751 | if (rdtp->all_lazy && |
1746 | rdtp->nonlazy_posted != rdtp->nonlazy_posted_snap) { | 1752 | rdtp->nonlazy_posted != rdtp->nonlazy_posted_snap) { |
1753 | rdtp->all_lazy = false; | ||
1754 | rdtp->nonlazy_posted_snap = rdtp->nonlazy_posted; | ||
1747 | invoke_rcu_core(); | 1755 | invoke_rcu_core(); |
1748 | return; | 1756 | return; |
1749 | } | 1757 | } |
@@ -1773,17 +1781,11 @@ static void rcu_prepare_for_idle(int cpu) | |||
1773 | */ | 1781 | */ |
1774 | static void rcu_cleanup_after_idle(int cpu) | 1782 | static void rcu_cleanup_after_idle(int cpu) |
1775 | { | 1783 | { |
1776 | struct rcu_data *rdp; | ||
1777 | struct rcu_state *rsp; | ||
1778 | 1784 | ||
1779 | if (rcu_is_nocb_cpu(cpu)) | 1785 | if (rcu_is_nocb_cpu(cpu)) |
1780 | return; | 1786 | return; |
1781 | rcu_try_advance_all_cbs(); | 1787 | if (rcu_try_advance_all_cbs()) |
1782 | for_each_rcu_flavor(rsp) { | 1788 | invoke_rcu_core(); |
1783 | rdp = per_cpu_ptr(rsp->rda, cpu); | ||
1784 | if (cpu_has_callbacks_ready_to_invoke(rdp)) | ||
1785 | invoke_rcu_core(); | ||
1786 | } | ||
1787 | } | 1789 | } |
1788 | 1790 | ||
1789 | /* | 1791 | /* |