diff options
author | ckolivas <kernel@kolivas.org> | 2016-10-26 20:14:23 +1100 |
---|---|---|
committer | Con Kolivas <kernel@kolivas.org> | 2016-10-27 14:06:09 +1100 |
commit | 76753a65c9e0c15dde1d54b86e88a4b30e77f2cc (patch) | |
tree | 2478fbb136ab29591d5915775861a09d317dcf1d /kernel | |
parent | 30f02b7736860c0109c8c245310567d6ea675c51 (diff) |
Create full nohz support regardless of load when highres timers are active since we are not dependent on the timer tick at all.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/MuQSS.c | 55 | ||||
-rw-r--r-- | kernel/time/Kconfig | 3 |
2 files changed, 57 insertions, 1 deletions
diff --git a/kernel/sched/MuQSS.c b/kernel/sched/MuQSS.c index 869626024d56..0f2a72c1917b 100644 --- a/kernel/sched/MuQSS.c +++ b/kernel/sched/MuQSS.c @@ -3608,6 +3608,60 @@ out_resched: rq_unlock(rq); } +#ifdef CONFIG_NO_HZ_FULL +/* + * We can stop the timer tick any time highres timers are active since + * we rely entirely on highres timeouts for task expiry rescheduling. + */ +static void sched_stop_tick(struct rq *rq, int cpu) +{ + if (!hrexpiry_enabled(rq)) + return; + if (!tick_nohz_full_enabled()) + return; + if (!tick_nohz_full_cpu(cpu)) + return; + tick_nohz_dep_clear_cpu(cpu, TICK_DEP_BIT_SCHED); +} + +static void sched_start_tick(struct rq *rq, int cpu) +{ + tick_nohz_dep_set_cpu(cpu, TICK_DEP_BIT_SCHED); +} + +/** + * scheduler_tick_max_deferment + * + * Keep at least one tick per second when a single + * active task is running. + * + * This makes sure that uptime continues to move forward, even + * with a very low granularity. + * + * Return: Maximum deferment in nanoseconds. + */ +u64 scheduler_tick_max_deferment(void) +{ + struct rq *rq = this_rq(); + unsigned long next, now = READ_ONCE(jiffies); + + next = rq->last_jiffy + HZ; + + if (time_before_eq(next, now)) + return 0; + + return jiffies_to_nsecs(next - now); +} +#else +static inline void sched_stop_tick(struct rq *rq, int cpu) +{ +} + +static inline void sched_start_tick(struct rq *rq, int cpu) +{ +} +#endif + /* * This function gets called by the timer code, with HZ frequency. * We call it with interrupts disabled. @@ -3628,6 +3682,7 @@ void scheduler_tick(void) rq->last_scheduler_tick = rq->last_jiffy; rq->last_tick = rq->clock; perf_event_task_tick(); + sched_stop_tick(rq, cpu); } #if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index 10e18d267675..029afbd378ae 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig @@ -89,12 +89,13 @@ config NO_HZ_IDLE config NO_HZ_FULL bool "Full dynticks system (tickless)" # NO_HZ_COMMON dependency - depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS && !SCHED_MUQSS + depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS # We need at least one periodic CPU for timekeeping depends on SMP depends on HAVE_CONTEXT_TRACKING # VIRT_CPU_ACCOUNTING_GEN dependency depends on HAVE_VIRT_CPU_ACCOUNTING_GEN + select CONTEXT_TRACKING select NO_HZ_COMMON select RCU_NOCB_CPU select VIRT_CPU_ACCOUNTING_GEN |