]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/sched/sched.h
Merge tag 'selinux-pr-20190801' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / kernel / sched / sched.h
index b52ed1ada0be8bea55bf983028fc896d72b6b473..802b1f3405f247897571aa041035cac97b4d7ddd 100644 (file)
@@ -96,12 +96,6 @@ extern atomic_long_t calc_load_tasks;
 extern void calc_global_load_tick(struct rq *this_rq);
 extern long calc_load_fold_active(struct rq *this_rq, long adjust);
 
-#ifdef CONFIG_SMP
-extern void cpu_load_update_active(struct rq *this_rq);
-#else
-static inline void cpu_load_update_active(struct rq *this_rq) { }
-#endif
-
 /*
  * Helpers for converting nanosecond timing to jiffy resolution
  */
@@ -344,8 +338,10 @@ struct cfs_bandwidth {
        u64                     runtime_expires;
        int                     expires_seq;
 
-       short                   idle;
-       short                   period_active;
+       u8                      idle;
+       u8                      period_active;
+       u8                      distribute_running;
+       u8                      slack_started;
        struct hrtimer          period_timer;
        struct hrtimer          slack_timer;
        struct list_head        throttled_cfs_rq;
@@ -354,8 +350,6 @@ struct cfs_bandwidth {
        int                     nr_periods;
        int                     nr_throttled;
        u64                     throttled_time;
-
-       bool                    distribute_running;
 #endif
 };
 
@@ -797,6 +791,48 @@ extern void rto_push_irq_work_func(struct irq_work *work);
 #endif
 #endif /* CONFIG_SMP */
 
+#ifdef CONFIG_UCLAMP_TASK
+/*
+ * struct uclamp_bucket - Utilization clamp bucket
+ * @value: utilization clamp value for tasks on this clamp bucket
+ * @tasks: number of RUNNABLE tasks on this clamp bucket
+ *
+ * Keep track of how many tasks are RUNNABLE for a given utilization
+ * clamp value.
+ */
+struct uclamp_bucket {
+       unsigned long value : bits_per(SCHED_CAPACITY_SCALE);
+       unsigned long tasks : BITS_PER_LONG - bits_per(SCHED_CAPACITY_SCALE);
+};
+
+/*
+ * struct uclamp_rq - rq's utilization clamp
+ * @value: currently active clamp values for a rq
+ * @bucket: utilization clamp buckets affecting a rq
+ *
+ * Keep track of RUNNABLE tasks on a rq to aggregate their clamp values.
+ * A clamp value is affecting a rq when there is at least one task RUNNABLE
+ * (or actually running) with that value.
+ *
+ * There are up to UCLAMP_CNT possible different clamp values, currently there
+ * are only two: minimum utilization and maximum utilization.
+ *
+ * All utilization clamping values are MAX aggregated, since:
+ * - for util_min: we want to run the CPU at least at the max of the minimum
+ *   utilization required by its currently RUNNABLE tasks.
+ * - for util_max: we want to allow the CPU to run up to the max of the
+ *   maximum utilization allowed by its currently RUNNABLE tasks.
+ *
+ * Since on each system we expect only a limited number of different
+ * utilization clamp values (UCLAMP_BUCKETS), use a simple array to track
+ * the metrics required to compute all the per-rq utilization clamp values.
+ */
+struct uclamp_rq {
+       unsigned int value;
+       struct uclamp_bucket bucket[UCLAMP_BUCKETS];
+};
+#endif /* CONFIG_UCLAMP_TASK */
+
 /*
  * This is the main, per-CPU runqueue data structure.
  *
@@ -818,8 +854,6 @@ struct rq {
        unsigned int            nr_preferred_running;
        unsigned int            numa_migrate_on;
 #endif
-       #define CPU_LOAD_IDX_MAX 5
-       unsigned long           cpu_load[CPU_LOAD_IDX_MAX];
 #ifdef CONFIG_NO_HZ_COMMON
 #ifdef CONFIG_SMP
        unsigned long           last_load_update_tick;
@@ -830,11 +864,16 @@ struct rq {
        atomic_t nohz_flags;
 #endif /* CONFIG_NO_HZ_COMMON */
 
-       /* capture load from *all* tasks on this CPU: */
-       struct load_weight      load;
        unsigned long           nr_load_updates;
        u64                     nr_switches;
 
+#ifdef CONFIG_UCLAMP_TASK
+       /* Utilization clamp values based on CPU's RUNNABLE tasks */
+       struct uclamp_rq        uclamp[UCLAMP_CNT] ____cacheline_aligned;
+       unsigned int            uclamp_flags;
+#define UCLAMP_FLAG_IDLE 0x01
+#endif
+
        struct cfs_rq           cfs;
        struct rt_rq            rt;
        struct dl_rq            dl;
@@ -1649,6 +1688,10 @@ extern const u32         sched_prio_to_wmult[40];
 struct sched_class {
        const struct sched_class *next;
 
+#ifdef CONFIG_UCLAMP_TASK
+       int uclamp_enabled;
+#endif
+
        void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
        void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
        void (*yield_task)   (struct rq *rq);
@@ -2222,6 +2265,48 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
 static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {}
 #endif /* CONFIG_CPU_FREQ */
 
+#ifdef CONFIG_UCLAMP_TASK
+unsigned int uclamp_eff_value(struct task_struct *p, unsigned int clamp_id);
+
+static __always_inline
+unsigned int uclamp_util_with(struct rq *rq, unsigned int util,
+                             struct task_struct *p)
+{
+       unsigned int min_util = READ_ONCE(rq->uclamp[UCLAMP_MIN].value);
+       unsigned int max_util = READ_ONCE(rq->uclamp[UCLAMP_MAX].value);
+
+       if (p) {
+               min_util = max(min_util, uclamp_eff_value(p, UCLAMP_MIN));
+               max_util = max(max_util, uclamp_eff_value(p, UCLAMP_MAX));
+       }
+
+       /*
+        * Since CPU's {min,max}_util clamps are MAX aggregated considering
+        * RUNNABLE tasks with _different_ clamps, we can end up with an
+        * inversion. Fix it now when the clamps are applied.
+        */
+       if (unlikely(min_util >= max_util))
+               return min_util;
+
+       return clamp(util, min_util, max_util);
+}
+
+static inline unsigned int uclamp_util(struct rq *rq, unsigned int util)
+{
+       return uclamp_util_with(rq, util, NULL);
+}
+#else /* CONFIG_UCLAMP_TASK */
+static inline unsigned int uclamp_util_with(struct rq *rq, unsigned int util,
+                                           struct task_struct *p)
+{
+       return util;
+}
+static inline unsigned int uclamp_util(struct rq *rq, unsigned int util)
+{
+       return util;
+}
+#endif /* CONFIG_UCLAMP_TASK */
+
 #ifdef arch_scale_freq_capacity
 # ifndef arch_scale_freq_invariant
 #  define arch_scale_freq_invariant()  true
@@ -2237,7 +2322,6 @@ static inline unsigned long capacity_orig_of(int cpu)
 }
 #endif
 
-#ifdef CONFIG_CPU_FREQ_GOV_SCHEDUTIL
 /**
  * enum schedutil_type - CPU utilization type
  * @FREQUENCY_UTIL:    Utilization used to select frequency
@@ -2253,15 +2337,11 @@ enum schedutil_type {
        ENERGY_UTIL,
 };
 
-unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs,
-                                 unsigned long max, enum schedutil_type type);
-
-static inline unsigned long schedutil_energy_util(int cpu, unsigned long cfs)
-{
-       unsigned long max = arch_scale_cpu_capacity(NULL, cpu);
+#ifdef CONFIG_CPU_FREQ_GOV_SCHEDUTIL
 
-       return schedutil_freq_util(cpu, cfs, max, ENERGY_UTIL);
-}
+unsigned long schedutil_cpu_util(int cpu, unsigned long util_cfs,
+                                unsigned long max, enum schedutil_type type,
+                                struct task_struct *p);
 
 static inline unsigned long cpu_bw_dl(struct rq *rq)
 {
@@ -2290,11 +2370,13 @@ static inline unsigned long cpu_util_rt(struct rq *rq)
        return READ_ONCE(rq->avg_rt.util_avg);
 }
 #else /* CONFIG_CPU_FREQ_GOV_SCHEDUTIL */
-static inline unsigned long schedutil_energy_util(int cpu, unsigned long cfs)
+static inline unsigned long schedutil_cpu_util(int cpu, unsigned long util_cfs,
+                                unsigned long max, enum schedutil_type type,
+                                struct task_struct *p)
 {
-       return cfs;
+       return 0;
 }
-#endif
+#endif /* CONFIG_CPU_FREQ_GOV_SCHEDUTIL */
 
 #ifdef CONFIG_HAVE_SCHED_AVG_IRQ
 static inline unsigned long cpu_util_irq(struct rq *rq)