diff options
-rw-r--r-- | kernel/rcutree.h | 1 | ||||
-rw-r--r-- | kernel/rcutree_plugin.h | 15 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 2 |
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 | ||
1974 | extern 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 | */ |
108 | static int tick_nohz_enabled __read_mostly = 1; | 108 | int tick_nohz_enabled __read_mostly = 1; |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * Enable / Disable tickless mode | 111 | * Enable / Disable tickless mode |