summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Christie <michael.christie@oracle.com>2024-12-03 13:15:11 -0600
committerMichael S. Tsirkin <mst@redhat.com>2025-02-25 07:10:46 -0500
commit891b99eab0f89dbe08d216f4ab71acbeaf7a3102 (patch)
treefa7c1f0553caa3a4ae04f771b5e9ee7629ce712c
parent3ca51662f8186b569b8fb282242c20ccbb3993c2 (diff)
downloadlinux-891b99eab0f89dbe08d216f4ab71acbeaf7a3102.tar.gz
linux-891b99eab0f89dbe08d216f4ab71acbeaf7a3102.tar.bz2
linux-891b99eab0f89dbe08d216f4ab71acbeaf7a3102.zip
vhost-scsi: Return queue full for page alloc failures during copy
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>
-rw-r--r--drivers/vhost/scsi.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index ed4fd45da287..c087fbc6f8d3 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -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;