This hooks vhost-scsi into the vring set cpu ioctl support by just replacing it's existing workqueue use with the vhost support. Signed-off-by: Mike Christie <michael.christie@xxxxxxxxxx> --- drivers/vhost/scsi.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 8005a7f..29b139c 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -101,8 +101,6 @@ struct vhost_scsi_cmd { struct vhost_scsi_nexus *tvc_nexus; /* The TCM I/O descriptor that is accessed via container_of() */ struct se_cmd tvc_se_cmd; - /* work item used for cmwq dispatch to vhost_scsi_submission_work() */ - struct work_struct work; /* Copy of the incoming SCSI command descriptor block (CDB) */ unsigned char tvc_cdb[VHOST_SCSI_MAX_CDB_SIZE]; /* Sense buffer that will be mapped into outgoing status */ @@ -778,10 +776,8 @@ static int vhost_scsi_to_tcm_attr(int attr) return TCM_SIMPLE_TAG; } -static void vhost_scsi_submission_work(struct work_struct *work) +static void vhost_scsi_target_submit(struct vhost_scsi_cmd *cmd) { - struct vhost_scsi_cmd *cmd = - container_of(work, struct vhost_scsi_cmd, work); struct vhost_scsi_nexus *tv_nexus; struct se_cmd *se_cmd = &cmd->tvc_se_cmd; struct scatterlist *sg_ptr, *sg_prot_ptr = NULL; @@ -1128,14 +1124,7 @@ static u16 vhost_buf_to_lun(u8 *lun_buf) * vhost_scsi_queue_data_in() and vhost_scsi_queue_status() */ cmd->tvc_vq_desc = vc.head; - /* - * Dispatch cmd descriptor for cmwq execution in process - * context provided by vhost_scsi_workqueue. This also ensures - * cmd is executed on the same kworker CPU as this vhost - * thread to gain positive L2 cache locality effects. - */ - INIT_WORK(&cmd->work, vhost_scsi_submission_work); - queue_work(vhost_scsi_workqueue, &cmd->work); + vhost_scsi_target_submit(cmd); ret = 0; err: /* @@ -1811,6 +1800,15 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) return 0; } +static struct workqueue_struct *vhost_scsi_get_workqueue(void) +{ + return vhost_scsi_workqueue; +} + +static struct vhost_dev_ops vhost_scsi_dev_ops = { + .get_workqueue = vhost_scsi_get_workqueue, +}; + static int vhost_scsi_open(struct inode *inode, struct file *f) { struct vhost_scsi_virtqueue *svq; @@ -1849,7 +1847,7 @@ static int vhost_scsi_open(struct inode *inode, struct file *f) svq->vq.handle_kick = vhost_scsi_handle_kick; } vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV, - VHOST_SCSI_WEIGHT, 0, true, NULL); + VHOST_SCSI_WEIGHT, 0, true, &vhost_scsi_dev_ops); vhost_scsi_init_inflight(vs, NULL); @@ -2502,7 +2500,7 @@ static int __init vhost_scsi_init(void) * Use our own dedicated workqueue for submitting I/O into * target core to avoid contention within system_wq. */ - vhost_scsi_workqueue = alloc_workqueue("vhost_scsi", 0, 0); + vhost_scsi_workqueue = alloc_workqueue("vhost_scsi", WQ_SYSFS, 0); if (!vhost_scsi_workqueue) goto out; -- 1.8.3.1