]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/sched/sched.h
Merge branches 'pm-core', 'pm-qos', 'pm-domains' and 'pm-opp'
[linux.git] / kernel / sched / sched.h
index 98e7eee07237823849e058f87e6ad8ecf0f10b19..71b10a9b73cfe290b2545dfd3cd10a49d0af2cc9 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/sched/rt.h>
 #include <linux/u64_stats_sync.h>
 #include <linux/sched/deadline.h>
+#include <linux/kernel_stat.h>
 #include <linux/binfmts.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
@@ -222,7 +223,7 @@ bool __dl_overflow(struct dl_bw *dl_b, int cpus, u64 old_bw, u64 new_bw)
               dl_b->bw * cpus < dl_b->total_bw - old_bw + new_bw;
 }
 
-extern struct mutex sched_domains_mutex;
+extern void init_dl_bw(struct dl_bw *dl_b);
 
 #ifdef CONFIG_CGROUP_SCHED
 
@@ -583,6 +584,13 @@ struct root_domain {
 };
 
 extern struct root_domain def_root_domain;
+extern struct mutex sched_domains_mutex;
+extern cpumask_var_t fallback_doms;
+extern cpumask_var_t sched_domains_tmpmask;
+
+extern void init_defrootdomain(void);
+extern int init_sched_domains(const struct cpumask *cpu_map);
+extern void rq_attach_root(struct rq *rq, struct root_domain *rd);
 
 #endif /* CONFIG_SMP */
 
@@ -644,7 +652,7 @@ struct rq {
        unsigned long next_balance;
        struct mm_struct *prev_mm;
 
-       unsigned int clock_skip_update;
+       unsigned int clock_update_flags;
        u64 clock;
        u64 clock_task;
 
@@ -768,48 +776,110 @@ static inline u64 __rq_clock_broken(struct rq *rq)
        return READ_ONCE(rq->clock);
 }
 
+/*
+ * rq::clock_update_flags bits
+ *
+ * %RQCF_REQ_SKIP - will request skipping of clock update on the next
+ *  call to __schedule(). This is an optimisation to avoid
+ *  neighbouring rq clock updates.
+ *
+ * %RQCF_ACT_SKIP - is set from inside of __schedule() when skipping is
+ *  in effect and calls to update_rq_clock() are being ignored.
+ *
+ * %RQCF_UPDATED - is a debug flag that indicates whether a call has been
+ *  made to update_rq_clock() since the last time rq::lock was pinned.
+ *
+ * If inside of __schedule(), clock_update_flags will have been
+ * shifted left (a left shift is a cheap operation for the fast path
+ * to promote %RQCF_REQ_SKIP to %RQCF_ACT_SKIP), so you must use,
+ *
+ *     if (rq-clock_update_flags >= RQCF_UPDATED)
+ *
+ * to check if %RQCF_UPADTED is set. It'll never be shifted more than
+ * one position though, because the next rq_unpin_lock() will shift it
+ * back.
+ */
+#define RQCF_REQ_SKIP  0x01
+#define RQCF_ACT_SKIP  0x02
+#define RQCF_UPDATED   0x04
+
+static inline void assert_clock_updated(struct rq *rq)
+{
+       /*
+        * The only reason for not seeing a clock update since the
+        * last rq_pin_lock() is if we're currently skipping updates.
+        */
+       SCHED_WARN_ON(rq->clock_update_flags < RQCF_ACT_SKIP);
+}
+
 static inline u64 rq_clock(struct rq *rq)
 {
        lockdep_assert_held(&rq->lock);
+       assert_clock_updated(rq);
+
        return rq->clock;
 }
 
 static inline u64 rq_clock_task(struct rq *rq)
 {
        lockdep_assert_held(&rq->lock);
+       assert_clock_updated(rq);
+
        return rq->clock_task;
 }
 
