vhost-scsi: Return queue full for page alloc failures during copy
[ Upstream commit 891b99eab0f89dbe08d216f4ab71acbeaf7a3102 ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
de4469a900
commit
f5121d5ba7
@@ -751,7 +751,7 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
|
|||||||
size_t len = iov_iter_count(iter);
|
size_t len = iov_iter_count(iter);
|
||||||
unsigned int nbytes = 0;
|
unsigned int nbytes = 0;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
int i;
|
int i, ret;
|
||||||
|
|
||||||
if (cmd->tvc_data_direction == DMA_FROM_DEVICE) {
|
if (cmd->tvc_data_direction == DMA_FROM_DEVICE) {
|
||||||
cmd->saved_iter_addr = dup_iter(&cmd->saved_iter, iter,
|
cmd->saved_iter_addr = dup_iter(&cmd->saved_iter, iter,
|
||||||
@@ -764,6 +764,7 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
|
|||||||
page = alloc_page(GFP_KERNEL);
|
page = alloc_page(GFP_KERNEL);
|
||||||
if (!page) {
|
if (!page) {
|
||||||
i--;
|
i--;
|
||||||
|
ret = -ENOMEM;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,8 +772,10 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
|
|||||||
sg_set_page(&sg[i], page, nbytes, 0);
|
sg_set_page(&sg[i], page, nbytes, 0);
|
||||||
|
|
||||||
if (cmd->tvc_data_direction == DMA_TO_DEVICE &&
|
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;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
len -= nbytes;
|
len -= nbytes;
|
||||||
}
|
}
|
||||||
@@ -787,7 +790,7 @@ err:
|
|||||||
for (; i >= 0; i--)
|
for (; i >= 0; i--)
|
||||||
__free_page(sg_page(&sg[i]));
|
__free_page(sg_page(&sg[i]));
|
||||||
kfree(cmd->saved_iter_addr);
|
kfree(cmd->saved_iter_addr);
|
||||||
return -ENOMEM;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1226,9 +1229,9 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
|
|||||||
" %d\n", cmd, exp_data_len, prot_bytes, data_direction);
|
" %d\n", cmd, exp_data_len, prot_bytes, data_direction);
|
||||||
|
|
||||||
if (data_direction != DMA_NONE) {
|
if (data_direction != DMA_NONE) {
|
||||||
if (unlikely(vhost_scsi_mapal(cmd, prot_bytes,
|
ret = vhost_scsi_mapal(cmd, prot_bytes, &prot_iter,
|
||||||
&prot_iter, exp_data_len,
|
exp_data_len, &data_iter);
|
||||||
&data_iter))) {
|
if (unlikely(ret)) {
|
||||||
vq_err(vq, "Failed to map iov to sgl\n");
|
vq_err(vq, "Failed to map iov to sgl\n");
|
||||||
vhost_scsi_release_cmd_res(&cmd->tvc_se_cmd);
|
vhost_scsi_release_cmd_res(&cmd->tvc_se_cmd);
|
||||||
goto err;
|
goto err;
|
||||||
|
Reference in New Issue
Block a user