diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched/deadline.c | 13 | ||||
| -rw-r--r-- | kernel/sched/sched.h | 1 |
2 files changed, 14 insertions, 0 deletions
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 0b7ac4c12797..4754dbe4232d 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -2541,6 +2541,9 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) if (task_is_blocked(p)) return; + if (dl_rq->curr == dl_se) + return; + if (!task_current(rq, p) && !dl_se->dl_throttled && p->nr_cpus_allowed > 1) enqueue_pushable_dl_task(rq, p); } @@ -2763,6 +2766,10 @@ static void start_hrtick_dl(struct rq *rq, struct sched_dl_entity *dl_se) } #endif /* !CONFIG_SCHED_HRTICK */ +/* + * DL keeps current in tree, because ->deadline is not typically changed while + * a task is runnable. + */ static void set_next_task_dl(struct rq *rq, struct task_struct *p, bool first) { struct sched_dl_entity *dl_se = &p->dl; @@ -2775,6 +2782,9 @@ static void set_next_task_dl(struct rq *rq, struct task_struct *p, bool first) /* You can't push away the running task */ dequeue_pushable_dl_task(rq, p); + WARN_ON_ONCE(dl_rq->curr); + dl_rq->curr = dl_se; + if (!first) return; @@ -2845,6 +2855,9 @@ static void put_prev_task_dl(struct rq *rq, struct task_struct *p, struct task_s update_dl_rq_load_avg(rq_clock_pelt(rq), rq, 1); + WARN_ON_ONCE(dl_rq->curr != dl_se); + dl_rq->curr = NULL; + if (task_is_blocked(p)) return; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index ef715f2acbaa..b3aff26dbb13 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -893,6 +893,7 @@ struct dl_rq { bool overloaded; + struct sched_dl_entity *curr; /* * Tasks on this rq that can be pushed away. They are kept in * an rb-tree, ordered by tasks' deadlines, with caching |
