@@ -284,6 +284,44 @@ void vp_del_vqs(struct virtio_device *vdev)
284
284
vp_dev -> vqs = NULL ;
285
285
}
286
286
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
+
287
325
static int vp_find_vqs_msix (struct virtio_device * vdev , unsigned int nvqs ,
288
326
struct virtqueue * vqs [],
289
327
struct virtqueue_info vqs_info [],
@@ -292,7 +330,6 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
292
330
{
293
331
struct virtio_pci_device * vp_dev = to_vp_device (vdev );
294
332
struct virtqueue_info * vqi ;
295
- u16 msix_vec ;
296
333
int i , err , nvectors , allocated_vectors , queue_idx = 0 ;
297
334
298
335
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,
325
362
vqs [i ] = NULL ;
326
363
continue ;
327
364
}
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 );
337
368
if (IS_ERR (vqs [i ])) {
338
369
err = PTR_ERR (vqs [i ]);
339
370
goto error_find ;
340
371
}
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
- }
358
372
}
359
373
return 0 ;
360
374
0 commit comments