From 51febc58ca1cfecdc213a000f404423e375b3005 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Thu, 11 Mar 2010 17:17:13 +0100 Subject: [PATCH] --- yaml --- r: 191383 b: refs/heads/master c: 39c0cbe2150cbd848a25ba6cdb271d1ad46818ad h: refs/heads/master i: 191381: 03d92611fc5e4a3226007471581fbc25a4c55b02 191379: 435ea04c02c55ad875d413c138fd3ff1e08c38c6 191375: 16524d549f713a1fe1d81f77991975e1f3861a10 v: v3 --- [refs] | 2 +- trunk/include/linux/sched.h | 6 ++++++ trunk/kernel/sched.c | 12 ++++++++++++ trunk/kernel/time/tick-sched.c | 3 +++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 5f6a29b53cab..12187934018a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 41acab8851a0408c1d5ad6c21a07456f88b54d40 +refs/heads/master: 39c0cbe2150cbd848a25ba6cdb271d1ad46818ad diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 8cc863d66477..13efe7dac5fa 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -271,11 +271,17 @@ extern cpumask_var_t nohz_cpu_mask; #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) extern int select_nohz_load_balancer(int cpu); extern int get_nohz_load_balancer(void); +extern int nohz_ratelimit(int cpu); #else static inline int select_nohz_load_balancer(int cpu) { return 0; } + +static inline int nohz_ratelimit(int cpu) +{ + return 0; +} #endif /* diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index a4aa071f08f3..60b1bbe2ad1b 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -492,6 +492,7 @@ struct rq { #define CPU_LOAD_IDX_MAX 5 unsigned long cpu_load[CPU_LOAD_IDX_MAX]; #ifdef CONFIG_NO_HZ + u64 nohz_stamp; unsigned char in_nohz_recently; #endif /* capture load from *all* tasks on this cpu: */ @@ -1228,6 +1229,17 @@ void wake_up_idle_cpu(int cpu) if (!tsk_is_polling(rq->idle)) smp_send_reschedule(cpu); } + +int nohz_ratelimit(int cpu) +{ + struct rq *rq = cpu_rq(cpu); + u64 diff = rq->clock - rq->nohz_stamp; + + rq->nohz_stamp = rq->clock; + + return diff < (NSEC_PER_SEC / HZ) >> 1; +} + #endif /* CONFIG_NO_HZ */ static u64 sched_avg_period(void) diff --git a/trunk/kernel/time/tick-sched.c b/trunk/kernel/time/tick-sched.c index f992762d7f51..f25735a767af 100644 --- a/trunk/kernel/time/tick-sched.c +++ b/trunk/kernel/time/tick-sched.c @@ -262,6 +262,9 @@ void tick_nohz_stop_sched_tick(int inidle) goto end; } + if (nohz_ratelimit(cpu)) + goto end; + ts->idle_calls++; /* Read jiffies and the time when jiffies were updated last */ do {