Handle failed request processing with extra care: - If we got ENOMEM or EAGAIN, reverse vq head with vhost_discard_vq_desc() and re-queue this callback. ENOMEM isn't that critical, as we always allocate the memory with GFP_KERNEL so it can reclaim or sleep anyway. But with EAGAIN we should re-enter the function to properly check vq->backend. - On any other error, signal error and wait for next kick just like vhost-net or vhost-scsi. After all, we can't do anything with faulty guest request anyway.
https://virtuozzo.atlassian.net/browse/VSTOR-134034 Signed-off-by: Andrey Zhadchenko <[email protected]> --- v2: - drop one missed vhost_discard_vq_desc(vq, 1); - change EGAIN and ENOMEM behaviour and expand commit message with the reasoning drivers/vhost/blk.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/vhost/blk.c b/drivers/vhost/blk.c index 7e33a4f30165d..6a1a2bab3bed8 100644 --- a/drivers/vhost/blk.c +++ b/drivers/vhost/blk.c @@ -540,7 +540,6 @@ static void vhost_blk_handle_guest_kick(struct vhost_work *work) ret = move_iovec(vq->iov, hdr_iovec, sizeof(hdr), in + out, ARRAY_SIZE(hdr_iovec)); if (ret < 0) { vhostblk_vq_err(blk, vq, "virtio_blk_hdr (head %d) is too split!", head); - vhost_discard_vq_desc(vq, 1); break; } @@ -549,12 +548,17 @@ static void vhost_blk_handle_guest_kick(struct vhost_work *work) if (ret != sizeof(hdr)) { vhostblk_vq_err(blk, vq, "Failed to get read header (head %d): got %d, expected %ld!\n", head, ret, sizeof(hdr)); - vhost_discard_vq_desc(vq, 1); break; } - if (vhost_blk_req_handle(vq, &hdr, head, out + in) < 0) { + ret = vhost_blk_req_handle(vq, &hdr, head, out + in); + if (ret == -EAGAIN || ret == -ENOMEM) { vhost_discard_vq_desc(vq, 1); + vhost_poll_queue(&vq->poll); + break; + } else if (ret < 0) { + vhostblk_vq_err(blk, vq, "Failed to process guest request (head %d) with %d", + head, ret); break; } -- 2.43.5 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
