aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/rcutree.h1
-rw-r--r--kernel/rcutree_plugin.h15
-rw-r--r--kernel/time/tick-sched.c2
3 files changed, 17 insertions, 1 deletions
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index 19b61ac1079f..e978845c6800 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -97,6 +97,7 @@ struct rcu_dynticks {
97 /* # times non-lazy CBs posted to CPU. */ 97 /* # times non-lazy CBs posted to CPU. */
98 unsigned long nonlazy_posted_snap; 98 unsigned long nonlazy_posted_snap;
99 /* idle-period nonlazy_posted snapshot. */ 99 /* idle-period nonlazy_posted snapshot. */
100 int tick_nohz_enabled_snap; /* Previously seen value from sysfs. */
100#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ 101#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */
101}; 102};
102 103
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index c28d25522a81..3508000e077d 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -1971,6 +1971,8 @@ static void rcu_idle_count_callbacks_posted(void)
1971#define RCU_IDLE_GP_DELAY 4 /* Roughly one grace period. */ 1971#define RCU_IDLE_GP_DELAY 4 /* Roughly one grace period. */
1972#define RCU_IDLE_LAZY_GP_DELAY (6 * HZ) /* Roughly six seconds. */ 1972#define RCU_IDLE_LAZY_GP_DELAY (6 * HZ) /* Roughly six seconds. */
1973 1973
1974extern int tick_nohz_enabled;
1975
1974/* 1976/*
1975 * Does the specified flavor of RCU have non-lazy callbacks pending on 1977 * Does the specified flavor of RCU have non-lazy callbacks pending on
1976 * the specified CPU? Both RCU flavor and CPU are specified by the 1978 * the specified CPU? Both RCU flavor and CPU are specified by the
@@ -2112,6 +2114,7 @@ static void rcu_cleanup_after_idle(int cpu)
2112 2114
2113 del_timer(&rdtp->idle_gp_timer); 2115 del_timer(&rdtp->idle_gp_timer);
2114 trace_rcu_prep_idle("Cleanup after idle"); 2116 trace_rcu_prep_idle("Cleanup after idle");
2117 rdtp->tick_nohz_enabled_snap = ACCESS_ONCE(tick_nohz_enabled);
2115} 2118}
2116 2119
2117/* 2120/*
@@ -2137,6 +2140,18 @@ static void rcu_prepare_for_idle(int cpu)
2137{ 2140{
2138 struct timer_list *tp; 2141 struct timer_list *tp;
2139 struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu); 2142 struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
2143 int tne;
2144
2145 /* Handle nohz enablement switches conservatively. */
2146 tne = ACCESS_ONCE(tick_nohz_enabled);
2147 if (tne != rdtp->tick_nohz_enabled_snap) {
2148 if (rcu_cpu_has_callbacks(cpu))
2149 invoke_rcu_core(); /* force nohz to see update. */
2150 rdtp->tick_nohz_enabled_snap = tne;
2151 return;
2152 }
2153 if (!tne)
2154 return;
2140 2155
2141 /* 2156 /*
2142 * If this is an idle re-entry, for example, due to use of 2157 * If this is an idle re-entry, for example, due to use of
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 869997833928..66ff07f6184c 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -105,7 +105,7 @@ static ktime_t tick_init_jiffy_update(void)
105/* 105/*
106 * NO HZ enabled ? 106 * NO HZ enabled ?
107 */ 107 */
108static int tick_nohz_enabled __read_mostly = 1; 108int tick_nohz_enabled __read_mostly = 1;
109 109
110/* 110/*
111 * Enable / Disable tickless mode 111 * Enable / Disable tickless mode