From: Dario Faggioli <raist...@linux.it>

Add some typical sched-debug output to dl_rq(s) and some
schedstats to -deadline tasks.

Signed-off-by: Dario Faggioli <raist...@linux.it>
Signed-off-by: Juri Lelli <juri.le...@gmail.com>
---
 include/linux/sched.h   |   13 +++++++++++++
 kernel/sched/deadline.c |   45 +++++++++++++++++++++++++++++++++++++++++++++
 kernel/sched/debug.c    |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 kernel/sched/sched.h    |    9 ++++++++-
 4 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 424f64a..c8bfabc 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1058,6 +1058,15 @@ struct sched_rt_entity {
 #endif
 };
 
+#ifdef CONFIG_SCHEDSTATS
+struct sched_stats_dl {
+       u64                     last_dmiss;
+       u64                     last_rorun;
+       u64                     dmiss_max;
+       u64                     rorun_max;
+};
+#endif
+
 struct sched_dl_entity {
        struct rb_node  rb_node;
 
@@ -1097,6 +1106,10 @@ struct sched_dl_entity {
         * own bandwidth to be enforced, thus we need one timer per task.
         */
        struct hrtimer dl_timer;
+
+#ifdef CONFIG_SCHEDSTATS
+       struct sched_stats_dl stats;
+#endif
 };
 
 struct rcu_node;
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 92546f3..c2381f3 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -517,6 +517,25 @@ int dl_runtime_exceeded(struct rq *rq, struct 
sched_dl_entity *dl_se)
                return 0;
 
        /*
+        * Record statistics about last and maximum deadline
+        * misses and runtime overruns.
+        */
+       if (dmiss) {
+               u64 damount = rq->clock - dl_se->deadline;
+
+               schedstat_set(dl_se->stats.last_dmiss, damount);
+               schedstat_set(dl_se->stats.dmiss_max,
+                             max(dl_se->stats.dmiss_max, damount));
+       }
+       if (rorun) {
+               u64 ramount = -dl_se->runtime;
+
+               schedstat_set(dl_se->stats.last_rorun, ramount);
+               schedstat_set(dl_se->stats.rorun_max,
+                             max(dl_se->stats.rorun_max, ramount));
+       }
+
+       /*
         * If we are beyond our current deadline and we are still
         * executing, then we have already used some of the runtime of
         * the next instance. Thus, if we do not account that, we are
@@ -556,6 +575,7 @@ static void update_curr_dl(struct rq *rq)
                      max(curr->se.statistics.exec_max, delta_exec));
 
        curr->se.sum_exec_runtime += delta_exec;
+       schedstat_add(&rq->dl, exec_clock, delta_exec);
        account_group_exec_runtime(curr, delta_exec);
 
        curr->se.exec_start = rq->clock_task;
@@ -907,6 +927,18 @@ static void start_hrtick_dl(struct rq *rq, struct 
task_struct *p)
 }
 #endif
 
+#ifdef CONFIG_SCHED_DEBUG
+struct sched_dl_entity *__pick_dl_last_entity(struct dl_rq *dl_rq)
+{
+       struct rb_node *last = rb_last(&dl_rq->rb_root);
+
+       if (!last)
+               return NULL;
+
+       return rb_entry(last, struct sched_dl_entity, rb_node);
+}
+#endif /* CONFIG_SCHED_DEBUG */
+
 static struct sched_dl_entity *pick_next_dl_entity(struct rq *rq,
                                                   struct dl_rq *dl_rq)
 {
@@ -1583,3 +1615,16 @@ const struct sched_class dl_sched_class = {
        .switched_from          = switched_from_dl,
        .switched_to            = switched_to_dl,
 };
+
+#ifdef CONFIG_SCHED_DEBUG
+extern void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq *dl_rq);
+
+void print_dl_stats(struct seq_file *m, int cpu)
+{
+       struct dl_rq *dl_rq = &cpu_rq(cpu)->dl;
+
+       rcu_read_lock();
+       print_dl_rq(m, cpu, dl_rq);
+       rcu_read_unlock();
+}
+#endif /* CONFIG_SCHED_DEBUG */
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 1965599..811b025 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -253,6 +253,45 @@ void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq 
*rt_rq)
 #undef P
 }
 
