]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
vhost-scsi: Return queue full for page alloc failures during copy
authorMike Christie <michael.christie@oracle.com>
Tue, 3 Dec 2024 19:15:11 +0000 (13:15 -0600)
committerMichael S. Tsirkin <mst@redhat.com>
Tue, 25 Feb 2025 12:10:46 +0000 (07:10 -0500)
This has us return queue full if we can't allocate a page during the
copy operation so the initiator can retry.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
Message-Id: <20241203191705.19431-5-michael.christie@oracle.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
drivers/vhost/scsi.c

index ed4fd45da28780dff80c66de1d62382715a2f9f5..c087fbc6f8d3cec3b8d9eac9ac73b38991283741 100644 (file)
@@ -756,7 +756,7 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
        size_t len = iov_iter_count(iter);
        unsigned int nbytes = 0;
        struct page *page;
-       int i;
+       int i, ret;
 
        if (cmd->tvc_data_direction == DMA_FROM_DEVICE) {
                cmd->saved_iter_addr = dup_iter(&cmd->saved_iter, iter,
@@ -769,6 +769,7 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
                page = alloc_page(GFP_KERNEL);
                if (!page) {
                        i--;
+                       ret = -ENOMEM;
                        goto err;
                }
 
@@ -776,8 +777,10 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
                sg_set_page(&sg[i], page, nbytes, 0);
 
                if (cmd->tvc_data_direction == DMA_TO_DEVICE &&
-                   copy_page_from_iter(page, 0, nbytes, iter) != nbytes)
+                   copy_page_from_iter(page, 0, nbytes, iter) != nbytes) {
+                       ret = -EFAULT;
                        goto err;
+               }
 
                len -= nbytes;
        }
@@ -792,7 +795,7 @@ err:
        for (; i >= 0; i--)
                __free_page(sg_page(&sg[i]));
        kfree(cmd->saved_iter_addr);
-       return -ENOMEM;
+       return ret;
 }
 
 static int
@@ -1249,9 +1252,9 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
                         " %d\n", cmd, exp_data_len, prot_bytes, data_direction);
 
                if (data_direction != DMA_NONE) {
-                       if (unlikely(vhost_scsi_mapal(cmd, prot_bytes,
-                                                     &prot_iter, exp_data_len,
-                                                     &data_iter))) {
+                       ret = vhost_scsi_mapal(cmd, prot_bytes, &prot_iter,
+                                              exp_data_len, &data_iter);
+                       if (unlikely(ret)) {
                                vq_err(vq, "Failed to map iov to sgl\n");
                                vhost_scsi_release_cmd_res(&cmd->tvc_se_cmd);
                                goto err;