@@ -167,6 +167,7 @@ MODULE_PARM_DESC(max_io_vqs, "Set the max number of IO virtqueues a vhost scsi d
167167
168168struct vhost_scsi_virtqueue {
169169 struct vhost_virtqueue vq ;
170+ struct vhost_scsi * vs ;
170171 /*
171172 * Reference counting for inflight reqs, used for flush operation. At
172173 * each time, one reference tracks new commands submitted, while we
@@ -181,6 +182,9 @@ struct vhost_scsi_virtqueue {
181182 struct vhost_scsi_cmd * scsi_cmds ;
182183 struct sbitmap scsi_tags ;
183184 int max_cmds ;
185+
186+ struct vhost_work completion_work ;
187+ struct llist_head completion_list ;
184188};
185189
186190struct vhost_scsi {
@@ -190,12 +194,8 @@ struct vhost_scsi {
190194
191195 struct vhost_dev dev ;
192196 struct vhost_scsi_virtqueue * vqs ;
193- unsigned long * compl_bitmap ;
194197 struct vhost_scsi_inflight * * old_inflight ;
195198
196- struct vhost_work vs_completion_work ; /* cmd completion work item */
197- struct llist_head vs_completion_list ; /* cmd completion queue */
198-
199199 struct vhost_work vs_event_work ; /* evt injection work item */
200200 struct llist_head vs_event_list ; /* evt injection queue */
201201
@@ -358,10 +358,11 @@ static void vhost_scsi_release_cmd(struct se_cmd *se_cmd)
358358 } else {
359359 struct vhost_scsi_cmd * cmd = container_of (se_cmd ,
360360 struct vhost_scsi_cmd , tvc_se_cmd );
361- struct vhost_scsi * vs = cmd -> tvc_vhost ;
361+ struct vhost_scsi_virtqueue * svq = container_of (cmd -> tvc_vq ,
362+ struct vhost_scsi_virtqueue , vq );
362363
363- llist_add (& cmd -> tvc_completion_list , & vs -> vs_completion_list );
364- vhost_work_queue ( & vs -> dev , & vs -> vs_completion_work );
364+ llist_add (& cmd -> tvc_completion_list , & svq -> completion_list );
365+ vhost_vq_work_queue ( & svq -> vq , & svq -> completion_work );
365366 }
366367}
367368
@@ -509,17 +510,17 @@ static void vhost_scsi_evt_work(struct vhost_work *work)
509510 */
510511static void vhost_scsi_complete_cmd_work (struct vhost_work * work )
511512{
512- struct vhost_scsi * vs = container_of (work , struct vhost_scsi ,
513- vs_completion_work );
513+ struct vhost_scsi_virtqueue * svq = container_of (work ,
514+ struct vhost_scsi_virtqueue , completion_work );
514515 struct virtio_scsi_cmd_resp v_rsp ;
515516 struct vhost_scsi_cmd * cmd , * t ;
516517 struct llist_node * llnode ;
517518 struct se_cmd * se_cmd ;
518519 struct iov_iter iov_iter ;
519- int ret , vq ;
520+ bool signal = false;
521+ int ret ;
520522
521- bitmap_zero (vs -> compl_bitmap , vs -> dev .nvqs );
522- llnode = llist_del_all (& vs -> vs_completion_list );
523+ llnode = llist_del_all (& svq -> completion_list );
523524 llist_for_each_entry_safe (cmd , t , llnode , tvc_completion_list ) {
524525 se_cmd = & cmd -> tvc_se_cmd ;
525526
@@ -539,21 +540,17 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
539540 cmd -> tvc_in_iovs , sizeof (v_rsp ));
540541 ret = copy_to_iter (& v_rsp , sizeof (v_rsp ), & iov_iter );
541542 if (likely (ret == sizeof (v_rsp ))) {
542- struct vhost_scsi_virtqueue * q ;
543+ signal = true;
544+
543545 vhost_add_used (cmd -> tvc_vq , cmd -> tvc_vq_desc , 0 );
544- q = container_of (cmd -> tvc_vq , struct vhost_scsi_virtqueue , vq );
545- vq = q - vs -> vqs ;
546- __set_bit (vq , vs -> compl_bitmap );
547546 } else
548547 pr_err ("Faulted on virtio_scsi_cmd_resp\n" );
549548
550549 vhost_scsi_release_cmd_res (se_cmd );
551550 }
552551
553- vq = -1 ;
554- while ((vq = find_next_bit (vs -> compl_bitmap , vs -> dev .nvqs , vq + 1 ))
555- < vs -> dev .nvqs )
556- vhost_signal (& vs -> dev , & vs -> vqs [vq ].vq );
552+ if (signal )
553+ vhost_signal (& svq -> vs -> dev , & svq -> vq );
557554}
558555
559556static struct vhost_scsi_cmd *
@@ -1770,6 +1767,7 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
17701767
17711768static int vhost_scsi_open (struct inode * inode , struct file * f )
17721769{
1770+ struct vhost_scsi_virtqueue * svq ;
17731771 struct vhost_scsi * vs ;
17741772 struct vhost_virtqueue * * vqs ;
17751773 int r = - ENOMEM , i , nvqs = vhost_scsi_max_io_vqs ;
@@ -1788,10 +1786,6 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
17881786 }
17891787 nvqs += VHOST_SCSI_VQ_IO ;
17901788
1791- vs -> compl_bitmap = bitmap_alloc (nvqs , GFP_KERNEL );
1792- if (!vs -> compl_bitmap )
1793- goto err_compl_bitmap ;
1794-
17951789 vs -> old_inflight = kmalloc_array (nvqs , sizeof (* vs -> old_inflight ),
17961790 GFP_KERNEL | __GFP_ZERO );
17971791 if (!vs -> old_inflight )
@@ -1806,7 +1800,6 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
18061800 if (!vqs )
18071801 goto err_local_vqs ;
18081802
1809- vhost_work_init (& vs -> vs_completion_work , vhost_scsi_complete_cmd_work );
18101803 vhost_work_init (& vs -> vs_event_work , vhost_scsi_evt_work );
18111804
18121805 vs -> vs_events_nr = 0 ;
@@ -1817,8 +1810,14 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
18171810 vs -> vqs [VHOST_SCSI_VQ_CTL ].vq .handle_kick = vhost_scsi_ctl_handle_kick ;
18181811 vs -> vqs [VHOST_SCSI_VQ_EVT ].vq .handle_kick = vhost_scsi_evt_handle_kick ;
18191812 for (i = VHOST_SCSI_VQ_IO ; i < nvqs ; i ++ ) {
1820- vqs [i ] = & vs -> vqs [i ].vq ;
1821- vs -> vqs [i ].vq .handle_kick = vhost_scsi_handle_kick ;
1813+ svq = & vs -> vqs [i ];
1814+
1815+ vqs [i ] = & svq -> vq ;
1816+ svq -> vs = vs ;
1817+ init_llist_head (& svq -> completion_list );
1818+ vhost_work_init (& svq -> completion_work ,
1819+ vhost_scsi_complete_cmd_work );
1820+ svq -> vq .handle_kick = vhost_scsi_handle_kick ;
18221821 }
18231822 vhost_dev_init (& vs -> dev , vqs , nvqs , UIO_MAXIOV ,
18241823 VHOST_SCSI_WEIGHT , 0 , true, NULL );
@@ -1833,8 +1832,6 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
18331832err_vqs :
18341833 kfree (vs -> old_inflight );
18351834err_inflight :
1836- bitmap_free (vs -> compl_bitmap );
1837- err_compl_bitmap :
18381835 kvfree (vs );
18391836err_vs :
18401837 return r ;
@@ -1854,7 +1851,6 @@ static int vhost_scsi_release(struct inode *inode, struct file *f)
18541851 kfree (vs -> dev .vqs );
18551852 kfree (vs -> vqs );
18561853 kfree (vs -> old_inflight );
1857- bitmap_free (vs -> compl_bitmap );
18581854 kvfree (vs );
18591855 return 0 ;
18601856}
0 commit comments