Skip to content

Commit 4c1f3a7

Browse files
mikechristiemstsirkin
authored andcommitted
vhost-scsi: Reduce mem use by moving upages to per queue
Each worker thread can process 1 command at a time so there's no need to allocate a upages array per cmd. This patch moves it to per queue. Even a small device with 128 cmds and 1 queue this brings mem use for the array from 2 MB = 8 bytes per page pointer * 2048 pointers * 128 cmds to 16K = 8 bytes per pointer * 2048 * 1 queue Signed-off-by: Mike Christie <michael.christie@oracle.com> Message-Id: <20241203191705.19431-2-michael.christie@oracle.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
1 parent fc80842 commit 4c1f3a7

File tree

1 file changed

+10
-14
lines changed

1 file changed

+10
-14
lines changed

drivers/vhost/scsi.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ struct vhost_scsi_cmd {
8383
/* Pointer to the SGL formatted memory from virtio-scsi */
8484
struct scatterlist *tvc_sgl;
8585
struct scatterlist *tvc_prot_sgl;
86-
struct page **tvc_upages;
8786
/* Pointer to response header iovec */
8887
struct iovec *tvc_resp_iov;
8988
/* Pointer to vhost_scsi for our device */
@@ -187,6 +186,7 @@ struct vhost_scsi_virtqueue {
187186
struct vhost_scsi_cmd *scsi_cmds;
188187
struct sbitmap scsi_tags;
189188
int max_cmds;
189+
struct page **upages;
190190

191191
struct vhost_work completion_work;
192192
struct llist_head completion_list;
@@ -619,7 +619,6 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg,
619619
struct vhost_scsi_nexus *tv_nexus;
620620
struct scatterlist *sg, *prot_sg;
621621
struct iovec *tvc_resp_iov;
622-
struct page **pages;
623622
int tag;
624623

625624
tv_nexus = tpg->tpg_nexus;
@@ -637,12 +636,10 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg,
637636
cmd = &svq->scsi_cmds[tag];
638637
sg = cmd->tvc_sgl;
639638
prot_sg = cmd->tvc_prot_sgl;
640-
pages = cmd->tvc_upages;
641639
tvc_resp_iov = cmd->tvc_resp_iov;
642640
memset(cmd, 0, sizeof(*cmd));
643641
cmd->tvc_sgl = sg;
644642
cmd->tvc_prot_sgl = prot_sg;
645-
cmd->tvc_upages = pages;
646643
cmd->tvc_se_cmd.map_tag = tag;
647644
cmd->tvc_tag = scsi_tag;
648645
cmd->tvc_lun = lun;
@@ -669,7 +666,9 @@ vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
669666
struct scatterlist *sgl,
670667
bool is_prot)
671668
{
672-
struct page **pages = cmd->tvc_upages;
669+
struct vhost_scsi_virtqueue *svq = container_of(cmd->tvc_vq,
670+
struct vhost_scsi_virtqueue, vq);
671+
struct page **pages = svq->upages;
673672
struct scatterlist *sg = sgl;
674673
ssize_t bytes, mapped_bytes;
675674
size_t offset, mapped_offset;
@@ -1598,11 +1597,11 @@ static void vhost_scsi_destroy_vq_cmds(struct vhost_virtqueue *vq)
15981597

15991598
kfree(tv_cmd->tvc_sgl);
16001599
kfree(tv_cmd->tvc_prot_sgl);
1601-
kfree(tv_cmd->tvc_upages);
16021600
kfree(tv_cmd->tvc_resp_iov);
16031601
}
16041602

16051603
sbitmap_free(&svq->scsi_tags);
1604+
kfree(svq->upages);
16061605
kfree(svq->scsi_cmds);
16071606
svq->scsi_cmds = NULL;
16081607
}
@@ -1628,6 +1627,11 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds)
16281627
return -ENOMEM;
16291628
}
16301629

1630+
svq->upages = kcalloc(VHOST_SCSI_PREALLOC_UPAGES, sizeof(struct page *),
1631+
GFP_KERNEL);
1632+
if (!svq->upages)
1633+
goto out;
1634+
16311635
for (i = 0; i < max_cmds; i++) {
16321636
tv_cmd = &svq->scsi_cmds[i];
16331637

@@ -1639,14 +1643,6 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds)
16391643
goto out;
16401644
}
16411645

1642-
tv_cmd->tvc_upages = kcalloc(VHOST_SCSI_PREALLOC_UPAGES,
1643-
sizeof(struct page *),
1644-
GFP_KERNEL);
1645-
if (!tv_cmd->tvc_upages) {
1646-
pr_err("Unable to allocate tv_cmd->tvc_upages\n");
1647-
goto out;
1648-
}
1649-
16501646
tv_cmd->tvc_resp_iov = kcalloc(UIO_MAXIOV,
16511647
sizeof(struct iovec),
16521648
GFP_KERNEL);

0 commit comments

Comments
 (0)