@@ -143,13 +143,13 @@ void vp_del_vqs(struct virtio_device *vdev)
143143
144144static int vp_find_vqs_msix (struct virtio_device * vdev , unsigned nvqs ,
145145 struct virtqueue * vqs [], vq_callback_t * callbacks [],
146- const char * const names [], struct irq_affinity * desc )
146+ const char * const names [], bool per_vq_vectors ,
147+ struct irq_affinity * desc )
147148{
148149 struct virtio_pci_device * vp_dev = to_vp_device (vdev );
149150 const char * name = dev_name (& vp_dev -> vdev .dev );
150151 int i , err = - ENOMEM , allocated_vectors , nvectors ;
151152 unsigned flags = PCI_IRQ_MSIX ;
152- bool shared = false;
153153 u16 msix_vec ;
154154
155155 if (desc ) {
@@ -162,16 +162,12 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
162162 if (callbacks [i ])
163163 nvectors ++ ;
164164
165- /* Try one vector per queue first. */
166- err = pci_alloc_irq_vectors_affinity (vp_dev -> pci_dev , nvectors ,
167- nvectors , flags , desc );
168- if (err < 0 ) {
169- /* Fallback to one vector for config, one shared for queues. */
170- shared = true;
165+ if (per_vq_vectors ) {
166+ err = pci_alloc_irq_vectors_affinity (vp_dev -> pci_dev , nvectors ,
167+ nvectors , flags , desc );
168+ } else {
171169 err = pci_alloc_irq_vectors (vp_dev -> pci_dev , 2 , 2 ,
172170 PCI_IRQ_MSIX );
173- if (err < 0 )
174- return err ;
175171 }
176172 if (err < 0 )
177173 return err ;
@@ -199,7 +195,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
199195 err = request_irq (pci_irq_vector (vp_dev -> pci_dev , 0 ), vp_config_changed ,
200196 0 , vp_dev -> msix_names [0 ], vp_dev );
201197 if (err )
202- goto out_free_msix_affinity_masks ;
198+ goto out_free_irq_vectors ;
203199
204200 /* Verify we had enough resources to assign the vector */
205201 if (vp_dev -> config_vector (vp_dev , 0 ) == VIRTIO_MSI_NO_VECTOR ) {
@@ -249,11 +245,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
249245 }
250246 vp_dev -> msix_vector_map [i ] = msix_vec ;
251247
252- /*
253- * Use a different vector for each queue if they are available,
254- * else share the same vector for all VQs.
255- */
256- if (!shared )
248+ if (per_vq_vectors )
257249 allocated_vectors ++ ;
258250 }
259251
@@ -319,9 +311,15 @@ int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
319311{
320312 int err ;
321313
322- err = vp_find_vqs_msix (vdev , nvqs , vqs , callbacks , names , desc );
314+ /* Try MSI-X with one vector per queue. */
315+ err = vp_find_vqs_msix (vdev , nvqs , vqs , callbacks , names , true, desc );
316+ if (!err )
317+ return 0 ;
318+ /* Fallback: MSI-X with one vector for config, one shared for queues. */
319+ err = vp_find_vqs_msix (vdev , nvqs , vqs , callbacks , names , false, desc );
323320 if (!err )
324321 return 0 ;
322+ /* Finally fall back to regular interrupts. */
325323 return vp_find_vqs_intx (vdev , nvqs , vqs , callbacks , names );
326324}
327325
0 commit comments