-#define RQCF_REQ_SKIP  0x01
-#define RQCF_ACT_SKIP  0x02
-
 static inline void rq_clock_skip_update(struct rq *rq, bool skip)
 {
        lockdep_assert_held(&rq->lock);
        if (skip)
-               rq->clock_skip_update |= RQCF_REQ_SKIP;
+               rq->clock_update_flags |= RQCF_REQ_SKIP;
        else
-               rq->clock_skip_update &= ~RQCF_REQ_SKIP;
+               rq->clock_update_flags &= ~RQCF_REQ_SKIP;
 }
 
 struct rq_flags {
        unsigned long flags;
        struct pin_cookie cookie;
+#ifdef CONFIG_SCHED_DEBUG
+       /*
+        * A copy of (rq::clock_update_flags & RQCF_UPDATED) for the
+        * current pin context is stashed here in case it needs to be
+        * restored in rq_repin_lock().
+        */
+       unsigned int clock_update_flags;
+#endif
 };
 
 static inline void rq_pin_lock(struct rq *rq, struct rq_flags *rf)
 {
        rf->cookie = lockdep_pin_lock(&rq->lock);
+
+#ifdef CONFIG_SCHED_DEBUG
+       rq->clock_update_flags &= (RQCF_REQ_SKIP|RQCF_ACT_SKIP);
+       rf->clock_update_flags = 0;
+#endif
 }
 
 static inline void rq_unpin_lock(struct rq *rq, struct rq_flags *rf)
 {
+#ifdef CONFIG_SCHED_DEBUG
+       if (rq->clock_update_flags > RQCF_ACT_SKIP)
+               rf->clock_update_flags = RQCF_UPDATED;
+#endif
+
        lockdep_unpin_lock(&rq->lock, rf->cookie);
 }
 
 static inline void rq_repin_lock(struct rq *rq, struct rq_flags *rf)
 {
        lockdep_repin_lock(&rq->lock, rf->cookie);
+
+#ifdef CONFIG_SCHED_DEBUG
+       /*
+        * Restore the value we stashed in @rf for this pin context.
+        */
+       rq->clock_update_flags |= rf->clock_update_flags;
+#endif
 }
 
 #ifdef CONFIG_NUMA
@@ -823,6 +893,16 @@ extern int sched_max_numa_distance;
 extern bool find_numa_distance(int distance);
 #endif
 
+#ifdef CONFIG_NUMA
+extern void sched_init_numa(void);
+extern void sched_domains_numa_masks_set(unsigned int cpu);
+extern void sched_domains_numa_masks_clear(unsigned int cpu);
+#else
+static inline void sched_init_numa(void) { }
+static inline void sched_domains_numa_masks_set(unsigned int cpu) { }
+static inline void sched_domains_numa_masks_clear(unsigned int cpu) { }
+#endif
+
 #ifdef CONFIG_NUMA_BALANCING
 /* The regions in numa_faults array from task_struct */
 enum numa_faults_stats {
@@ -989,7 +1069,7 @@ static inline void sched_ttwu_pending(void) { }
 #endif /* CONFIG_SMP */
 
 #include "stats.h"
-#include "auto_group.h"
+#include "autogroup.h"
 
 #ifdef CONFIG_CGROUP_SCHED
 
@@ -1689,6 +1769,10 @@ static inline void double_rq_unlock(struct rq *rq1, struct rq *rq2)
                __release(rq2->lock);
 }
 
+extern void set_rq_online (struct rq *rq);
+extern void set_rq_offline(struct rq *rq);
+extern bool sched_smp_initialized;
+
 #else /* CONFIG_SMP */
 
 /*
@@ -1765,8 +1849,7 @@ static inline void nohz_balance_exit_idle(unsigned int cpu) { }
 
 #ifdef CONFIG_IRQ_TIME_ACCOUNTING
 struct irqtime {
-       u64                     hardirq_time;
-       u64                     softirq_time;
+       u64                     tick_delta;
        u64                     irq_start_time;
        struct u64_stats_sync   sync;
 };
@@ -1776,12 +1859,13 @@ DECLARE_PER_CPU(struct irqtime, cpu_irqtime);
 static inline u64 irq_time_read(int cpu)
 {
        struct irqtime *irqtime = &per_cpu(cpu_irqtime, cpu);
+       u64 *cpustat = kcpustat_cpu(cpu).cpustat;
        unsigned int seq;
        u64 total;
 
        do {
                seq = __u64_stats_fetch_begin(&irqtime->sync);
-               total = irqtime->softirq_time + irqtime->hardirq_time;
+               total = cpustat[CPUTIME_SOFTIRQ] + cpustat[CPUTIME_IRQ];
        } while (__u64_stats_fetch_retry(&irqtime->sync, seq));
 
        return total;