@@ -284,6 +284,44 @@ void vp_del_vqs(struct virtio_device *vdev)
284284 vp_dev -> vqs = NULL ;
285285}
286286
287+ static struct virtqueue * vp_find_one_vq_msix (struct virtio_device * vdev ,
288+ int queue_idx ,
289+ vq_callback_t * callback ,
290+ const char * name , bool ctx ,
291+ int * allocated_vectors )
292+ {
293+ struct virtio_pci_device * vp_dev = to_vp_device (vdev );
294+ struct virtqueue * vq ;
295+ u16 msix_vec ;
296+ int err ;
297+
298+ if (!callback )
299+ msix_vec = VIRTIO_MSI_NO_VECTOR ;
300+ else if (vp_dev -> per_vq_vectors )
301+ msix_vec = (* allocated_vectors )++ ;
302+ else
303+ msix_vec = VP_MSIX_VQ_VECTOR ;
304+ vq = vp_setup_vq (vdev , queue_idx , callback , name , ctx , msix_vec );
305+ if (IS_ERR (vq ))
306+ return vq ;
307+
308+ if (!vp_dev -> per_vq_vectors || msix_vec == VIRTIO_MSI_NO_VECTOR )
309+ return vq ;
310+
311+ /* allocate per-vq irq if available and necessary */
312+ snprintf (vp_dev -> msix_names [msix_vec ], sizeof (* vp_dev -> msix_names ),
313+ "%s-%s" , dev_name (& vp_dev -> vdev .dev ), name );
314+ err = request_irq (pci_irq_vector (vp_dev -> pci_dev , msix_vec ),
315+ vring_interrupt , 0 ,
316+ vp_dev -> msix_names [msix_vec ], vq );
317+ if (err ) {
318+ vp_del_vq (vq );
319+ return ERR_PTR (err );
320+ }
321+
322+ return vq ;
323+ }
324+
287325static int vp_find_vqs_msix (struct virtio_device * vdev , unsigned int nvqs ,
288326 struct virtqueue * vqs [],
289327 struct virtqueue_info vqs_info [],
@@ -292,7 +330,6 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
292330{
293331 struct virtio_pci_device * vp_dev = to_vp_device (vdev );
294332 struct virtqueue_info * vqi ;
295- u16 msix_vec ;
296333 int i , err , nvectors , allocated_vectors , queue_idx = 0 ;
297334
298335 vp_dev -> vqs = kcalloc (nvqs , sizeof (* vp_dev -> vqs ), GFP_KERNEL );
@@ -325,36 +362,13 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
325362 vqs [i ] = NULL ;
326363 continue ;
327364 }
328-
329- if (!vqi -> callback )
330- msix_vec = VIRTIO_MSI_NO_VECTOR ;
331- else if (vp_dev -> per_vq_vectors )
332- msix_vec = allocated_vectors ++ ;
333- else
334- msix_vec = VP_MSIX_VQ_VECTOR ;
335- vqs [i ] = vp_setup_vq (vdev , queue_idx ++ , vqi -> callback ,
336- vqi -> name , vqi -> ctx , msix_vec );
365+ vqs [i ] = vp_find_one_vq_msix (vdev , queue_idx ++ , vqi -> callback ,
366+ vqi -> name , vqi -> ctx ,
367+ & allocated_vectors );
337368 if (IS_ERR (vqs [i ])) {
338369 err = PTR_ERR (vqs [i ]);
339370 goto error_find ;
340371 }
341-
342- if (!vp_dev -> per_vq_vectors || msix_vec == VIRTIO_MSI_NO_VECTOR )
343- continue ;
344-
345- /* allocate per-vq irq if available and necessary */
346- snprintf (vp_dev -> msix_names [msix_vec ],
347- sizeof * vp_dev -> msix_names ,
348- "%s-%s" ,
349- dev_name (& vp_dev -> vdev .dev ), vqi -> name );
350- err = request_irq (pci_irq_vector (vp_dev -> pci_dev , msix_vec ),
351- vring_interrupt , 0 ,
352- vp_dev -> msix_names [msix_vec ],
353- vqs [i ]);
354- if (err ) {
355- vp_del_vq (vqs [i ]);
356- goto error_find ;
357- }
358372 }
359373 return 0 ;
360374
0 commit comments