diff --git a/block/blk-core.c b/block/blk-core.c index 4984b46..4924aa0 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1100,6 +1100,7 @@ static bool attempt_plug_merge(struct task_struct *tsk, struct request_queue *q, struct request *rq; bool ret = false; + preempt_disable(); plug = tsk->plug; if (!plug) goto out; @@ -1122,6 +1123,7 @@ static bool attempt_plug_merge(struct task_struct *tsk, struct request_queue *q, } } out: + preempt_enable(); return ret; } diff --git a/kernel/sched.c b/kernel/sched.c index e806446..7b4b2f9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3938,6 +3938,14 @@ asmlinkage void __sched schedule(void) struct rq *rq; int cpu; + /* + * If this task has IO plugged, make sure it gets flushed out to the + * devices before we go to sleep. Must be called before below lock, + * otherwise there is deadlock + */ + blk_flush_plug(current); + BUG_ON(current->plug && !list_empty(¤t->plug->list)); + need_resched: preempt_disable(); cpu = smp_processor_id(); @@ -3973,14 +3981,6 @@ need_resched_nonpreemptible: if (to_wakeup) try_to_wake_up_local(to_wakeup); } - /* - * If this task has IO plugged, make sure it - * gets flushed out to the devices before we go - * to sleep - */ - blk_flush_plug(prev); - BUG_ON(prev->plug && !list_empty(&prev->plug->list)); - deactivate_task(rq, prev, DEQUEUE_SLEEP); } switch_count = &prev->nvcsw;