Loading drivers/block/virtio_blk.c +37 −45 Original line number Diff line number Diff line Loading @@ -348,63 +348,33 @@ static inline void virtblk_request_done(struct request *req) blk_mq_end_request(req, status); } static void virtblk_complete_batch(struct io_comp_batch *iob) { struct request *req; rq_list_for_each(&iob->req_list, req) { virtblk_unmap_data(req, blk_mq_rq_to_pdu(req)); virtblk_cleanup_cmd(req); } blk_mq_end_request_batch(iob); } static int virtblk_handle_req(struct virtio_blk_vq *vq, struct io_comp_batch *iob) { struct virtblk_req *vbr; int req_done = 0; unsigned int len; while ((vbr = virtqueue_get_buf(vq->vq, &len)) != NULL) { struct request *req = blk_mq_rq_from_pdu(vbr); if (likely(!blk_should_fake_timeout(req->q)) && !blk_mq_complete_request_remote(req) && !blk_mq_add_to_batch(req, iob, virtblk_vbr_status(vbr), virtblk_complete_batch)) virtblk_request_done(req); req_done++; } return req_done; } static void virtblk_done(struct virtqueue *vq) { struct virtio_blk *vblk = vq->vdev->priv; struct virtio_blk_vq *vblk_vq = &vblk->vqs[vq->index]; int req_done = 0; bool req_done = false; int qid = vq->index; struct virtblk_req *vbr; unsigned long flags; DEFINE_IO_COMP_BATCH(iob); unsigned int len; spin_lock_irqsave(&vblk_vq->lock, flags); spin_lock_irqsave(&vblk->vqs[qid].lock, flags); do { virtqueue_disable_cb(vq); req_done += virtblk_handle_req(vblk_vq, &iob); while ((vbr = virtqueue_get_buf(vblk->vqs[qid].vq, &len)) != NULL) { struct request *req = blk_mq_rq_from_pdu(vbr); if (likely(!blk_should_fake_timeout(req->q))) blk_mq_complete_request(req); req_done = true; } if (unlikely(virtqueue_is_broken(vq))) break; } while (!virtqueue_enable_cb(vq)); if (req_done) { if (!rq_list_empty(iob.req_list)) iob.complete(&iob); /* In case queue is stopped waiting for more buffers. */ if (req_done) blk_mq_start_stopped_hw_queues(vblk->disk->queue, true); } spin_unlock_irqrestore(&vblk_vq->lock, flags); spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); } static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx) Loading Loading @@ -1283,15 +1253,37 @@ static void virtblk_map_queues(struct blk_mq_tag_set *set) } } static void virtblk_complete_batch(struct io_comp_batch *iob) { struct request *req; rq_list_for_each(&iob->req_list, req) { virtblk_unmap_data(req, blk_mq_rq_to_pdu(req)); virtblk_cleanup_cmd(req); } blk_mq_end_request_batch(iob); } static int virtblk_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) { struct virtio_blk *vblk = hctx->queue->queuedata; struct virtio_blk_vq *vq = get_virtio_blk_vq(hctx); struct virtblk_req *vbr; unsigned long flags; unsigned int len; int found = 0; spin_lock_irqsave(&vq->lock, flags); found = virtblk_handle_req(vq, iob); while ((vbr = virtqueue_get_buf(vq->vq, &len)) != NULL) { struct request *req = blk_mq_rq_from_pdu(vbr); found++; if (!blk_mq_complete_request_remote(req) && !blk_mq_add_to_batch(req, iob, virtblk_vbr_status(vbr), virtblk_complete_batch)) virtblk_request_done(req); } if (found) blk_mq_start_stopped_hw_queues(vblk->disk->queue, true); Loading Loading
drivers/block/virtio_blk.c +37 −45 Original line number Diff line number Diff line Loading @@ -348,63 +348,33 @@ static inline void virtblk_request_done(struct request *req) blk_mq_end_request(req, status); } static void virtblk_complete_batch(struct io_comp_batch *iob) { struct request *req; rq_list_for_each(&iob->req_list, req) { virtblk_unmap_data(req, blk_mq_rq_to_pdu(req)); virtblk_cleanup_cmd(req); } blk_mq_end_request_batch(iob); } static int virtblk_handle_req(struct virtio_blk_vq *vq, struct io_comp_batch *iob) { struct virtblk_req *vbr; int req_done = 0; unsigned int len; while ((vbr = virtqueue_get_buf(vq->vq, &len)) != NULL) { struct request *req = blk_mq_rq_from_pdu(vbr); if (likely(!blk_should_fake_timeout(req->q)) && !blk_mq_complete_request_remote(req) && !blk_mq_add_to_batch(req, iob, virtblk_vbr_status(vbr), virtblk_complete_batch)) virtblk_request_done(req); req_done++; } return req_done; } static void virtblk_done(struct virtqueue *vq) { struct virtio_blk *vblk = vq->vdev->priv; struct virtio_blk_vq *vblk_vq = &vblk->vqs[vq->index]; int req_done = 0; bool req_done = false; int qid = vq->index; struct virtblk_req *vbr; unsigned long flags; DEFINE_IO_COMP_BATCH(iob); unsigned int len; spin_lock_irqsave(&vblk_vq->lock, flags); spin_lock_irqsave(&vblk->vqs[qid].lock, flags); do { virtqueue_disable_cb(vq); req_done += virtblk_handle_req(vblk_vq, &iob); while ((vbr = virtqueue_get_buf(vblk->vqs[qid].vq, &len)) != NULL) { struct request *req = blk_mq_rq_from_pdu(vbr); if (likely(!blk_should_fake_timeout(req->q))) blk_mq_complete_request(req); req_done = true; } if (unlikely(virtqueue_is_broken(vq))) break; } while (!virtqueue_enable_cb(vq)); if (req_done) { if (!rq_list_empty(iob.req_list)) iob.complete(&iob); /* In case queue is stopped waiting for more buffers. */ if (req_done) blk_mq_start_stopped_hw_queues(vblk->disk->queue, true); } spin_unlock_irqrestore(&vblk_vq->lock, flags); spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); } static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx) Loading Loading @@ -1283,15 +1253,37 @@ static void virtblk_map_queues(struct blk_mq_tag_set *set) } } static void virtblk_complete_batch(struct io_comp_batch *iob) { struct request *req; rq_list_for_each(&iob->req_list, req) { virtblk_unmap_data(req, blk_mq_rq_to_pdu(req)); virtblk_cleanup_cmd(req); } blk_mq_end_request_batch(iob); } static int virtblk_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) { struct virtio_blk *vblk = hctx->queue->queuedata; struct virtio_blk_vq *vq = get_virtio_blk_vq(hctx); struct virtblk_req *vbr; unsigned long flags; unsigned int len; int found = 0; spin_lock_irqsave(&vq->lock, flags); found = virtblk_handle_req(vq, iob); while ((vbr = virtqueue_get_buf(vq->vq, &len)) != NULL) { struct request *req = blk_mq_rq_from_pdu(vbr); found++; if (!blk_mq_complete_request_remote(req) && !blk_mq_add_to_batch(req, iob, virtblk_vbr_status(vbr), virtblk_complete_batch)) virtblk_request_done(req); } if (found) blk_mq_start_stopped_hw_queues(vblk->disk->queue, true); Loading