Skip to content

Commit a94c96a

Browse files
Dongli Zhangmstsirkin
authored andcommitted
vhost-scsi: log control queue write descriptors
Log write descriptors for the control queue, leveraging vhost_scsi_get_desc() and vhost_get_vq_desc() to retrieve the array of write descriptors to obtain the log buffer. For Task Management Requests, similar to the I/O queue, store the log buffer during the submission path and log it in the completion or error handling path. For Asynchronous Notifications, only the submission path is involved. Suggested-by: Joao Martins <joao.m.martins@oracle.com> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com> Message-Id: <20250403063028.16045-8-dongli.zhang@oracle.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Mike Christie <michael.christie@oracle.com>
1 parent c2c5c25 commit a94c96a

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

drivers/vhost/scsi.c

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ struct vhost_scsi_tmf {
263263
struct iovec resp_iov;
264264
int in_iovs;
265265
int vq_desc;
266+
267+
/*
268+
* Dirty write descriptors of this command.
269+
*/
270+
struct vhost_log *tmf_log;
271+
unsigned int tmf_log_num;
266272
};
267273

268274
/*
@@ -452,6 +458,10 @@ static void vhost_scsi_release_tmf_res(struct vhost_scsi_tmf *tmf)
452458
{
453459
struct vhost_scsi_inflight *inflight = tmf->inflight;
454460

461+
/*
462+
* tmf->tmf_log is default NULL unless VHOST_F_LOG_ALL is set.
463+
*/
464+
kfree(tmf->tmf_log);
455465
kfree(tmf);
456466
vhost_scsi_put_inflight(inflight);
457467
}
@@ -1537,6 +1547,8 @@ static void vhost_scsi_tmf_resp_work(struct vhost_work *work)
15371547
mutex_lock(&tmf->svq->vq.mutex);
15381548
vhost_scsi_send_tmf_resp(tmf->vhost, &tmf->svq->vq, tmf->in_iovs,
15391549
tmf->vq_desc, &tmf->resp_iov, resp_code);
1550+
vhost_scsi_log_write(&tmf->svq->vq, tmf->tmf_log,
1551+
tmf->tmf_log_num);
15401552
mutex_unlock(&tmf->svq->vq.mutex);
15411553

15421554
vhost_scsi_release_tmf_res(tmf);
@@ -1560,7 +1572,8 @@ static void
15601572
vhost_scsi_handle_tmf(struct vhost_scsi *vs, struct vhost_scsi_tpg *tpg,
15611573
struct vhost_virtqueue *vq,
15621574
struct virtio_scsi_ctrl_tmf_req *vtmf,
1563-
struct vhost_scsi_ctx *vc)
1575+
struct vhost_scsi_ctx *vc,
1576+
struct vhost_log *log, unsigned int log_num)
15641577
{
15651578
struct vhost_scsi_virtqueue *svq = container_of(vq,
15661579
struct vhost_scsi_virtqueue, vq);
@@ -1588,6 +1601,19 @@ vhost_scsi_handle_tmf(struct vhost_scsi *vs, struct vhost_scsi_tpg *tpg,
15881601
tmf->in_iovs = vc->in;
15891602
tmf->inflight = vhost_scsi_get_inflight(vq);
15901603

1604+
if (unlikely(log && log_num)) {
1605+
tmf->tmf_log = kmalloc_array(log_num, sizeof(*tmf->tmf_log),
1606+
GFP_KERNEL);
1607+
if (tmf->tmf_log) {
1608+
memcpy(tmf->tmf_log, log, sizeof(*tmf->tmf_log) * log_num);
1609+
tmf->tmf_log_num = log_num;
1610+
} else {
1611+
pr_err("vhost_scsi tmf log allocation error\n");
1612+
vhost_scsi_release_tmf_res(tmf);
1613+
goto send_reject;
1614+
}
1615+
}
1616+
15911617
if (target_submit_tmr(&tmf->se_cmd, tpg->tpg_nexus->tvn_se_sess, NULL,
15921618
vhost_buf_to_lun(vtmf->lun), NULL,
15931619
TMR_LUN_RESET, GFP_KERNEL, 0,
@@ -1601,6 +1627,7 @@ vhost_scsi_handle_tmf(struct vhost_scsi *vs, struct vhost_scsi_tpg *tpg,
16011627
send_reject:
16021628
vhost_scsi_send_tmf_resp(vs, vq, vc->in, vc->head, &vq->iov[vc->out],
16031629
VIRTIO_SCSI_S_FUNCTION_REJECTED);
1630+
vhost_scsi_log_write(vq, log, log_num);
16041631
}
16051632

16061633
static void
@@ -1637,6 +1664,8 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
16371664
struct vhost_scsi_ctx vc;
16381665
size_t typ_size;
16391666
int ret, c = 0;
1667+
struct vhost_log *vq_log;
1668+
unsigned int log_num;
16401669

16411670
mutex_lock(&vq->mutex);
16421671
/*
@@ -1650,8 +1679,11 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
16501679

16511680
vhost_disable_notify(&vs->dev, vq);
16521681

1682+
vq_log = unlikely(vhost_has_feature(vq, VHOST_F_LOG_ALL)) ?
1683+
vq->log : NULL;
1684+
16531685
do {
1654-
ret = vhost_scsi_get_desc(vs, vq, &vc, NULL, NULL);
1686+
ret = vhost_scsi_get_desc(vs, vq, &vc, vq_log, &log_num);
16551687
if (ret)
16561688
goto err;
16571689

@@ -1715,9 +1747,12 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
17151747
goto err;
17161748

17171749
if (v_req.type == VIRTIO_SCSI_T_TMF)
1718-
vhost_scsi_handle_tmf(vs, tpg, vq, &v_req.tmf, &vc);
1719-
else
1750+
vhost_scsi_handle_tmf(vs, tpg, vq, &v_req.tmf, &vc,
1751+
vq_log, log_num);
1752+
else {
17201753
vhost_scsi_send_an_resp(vs, vq, &vc);
1754+
vhost_scsi_log_write(vq, vq_log, log_num);
1755+
}
17211756
err:
17221757
/*
17231758
* ENXIO: No more requests, or read error, wait for next kick
@@ -1727,11 +1762,13 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
17271762
*/
17281763
if (ret == -ENXIO)
17291764
break;
1730-
else if (ret == -EIO)
1765+
else if (ret == -EIO) {
17311766
vhost_scsi_send_bad_target(vs, vq, &vc,
17321767
v_req.type == VIRTIO_SCSI_T_TMF ?
17331768
TYPE_CTRL_TMF :
17341769
TYPE_CTRL_AN);
1770+
vhost_scsi_log_write(vq, vq_log, log_num);
1771+
}
17351772
} while (likely(!vhost_exceeds_weight(vq, ++c, 0)));
17361773
out:
17371774
mutex_unlock(&vq->mutex);

0 commit comments

Comments
 (0)