+extern struct sched_dl_entity *__pick_dl_last_entity(struct dl_rq *dl_rq);
+extern void print_dl_stats(struct seq_file *m, int cpu);
+
+void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq *dl_rq)
+{
+       s64 min_deadline = -1, max_deadline = -1;
+       struct rq *rq = cpu_rq(cpu);
+       struct sched_dl_entity *last;
+       unsigned long flags;
+
+       SEQ_printf(m, "\ndl_rq[%d]:\n", cpu);
+
+       raw_spin_lock_irqsave(&rq->lock, flags);
+       if (dl_rq->rb_leftmost)
+               min_deadline = (rb_entry(dl_rq->rb_leftmost,
+                                        struct sched_dl_entity,
+                                        rb_node))->deadline;
+       last = __pick_dl_last_entity(dl_rq);
+       if (last)
+               max_deadline = last->deadline;
+       raw_spin_unlock_irqrestore(&rq->lock, flags);
+
+#define P(x) \
+       SEQ_printf(m, "  .%-30s: %Ld\n", #x, (long long)(dl_rq->x))
+#define __PN(x) \
+       SEQ_printf(m, "  .%-30s: %Ld.%06ld\n", #x, SPLIT_NS(x))
+#define PN(x) \
+       SEQ_printf(m, "  .%-30s: %Ld.%06ld\n", #x, SPLIT_NS(dl_rq->x))
+
+       P(dl_nr_running);
+       PN(exec_clock);
+       __PN(min_deadline);
+       __PN(max_deadline);
+
+#undef PN
+#undef __PN
+#undef P
+}
+
 extern __read_mostly int sched_clock_running;
 
 static void print_cpu(struct seq_file *m, int cpu)
@@ -320,6 +359,7 @@ do {                                                        
                \
        spin_lock_irqsave(&sched_debug_lock, flags);
        print_cfs_stats(m, cpu);
        print_rt_stats(m, cpu);
+       print_dl_stats(m, cpu);
 
        rcu_read_lock();
        print_rq(m, rq, cpu);
@@ -540,6 +580,12 @@ void proc_sched_show_task(struct task_struct *p, struct 
seq_file *m)
        P(se.statistics.nr_wakeups_affine_attempts);
        P(se.statistics.nr_wakeups_passive);
        P(se.statistics.nr_wakeups_idle);
+       if (dl_task(p)) {
+               PN(dl.stats.last_dmiss);
+               PN(dl.stats.dmiss_max);
+               PN(dl.stats.last_rorun);
+               PN(dl.stats.rorun_max);
+       }
 
        {
                u64 avg_atom, avg_per_cpu;
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 70d0030..b04aeed 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -384,6 +384,8 @@ struct dl_rq {
 
        unsigned long dl_nr_running;
 
+       u64 exec_clock;
+
 #ifdef CONFIG_SMP
        /*
         * Deadline values of the currently executing and the
@@ -410,6 +412,11 @@ struct dl_rq {
 #endif
 };
 
+#ifdef CONFIG_SCHED_DEBUG
+struct sched_dl_entity *__pick_dl_last_entity(struct dl_rq *dl_rq);
+void print_dl_stats(struct seq_file *m, int cpu);
+#endif
+
 #ifdef CONFIG_SMP
 
 /*
@@ -1366,7 +1373,7 @@ extern void print_rt_stats(struct seq_file *m, int cpu);
 
 extern void init_cfs_rq(struct cfs_rq *cfs_rq);
 extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq);
-extern void init_dl_rq(struct dl_rq *rt_rq, struct rq *rq);
+extern void init_dl_rq(struct dl_rq *dl_rq, struct rq *rq);
 
 extern void account_cfs_bandwidth_used(int enabled, int was_enabled);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to