summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorckolivas <kernel@kolivas.org>2016-10-26 20:14:23 +1100
committerCon Kolivas <kernel@kolivas.org>2016-10-27 14:06:09 +1100
commit76753a65c9e0c15dde1d54b86e88a4b30e77f2cc (patch)
tree2478fbb136ab29591d5915775861a09d317dcf1d /kernel
parent30f02b7736860c0109c8c245310567d6ea675c51 (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.c55
-rw-r--r--kernel/time/Kconfig3
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