summaryrefslogtreecommitdiff
path: root/kernel/sched
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:01:15 +1100
commitb58a31f603e03064f2f9517e25901fd0694f9d36 (patch)
treeff9330aaaa29a774f936d10f24f9d61d8d822734 /kernel/sched
parent10b6fffc3aa173a3b86d4f359e17529085cddefe (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/sched')
-rw-r--r--kernel/sched/MuQSS.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/kernel/sched/MuQSS.c b/kernel/sched/MuQSS.c
index f1301160fda6..40e047013f2e 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) || \