|
@@ -1279,6 +1279,35 @@ unsigned long to_ratio(u64 period, u64 runtime);
|
|
|
|
|
|
extern void init_entity_runnable_average(struct sched_entity *se);
|
|
|
|
|
|
+#ifdef CONFIG_NO_HZ_FULL
|
|
|
+extern bool sched_can_stop_tick(struct rq *rq);
|
|
|
+
|
|
|
+/*
|
|
|
+ * Tick may be needed by tasks in the runqueue depending on their policy and
|
|
|
+ * requirements. If tick is needed, lets send the target an IPI to kick it out of
|
|
|
+ * nohz mode if necessary.
|
|
|
+ */
|
|
|
+static inline void sched_update_tick_dependency(struct rq *rq)
|
|
|
+{
|
|
|
+ int cpu;
|
|
|
+
|
|
|
+ if (!tick_nohz_full_enabled())
|
|
|
+ return;
|
|
|
+
|
|
|
+ cpu = cpu_of(rq);
|
|
|
+
|
|
|
+ if (!tick_nohz_full_cpu(cpu))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (sched_can_stop_tick(rq))
|
|
|
+ tick_nohz_dep_clear_cpu(cpu, TICK_DEP_BIT_SCHED);
|
|
|
+ else
|
|
|
+ tick_nohz_dep_set_cpu(cpu, TICK_DEP_BIT_SCHED);
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline void sched_update_tick_dependency(struct rq *rq) { }
|
|
|
+#endif
|
|
|
+
|
|
|
static inline void add_nr_running(struct rq *rq, unsigned count)
|
|
|
{
|
|
|
unsigned prev_nr = rq->nr_running;
|
|
@@ -1290,26 +1319,16 @@ static inline void add_nr_running(struct rq *rq, unsigned count)
|
|
|
if (!rq->rd->overload)
|
|
|
rq->rd->overload = true;
|
|
|
#endif
|
|
|
-
|
|
|
-#ifdef CONFIG_NO_HZ_FULL
|
|
|
- if (tick_nohz_full_cpu(rq->cpu)) {
|
|
|
- /*
|
|
|
- * Tick is needed if more than one task runs on a CPU.
|
|
|
- * Send the target an IPI to kick it out of nohz mode.
|
|
|
- *
|
|
|
- * We assume that IPI implies full memory barrier and the
|
|
|
- * new value of rq->nr_running is visible on reception
|
|
|
- * from the target.
|
|
|
- */
|
|
|
- tick_nohz_full_kick_cpu(rq->cpu);
|
|
|
- }
|
|
|
-#endif
|
|
|
}
|
|
|
+
|
|
|
+ sched_update_tick_dependency(rq);
|
|
|
}
|
|
|
|
|
|
static inline void sub_nr_running(struct rq *rq, unsigned count)
|
|
|
{
|
|
|
rq->nr_running -= count;
|
|
|
+ /* Check if we still need preemption */
|
|
|
+ sched_update_tick_dependency(rq);
|
|
|
}
|
|
|
|
|
|
static inline void rq_last_tick_reset(struct rq *rq)
|