usb: dwc3: rockchip: fix possible circular deadlock
[firefly-linux-kernel-4.4.55.git] / kernel / sched / rt.c
index 9694204660b7e7c4a29e070252cda0dd9e6007d6..8a16cba968c43c981b0e2671a5e1e2d6cc8e341a 100644 (file)
@@ -8,6 +8,8 @@
 #include <linux/slab.h>
 #include <linux/irq_work.h>
 
+#include "walt.h"
+
 int sched_rr_timeslice = RR_TIMESLICE;
 
 static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun);
@@ -889,6 +891,51 @@ static inline int rt_se_prio(struct sched_rt_entity *rt_se)
        return rt_task_of(rt_se)->prio;
 }
 
+static void dump_throttled_rt_tasks(struct rt_rq *rt_rq)
+{
+       struct rt_prio_array *array = &rt_rq->active;
+       struct sched_rt_entity *rt_se;
+       char buf[500];
+       char *pos = buf;
+       char *end = buf + sizeof(buf);
+       int idx;
+
+       pos += snprintf(pos, sizeof(buf),
+               "sched: RT throttling activated for rt_rq %p (cpu %d)\n",
+               rt_rq, cpu_of(rq_of_rt_rq(rt_rq)));
+
+       if (bitmap_empty(array->bitmap, MAX_RT_PRIO))
+               goto out;
+
+       pos += snprintf(pos, end - pos, "potential CPU hogs:\n");
+       idx = sched_find_first_bit(array->bitmap);
+       while (idx < MAX_RT_PRIO) {
+               list_for_each_entry(rt_se, array->queue + idx, run_list) {
+                       struct task_struct *p;
+
+                       if (!rt_entity_is_task(rt_se))
+                               continue;
+
+                       p = rt_task_of(rt_se);
+                       if (pos < end)
+                               pos += snprintf(pos, end - pos, "\t%s (%d)\n",
+                                       p->comm, p->pid);
+               }
+               idx = find_next_bit(array->bitmap, MAX_RT_PRIO, idx + 1);
+       }
+out:
+#ifdef CONFIG_PANIC_ON_RT_THROTTLING
+       /*
+        * Use pr_err() in the BUG() case since printk_sched() will
+        * not get flushed and deadlock is not a concern.
+        */
+       pr_err("%s", buf);
+       BUG();
+#else
+       printk_deferred("%s", buf);
+#endif
+}
+
 static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
 {
        u64 runtime = sched_rt_runtime(rt_rq);
@@ -912,8 +959,14 @@ static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
                 * but accrue some time due to boosting.
                 */
                if (likely(rt_b->rt_runtime)) {
+                       static bool once = false;
+
                        rt_rq->rt_throttled = 1;
-                       printk_deferred_once("sched: RT throttling activated\n");
+
+                       if (!once) {
+                               once = true;
+                               dump_throttled_rt_tasks(rt_rq);
+                       }
                } else {
                        /*
                         * In case we did anyway, make it go away,
@@ -1261,6 +1314,7 @@ enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags)
                rt_se->timeout = 0;
 
        enqueue_rt_entity(rt_se, flags & ENQUEUE_HEAD);
+       walt_inc_cumulative_runnable_avg(rq, p);
 
        if (!task_current(rq, p) && p->nr_cpus_allowed > 1)
                enqueue_pushable_task(rq, p);
@@ -1272,6 +1326,7 @@ static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags)
 
        update_curr_rt(rq);
        dequeue_rt_entity(rt_se);
+       walt_dec_cumulative_runnable_avg(rq, p);
 
        dequeue_pushable_task(rq, p);
 }