aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutree_plugin.h
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rcutree_plugin.h')
-rw-r--r--kernel/rcutree_plugin.h24
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);
1635extern int tick_nohz_enabled; 1635extern 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 */
1642static bool rcu_try_advance_all_cbs(void) 1642static 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 */
1774static void rcu_cleanup_after_idle(int cpu) 1782static 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/*