diff options
-rw-r--r-- | include/linux/sched.h | 6 | ||||
-rw-r--r-- | kernel/sched.c | 12 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 3 |
3 files changed, 21 insertions, 0 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 8cc863d66477..13efe7dac5fa 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -271,11 +271,17 @@ extern cpumask_var_t nohz_cpu_mask; | |||
271 | #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) | 271 | #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) |
272 | extern int select_nohz_load_balancer(int cpu); | 272 | extern int select_nohz_load_balancer(int cpu); |
273 | extern int get_nohz_load_balancer(void); | 273 | extern int get_nohz_load_balancer(void); |
274 | extern int nohz_ratelimit(int cpu); | ||
274 | #else | 275 | #else |
275 | static inline int select_nohz_load_balancer(int cpu) | 276 | static inline int select_nohz_load_balancer(int cpu) |
276 | { | 277 | { |
277 | return 0; | 278 | return 0; |
278 | } | 279 | } |
280 | |||
281 | static inline int nohz_ratelimit(int cpu) | ||
282 | { | ||
283 | return 0; | ||
284 | } | ||
279 | #endif | 285 | #endif |
280 | 286 | ||
281 | /* | 287 | /* |
diff --git a/kernel/sched.c b/kernel/sched.c index a4aa071f08f3..60b1bbe2ad1b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -492,6 +492,7 @@ struct rq { | |||
492 | #define CPU_LOAD_IDX_MAX 5 | 492 | #define CPU_LOAD_IDX_MAX 5 |
493 | unsigned long cpu_load[CPU_LOAD_IDX_MAX]; | 493 | unsigned long cpu_load[CPU_LOAD_IDX_MAX]; |
494 | #ifdef CONFIG_NO_HZ | 494 | #ifdef CONFIG_NO_HZ |
495 | u64 nohz_stamp; | ||
495 | unsigned char in_nohz_recently; | 496 | unsigned char in_nohz_recently; |
496 | #endif | 497 | #endif |
497 | /* capture load from *all* tasks on this cpu: */ | 498 | /* capture load from *all* tasks on this cpu: */ |
@@ -1228,6 +1229,17 @@ void wake_up_idle_cpu(int cpu) | |||
1228 | if (!tsk_is_polling(rq->idle)) | 1229 | if (!tsk_is_polling(rq->idle)) |
1229 | smp_send_reschedule(cpu); | 1230 | smp_send_reschedule(cpu); |
1230 | } | 1231 | } |
1232 | |||
1233 | int nohz_ratelimit(int cpu) | ||
1234 | { | ||
1235 | struct rq *rq = cpu_rq(cpu); | ||
1236 | u64 diff = rq->clock - rq->nohz_stamp; | ||
1237 | |||
1238 | rq->nohz_stamp = rq->clock; | ||
1239 | |||
1240 | return diff < (NSEC_PER_SEC / HZ) >> 1; | ||
1241 | } | ||
1242 | |||
1231 | #endif /* CONFIG_NO_HZ */ | 1243 | #endif /* CONFIG_NO_HZ */ |
1232 | 1244 | ||
1233 | static u64 sched_avg_period(void) | 1245 | static u64 sched_avg_period(void) |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index f992762d7f51..f25735a767af 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -262,6 +262,9 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
262 | goto end; | 262 | goto end; |
263 | } | 263 | } |
264 | 264 | ||
265 | if (nohz_ratelimit(cpu)) | ||
266 | goto end; | ||
267 | |||
265 | ts->idle_calls++; | 268 | ts->idle_calls++; |
266 | /* Read jiffies and the time when jiffies were updated last */ | 269 | /* Read jiffies and the time when jiffies were updated last */ |
267 | do { | 270 | do { |