On 9/3/24 2:16 AM, Muchun Song wrote: > Supposing the following scenario with a virtio_blk driver. > > CPU0 CPU1 CPU2 > > blk_mq_try_issue_directly() > __blk_mq_issue_directly() > q->mq_ops->queue_rq() > virtio_queue_rq() > blk_mq_stop_hw_queue() > blk_mq_try_issue_directly() virtblk_done() > if (blk_mq_hctx_stopped()) > blk_mq_request_bypass_insert() blk_mq_start_stopped_hw_queue() > blk_mq_run_hw_queue() blk_mq_run_hw_queue() > blk_mq_insert_request() > return // Who is responsible for dispatching this IO request? > > After CPU0 has marked the queue as stopped, CPU1 will see the queue is stopped. > But before CPU1 puts the request on the dispatch list, CPU2 receives the interrupt > of completion of request, so it will run the hardware queue and marks the queue > as non-stopped. Meanwhile, CPU1 also runs the same hardware queue. After both CPU1 > and CPU2 complete blk_mq_run_hw_queue(), CPU1 just puts the request to the same > hardware queue and returns. It misses dispatching a request. Fix it by running > the hardware queue explicitly. And blk_mq_request_issue_directly() should handle > a similar situation. Fix it as well. Patch looks fine, but this commit message is waaaaay too wide. Please limit it to 72-74 chars. The above ordering is diagram is going to otherwise be unreadable in a git log viewing in a terminal. -- Jens Axboe