aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sched.h6
-rw-r--r--kernel/sched.c12
-rw-r--r--kernel/time/tick-sched.c3
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)
272extern int select_nohz_load_balancer(int cpu); 272extern int select_nohz_load_balancer(int cpu);
273extern int get_nohz_load_balancer(void); 273extern int get_nohz_load_balancer(void);
274extern int nohz_ratelimit(int cpu);
274#else 275#else
275static inline int select_nohz_load_balancer(int cpu) 276static inline int select_nohz_load_balancer(int cpu)
276{ 277{
277 return 0; 278 return 0;
278} 279}
280
281static 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
1233int 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
1233static u64 sched_avg_period(void) 1245static 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 {