On Tue, 2017-12-05 at 15:52 +0800, Ming Lei wrote: > diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c > index db9556662e27..1816dd8259b3 100644 > --- a/drivers/scsi/scsi_lib.c > +++ b/drivers/scsi/scsi_lib.c > @@ -1967,6 +1967,8 @@ static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) > out_put_device: > put_device(&sdev->sdev_gendev); > out: > + if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev)) > + blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY); > return false; > } This cannot work since multiple threads can call scsi_mq_get_budget() concurrently and hence it can happen that none of them sees atomic_read(&sdev->device_busy) == 0. BTW, the above patch is something I consider as a workaround. Have you considered to fix the root cause and to add blk_mq_sched_mark_restart_hctx() where these are missing, e.g. in blk_mq_sched_dispatch_requests()? The patch below is not a full solution but resulted in a significant improvement in my tests: diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index 69e3226e66ca..9d86876ec503 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c @@ -226,6 +226,7 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx) * TODO: get more budgets, and dequeue more requests in * one time. */ + blk_mq_sched_mark_restart_hctx(hctx); blk_mq_do_dispatch_ctx(hctx); } else { blk_mq_flush_busy_ctxs(hctx, &rq_list); Bart.