]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/sched/sched.h
sched: Spare resched IPI when prio changes on a single fair task
[linux.git] / kernel / sched / sched.h
index 0db2c1b3361e03077d3971876f9dc06cf9bbb027..280a3c73593559d0d68fca27dc16f18dfafc8c5b 100644 (file)
@@ -1713,24 +1713,13 @@ struct sched_class {
 
        void (*check_preempt_curr)(struct rq *rq, struct task_struct *p, int flags);
 
-       /*
-        * Both @prev and @rf are optional and may be NULL, in which case the
-        * caller must already have invoked put_prev_task(rq, prev, rf).
-        *
-        * Otherwise it is the responsibility of the pick_next_task() to call
-        * put_prev_task() on the @prev task or something equivalent, IFF it
-        * returns a next task.
-        *
-        * In that case (@rf != NULL) it may return RETRY_TASK when it finds a
-        * higher prio class has runnable tasks.
-        */
-       struct task_struct * (*pick_next_task)(struct rq *rq,
-                                              struct task_struct *prev,
-                                              struct rq_flags *rf);
-       void (*put_prev_task)(struct rq *rq, struct task_struct *p, struct rq_flags *rf);
-       void (*set_next_task)(struct rq *rq, struct task_struct *p);
+       struct task_struct *(*pick_next_task)(struct rq *rq);
+
+       void (*put_prev_task)(struct rq *rq, struct task_struct *p);
+       void (*set_next_task)(struct rq *rq, struct task_struct *p, bool first);
 
 #ifdef CONFIG_SMP
+       int (*balance)(struct rq *rq, struct task_struct *prev, struct rq_flags *rf);
        int  (*select_task_rq)(struct task_struct *p, int task_cpu, int sd_flag, int flags);
        void (*migrate_task_rq)(struct task_struct *p, int new_cpu);
 
@@ -1773,13 +1762,13 @@ struct sched_class {
 static inline void put_prev_task(struct rq *rq, struct task_struct *prev)
 {
        WARN_ON_ONCE(rq->curr != prev);
-       prev->sched_class->put_prev_task(rq, prev, NULL);
+       prev->sched_class->put_prev_task(rq, prev);
 }
 
 static inline void set_next_task(struct rq *rq, struct task_struct *next)
 {
        WARN_ON_ONCE(rq->curr != next);
-       next->sched_class->set_next_task(rq, next);
+       next->sched_class->set_next_task(rq, next, false);
 }
 
 #ifdef CONFIG_SMP
@@ -1787,8 +1776,12 @@ static inline void set_next_task(struct rq *rq, struct task_struct *next)
 #else
 #define sched_class_highest (&dl_sched_class)
 #endif
+
+#define for_class_range(class, _from, _to) \
+       for (class = (_from); class != (_to); class = class->next)
+
 #define for_each_class(class) \
-   for (class = sched_class_highest; class; class = class->next)
+       for_class_range(class, sched_class_highest, NULL)
 
 extern const struct sched_class stop_sched_class;
 extern const struct sched_class dl_sched_class;
@@ -1796,6 +1789,28 @@ extern const struct sched_class rt_sched_class;
 extern const struct sched_class fair_sched_class;
 extern const struct sched_class idle_sched_class;
 
+static inline bool sched_stop_runnable(struct rq *rq)
+{
+       return rq->stop && task_on_rq_queued(rq->stop);
+}
+
+static inline bool sched_dl_runnable(struct rq *rq)
+{
+       return rq->dl.dl_nr_running > 0;
+}
+
+static inline bool sched_rt_runnable(struct rq *rq)
+{
+       return rq->rt.rt_queued > 0;
+}
+
+static inline bool sched_fair_runnable(struct rq *rq)
+{
+       return rq->cfs.nr_running > 0;
+}
+
+extern struct task_struct *pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf);
+extern struct task_struct *pick_next_task_idle(struct rq *rq);
 
 #ifdef CONFIG_SMP
 
@@ -2285,7 +2300,7 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {}
 #endif /* CONFIG_CPU_FREQ */
 
 #ifdef CONFIG_UCLAMP_TASK
-enum uclamp_id uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id);
+unsigned int uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id);
 
 static __always_inline
 unsigned int uclamp_util_with(struct rq *rq, unsigned int util,