diff options
Diffstat (limited to 'kernel/time/tick-sched.c')
| -rw-r--r-- | kernel/time/tick-sched.c | 27 | 
1 files changed, 21 insertions, 6 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 7a46bde78c6..a4d21939816 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -20,6 +20,7 @@  #include <linux/profile.h>  #include <linux/sched.h>  #include <linux/tick.h> +#include <linux/module.h>  #include <asm/irq_regs.h> @@ -75,6 +76,9 @@ static void tick_do_update_jiffies64(ktime_t now)  							   incr * ticks);  		}  		do_timer(++ticks); + +		/* Keep the tick_next_period variable up to date */ +		tick_next_period = ktime_add(last_jiffies_update, tick_period);  	}  	write_sequnlock(&xtime_lock);  } @@ -162,6 +166,8 @@ void tick_nohz_stop_idle(int cpu)  		ts->idle_lastupdate = now;  		ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);  		ts->idle_active = 0; + +		sched_clock_idle_wakeup_event(0);  	}  } @@ -177,6 +183,7 @@ static ktime_t tick_nohz_start_idle(struct tick_sched *ts)  	}  	ts->idle_entrytime = now;  	ts->idle_active = 1; +	sched_clock_idle_sleep_event();  	return now;  } @@ -184,9 +191,17 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)  {  	struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); -	*last_update_time = ktime_to_us(ts->idle_lastupdate); +	if (!tick_nohz_enabled) +		return -1; + +	if (ts->idle_active) +		*last_update_time = ktime_to_us(ts->idle_lastupdate); +	else +		*last_update_time = ktime_to_us(ktime_get()); +  	return ktime_to_us(ts->idle_sleeptime);  } +EXPORT_SYMBOL_GPL(get_cpu_idle_time_us);  /**   * tick_nohz_stop_sched_tick - stop the idle tick from the idle task @@ -218,7 +233,7 @@ void tick_nohz_stop_sched_tick(int inidle)  	 */  	if (unlikely(!cpu_online(cpu))) {  		if (cpu == tick_do_timer_cpu) -			tick_do_timer_cpu = -1; +			tick_do_timer_cpu = TICK_DO_TIMER_NONE;  	}  	if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) @@ -300,7 +315,7 @@ void tick_nohz_stop_sched_tick(int inidle)  		 * invoked.  		 */  		if (cpu == tick_do_timer_cpu) -			tick_do_timer_cpu = -1; +			tick_do_timer_cpu = TICK_DO_TIMER_NONE;  		ts->idle_sleeps++; @@ -465,7 +480,7 @@ static void tick_nohz_handler(struct clock_event_device *dev)  	 * this duty, then the jiffies update is still serialized by  	 * xtime_lock.  	 */ -	if (unlikely(tick_do_timer_cpu == -1)) +	if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))  		tick_do_timer_cpu = cpu;  	/* Check, if the jiffies need an update */ @@ -567,7 +582,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)  	 * this duty, then the jiffies update is still serialized by  	 * xtime_lock.  	 */ -	if (unlikely(tick_do_timer_cpu == -1)) +	if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))  		tick_do_timer_cpu = cpu;  #endif @@ -619,7 +634,7 @@ void tick_setup_sched_timer(void)  	 */  	hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);  	ts->sched_timer.function = tick_sched_timer; -	ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; +	ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;  	/* Get the next period (per cpu) */  	ts->sched_timer.expires = tick_init_jiffy_update();  | 
