diff --git a/include/linux/sched/walt.h b/include/linux/sched/walt.h index 918466220ba0..ec39456e2e8b 100644 --- a/include/linux/sched/walt.h +++ b/include/linux/sched/walt.h @@ -114,6 +114,7 @@ struct walt_task_struct { cpumask_t cpus_requested; bool iowaited; int prev_on_rq; + int prev_on_rq_cpu; struct list_head mvp_list; u64 sum_exec_snapshot; u64 total_exec; diff --git a/kernel/sched/walt/walt.c b/kernel/sched/walt/walt.c index f2147d424a2b..aeb7e0736144 100644 --- a/kernel/sched/walt/walt.c +++ b/kernel/sched/walt/walt.c @@ -2212,6 +2212,7 @@ static void init_new_task_load(struct task_struct *p) wts->prev_window = 0; wts->active_time = 0; wts->prev_on_rq = 0; + wts->prev_on_rq_cpu = -1; for (i = 0; i < NUM_BUSY_BUCKETS; ++i) wts->busy_buckets[i] = 0; @@ -3833,6 +3834,15 @@ static void android_rvh_enqueue_task(void *unused, struct rq *rq, struct task_st if (unlikely(walt_disabled)) return; + lockdep_assert_held(&rq->lock); + + if (p->cpu != cpu_of(rq)) { + printk_deferred("WALT-BUG enqueuing on rq %d when task->cpu is %d\n", + cpu_of(rq), p->cpu); + walt_task_dump(p); + SCHED_BUG_ON(1); + } + /* catch double enqueue */ if (wts->prev_on_rq == 1) { printk_deferred("WALT-BUG double enqueue detected: task_cpu=%d new_cpu=%d\n", @@ -3841,6 +3851,7 @@ static void android_rvh_enqueue_task(void *unused, struct rq *rq, struct task_st SCHED_BUG_ON(1); } wts->prev_on_rq = 1; + wts->prev_on_rq_cpu = cpu_of(rq); wts->last_enqueued_ts = wallclock; sched_update_nr_prod(rq->cpu, 1); @@ -3863,6 +3874,23 @@ static void android_rvh_dequeue_task(void *unused, struct rq *rq, struct task_st if (unlikely(walt_disabled)) return; + lockdep_assert_held(&rq->lock); + + /* + * a task can be enqueued before walt is started, and dequeued after. + * therefore the check to ensure that prev_on_rq_cpu is needed to prevent + * an invalid failure. + */ + if (wts->prev_on_rq_cpu >= 0 && wts->prev_on_rq_cpu != cpu_of(rq)) { + printk_deferred("WALT-BUG dequeue cpu %d not same as enqueue %d\n", + cpu_of(rq), wts->prev_on_rq_cpu); + walt_task_dump(p); + SCHED_BUG_ON(1); + } + + /* no longer on a cpu */ + wts->prev_on_rq_cpu = -1; + /* catch double deq */ if (wts->prev_on_rq == 2) { printk_deferred("WALT-BUG double dequeue detected: task_cpu=%d new_cpu=%d\n",