From: Rafael J. Wysocki Date: Wed, 11 Apr 2018 11:22:46 +0000 (+0200) Subject: Merge branches 'pm-cpuidle' and 'pm-qos' X-Git-Tag: v4.17-rc1~46^2 X-Git-Url: https://repo.jachan.dev/linux.git/commitdiff_plain/51798deaffb738ef3bdd4f544b11ce2adaff40f3 Merge branches 'pm-cpuidle' and 'pm-qos' * pm-cpuidle: tick-sched: avoid a maybe-uninitialized warning cpuidle: Add definition of residency to sysfs documentation time: hrtimer: Use timerqueue_iterate_next() to get to the next timer nohz: Avoid duplication of code related to got_idle_tick nohz: Gather tick_sched booleans under a common flag field cpuidle: menu: Avoid selecting shallow states with stopped tick cpuidle: menu: Refine idle state selection for running tick sched: idle: Select idle state before stopping the tick time: hrtimer: Introduce hrtimer_next_event_without() time: tick-sched: Split tick_nohz_stop_sched_tick() cpuidle: Return nohz hint from cpuidle_select() jiffies: Introduce USER_TICK_USEC and redefine TICK_USEC sched: idle: Do not stop the tick before cpuidle_idle_call() sched: idle: Do not stop the tick upfront in the idle loop time: tick-sched: Reorganize idle tick management code * pm-qos: PM / QoS: mark expected switch fall-throughs --- 51798deaffb738ef3bdd4f544b11ce2adaff40f3 diff --cc kernel/time/tick-sched.c index f3ab08caa2c3,e35a6fced00c,5d4a0342f934..646645e981f9 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@@@ -978,11 -1031,37 -969,11 +1040,37 @@@@ bool tick_nohz_idle_got_tick(void * * Called from power state control code with interrupts disabled */ - -ktime_t tick_nohz_get_sleep_length(void) + +ktime_t tick_nohz_get_sleep_length(ktime_t *delta_next) { + + struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev); struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched); + + int cpu = smp_processor_id(); + + /* + + * The idle entry time is expected to be a sufficient approximation of + + * the current time at this point. + + */ + + ktime_t now = ts->idle_entrytime; + + ktime_t next_event; + + + + WARN_ON_ONCE(!ts->inidle); + + + + *delta_next = ktime_sub(dev->next_event, now); + - return ts->sleep_length; + + if (!can_stop_idle_tick(cpu, ts)) + + return *delta_next; + + + + next_event = tick_nohz_next_event(ts, cpu); + + if (!next_event) + + return *delta_next; + + + + /* + + * If the next highres timer to expire is earlier than next_event, the + + * idle governor needs to know that. + + */ + + next_event = min_t(u64, next_event, + + hrtimer_next_event_without(&ts->sched_timer)); + - return ts->sleep_length; + + return ktime_sub(next_event, now); } /**