Message ID | 20151127112647.GR20439@e106622-lin |
---|---|
State | New |
Headers | show |
On 30/11/15 10:20, Wanpeng Li wrote: > 2015-11-27 20:14 GMT+08:00 Luca Abeni <luca.abeni@unitn.it>: > > Hi all, > > > > I ran some quick tests on this patch (because I was working on something > > related), and it seems to me that it triggers a bug. Here are some > > information: [snip] > > > > Here is my understanding of the crash: > > - schedule() invokes pick_next_task_dl() which wants to do a context switch > > (by selecting > > for execution a new task "p" which is different from "prev") > > - pick_next_task_dl() invokes put_prev, which puts the "prev" task in the > > pushable tasks > > queue (WARNING! "prev" is still the "current" task in this rq, because the > > scheduler is > > still running... I think this is the source of the issue) > > - then, pick_next_task_dl() invokes dequeue_pushable_dl_task() on p, to > > remove the selected > > task from the pushable tasks queue... > > - ...But after your patch dequeue_pushable_dl_task() invokes > > pick_next_pushable_dl_task(). > > Which sees that the next pushable task is the "current" task (see above). > > This happens > > becuase "prev" has already been inserted in the pushable tasks queue, and > > can be the > > next pushable task... But "current" has not been updated yet. > > - The BUG_ON() at line 1443 of deadline.c is just "BUG_ON(task_current(rq, > > p))" > > Thanks for your report and great analyse, Luca, you are right. > > > > > Summing up, I think pick_next_pushable_dl_task() cannot be called from > > dequeue_pushable_dl_task() (at least, not without removing or modifying that > > BUG_ON()). > > Juri, how about remove this BUG_ON() just like rt class? > It seems that we actually check the very same conditions for RT, as we do for DL. The difference is that RT doesn't call pick_next_pushable _task(). I think we can do the same, just checking and eventually using the updated leftmost in dequeue_pushable_dl_task(). Thanks, - Juri -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 547d102..d6de660 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -178,14 +178,13 @@ static void enqueue_pushable_dl_task(struct rq *rq, struct task_struct *p) } } - if (leftmost) + if (leftmost) { dl_rq->pushable_dl_tasks_leftmost = &p->pushable_dl_tasks; + dl_rq->earliest_dl.next = p->dl.deadline; + } rb_link_node(&p->pushable_dl_tasks, parent, link); rb_insert_color(&p->pushable_dl_tasks, &dl_rq->pushable_dl_tasks_root); - - if (dl_time_before(p->dl.deadline, dl_rq->earliest_dl.next)) - dl_rq->earliest_dl.next = p->dl.deadline; } static void dequeue_pushable_dl_task(struct rq *rq, struct task_struct *p) @@ -209,8 +208,6 @@ static void dequeue_pushable_dl_task(struct rq *rq, struct task_struct *p) next_pushable = pick_next_pushable_dl_task(rq); if (next_pushable) dl_rq->earliest_dl.next = next_pushable->dl.deadline; - else - dl_rq->earliest_dl.next = 0; } static inline int has_pushable_dl_tasks(struct rq *rq)