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 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);
1630extern int tick_nohz_enabled; 1630extern 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 */
1637static bool rcu_try_advance_all_cbs(void) 1637static 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 */
1769static void rcu_cleanup_after_idle(int cpu) 1777static 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/*