@@ -62,16 +62,13 @@ static irqreturn_t vp_config_changed(int irq, void *opaque)
62
62
static irqreturn_t vp_vring_interrupt (int irq , void * opaque )
63
63
{
64
64
struct virtio_pci_device * vp_dev = opaque ;
65
- struct virtio_pci_vq_info * info ;
66
65
irqreturn_t ret = IRQ_NONE ;
67
- unsigned long flags ;
66
+ struct virtqueue * vq ;
68
67
69
- spin_lock_irqsave (& vp_dev -> lock , flags );
70
- list_for_each_entry (info , & vp_dev -> virtqueues , node ) {
71
- if (vring_interrupt (irq , info -> vq ) == IRQ_HANDLED )
68
+ list_for_each_entry (vq , & vp_dev -> vdev .vqs , list ) {
69
+ if (vq -> callback && vring_interrupt (irq , vq ) == IRQ_HANDLED )
72
70
ret = IRQ_HANDLED ;
73
71
}
74
- spin_unlock_irqrestore (& vp_dev -> lock , flags );
75
72
76
73
return ret ;
77
74
}
@@ -167,55 +164,6 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
167
164
return err ;
168
165
}
169
166
170
- static struct virtqueue * vp_setup_vq (struct virtio_device * vdev , unsigned index ,
171
- void (* callback )(struct virtqueue * vq ),
172
- const char * name ,
173
- u16 msix_vec )
174
- {
175
- struct virtio_pci_device * vp_dev = to_vp_device (vdev );
176
- struct virtio_pci_vq_info * info = kmalloc (sizeof * info , GFP_KERNEL );
177
- struct virtqueue * vq ;
178
- unsigned long flags ;
179
-
180
- /* fill out our structure that represents an active queue */
181
- if (!info )
182
- return ERR_PTR (- ENOMEM );
183
-
184
- vq = vp_dev -> setup_vq (vp_dev , info , index , callback , name , msix_vec );
185
- if (IS_ERR (vq ))
186
- goto out_info ;
187
-
188
- info -> vq = vq ;
189
- if (callback ) {
190
- spin_lock_irqsave (& vp_dev -> lock , flags );
191
- list_add (& info -> node , & vp_dev -> virtqueues );
192
- spin_unlock_irqrestore (& vp_dev -> lock , flags );
193
- } else {
194
- INIT_LIST_HEAD (& info -> node );
195
- }
196
-
197
- vp_dev -> vqs [index ] = info ;
198
- return vq ;
199
-
200
- out_info :
201
- kfree (info );
202
- return vq ;
203
- }
204
-
205
- static void vp_del_vq (struct virtqueue * vq )
206
- {
207
- struct virtio_pci_device * vp_dev = to_vp_device (vq -> vdev );
208
- struct virtio_pci_vq_info * info = vp_dev -> vqs [vq -> index ];
209
- unsigned long flags ;
210
-
211
- spin_lock_irqsave (& vp_dev -> lock , flags );
212
- list_del (& info -> node );
213
- spin_unlock_irqrestore (& vp_dev -> lock , flags );
214
-
215
- vp_dev -> del_vq (info );
216
- kfree (info );
217
- }
218
-
219
167
/* the config->del_vqs() implementation */
220
168
void vp_del_vqs (struct virtio_device * vdev )
221
169
{
@@ -224,16 +172,15 @@ void vp_del_vqs(struct virtio_device *vdev)
224
172
int i ;
225
173
226
174
list_for_each_entry_safe (vq , n , & vdev -> vqs , list ) {
227
- if (vp_dev -> per_vq_vectors ) {
228
- int v = vp_dev -> vqs [vq -> index ]-> msix_vector ;
175
+ if (vp_dev -> msix_vector_map ) {
176
+ int v = vp_dev -> msix_vector_map [vq -> index ];
229
177
230
178
if (v != VIRTIO_MSI_NO_VECTOR )
231
179
free_irq (pci_irq_vector (vp_dev -> pci_dev , v ),
232
180
vq );
233
181
}
234
- vp_del_vq (vq );
182
+ vp_dev -> del_vq (vq );
235
183
}
236
- vp_dev -> per_vq_vectors = false;
237
184
238
185
if (vp_dev -> intx_enabled ) {
239
186
free_irq (vp_dev -> pci_dev -> irq , vp_dev );
@@ -261,8 +208,8 @@ void vp_del_vqs(struct virtio_device *vdev)
261
208
vp_dev -> msix_names = NULL ;
262
209
kfree (vp_dev -> msix_affinity_masks );
263
210
vp_dev -> msix_affinity_masks = NULL ;
264
- kfree (vp_dev -> vqs );
265
- vp_dev -> vqs = NULL ;
211
+ kfree (vp_dev -> msix_vector_map );
212
+ vp_dev -> msix_vector_map = NULL ;
266
213
}
267
214
268
215
static int vp_find_vqs_msix (struct virtio_device * vdev , unsigned nvqs ,
@@ -275,10 +222,6 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
275
222
u16 msix_vec ;
276
223
int i , err , nvectors , allocated_vectors ;
277
224
278
- vp_dev -> vqs = kcalloc (nvqs , sizeof (* vp_dev -> vqs ), GFP_KERNEL );
279
- if (!vp_dev -> vqs )
280
- return - ENOMEM ;
281
-
282
225
if (per_vq_vectors ) {
283
226
/* Best option: one for change interrupt, one per vq. */
284
227
nvectors = 1 ;
@@ -294,7 +237,13 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
294
237
if (err )
295
238
goto error_find ;
296
239
297
- vp_dev -> per_vq_vectors = per_vq_vectors ;
240
+ if (per_vq_vectors ) {
241
+ vp_dev -> msix_vector_map = kmalloc_array (nvqs ,
242
+ sizeof (* vp_dev -> msix_vector_map ), GFP_KERNEL );
243
+ if (!vp_dev -> msix_vector_map )
244
+ goto error_find ;
245
+ }
246
+
298
247
allocated_vectors = vp_dev -> msix_used_vectors ;
299
248
for (i = 0 ; i < nvqs ; ++ i ) {
300
249
if (!names [i ]) {
@@ -304,19 +253,25 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
304
253
305
254
if (!callbacks [i ])
306
255
msix_vec = VIRTIO_MSI_NO_VECTOR ;
307
- else if (vp_dev -> per_vq_vectors )
256
+ else if (per_vq_vectors )
308
257
msix_vec = allocated_vectors ++ ;
309
258
else
310
259
msix_vec = VP_MSIX_VQ_VECTOR ;
311
- vqs [i ] = vp_setup_vq (vdev , i , callbacks [i ], names [i ], msix_vec );
260
+ vqs [i ] = vp_dev -> setup_vq (vp_dev , i , callbacks [i ], names [i ],
261
+ msix_vec );
312
262
if (IS_ERR (vqs [i ])) {
313
263
err = PTR_ERR (vqs [i ]);
314
264
goto error_find ;
315
265
}
316
266
317
- if (!vp_dev -> per_vq_vectors || msix_vec == VIRTIO_MSI_NO_VECTOR )
267
+ if (!per_vq_vectors )
318
268
continue ;
319
269
270
+ if (msix_vec == VIRTIO_MSI_NO_VECTOR ) {
271
+ vp_dev -> msix_vector_map [i ] = VIRTIO_MSI_NO_VECTOR ;
272
+ continue ;
273
+ }
274
+
320
275
/* allocate per-vq irq if available and necessary */
321
276
snprintf (vp_dev -> msix_names [msix_vec ],
322
277
sizeof * vp_dev -> msix_names ,
@@ -326,8 +281,12 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
326
281
vring_interrupt , 0 ,
327
282
vp_dev -> msix_names [msix_vec ],
328
283
vqs [i ]);
329
- if (err )
284
+ if (err ) {
285
+ /* don't free this irq on error */
286
+ vp_dev -> msix_vector_map [i ] = VIRTIO_MSI_NO_VECTOR ;
330
287
goto error_find ;
288
+ }
289
+ vp_dev -> msix_vector_map [i ] = msix_vec ;
331
290
}
332
291
return 0 ;
333
292
@@ -343,23 +302,18 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs,
343
302
struct virtio_pci_device * vp_dev = to_vp_device (vdev );
344
303
int i , err ;
345
304
346
- vp_dev -> vqs = kcalloc (nvqs , sizeof (* vp_dev -> vqs ), GFP_KERNEL );
347
- if (!vp_dev -> vqs )
348
- return - ENOMEM ;
349
-
350
305
err = request_irq (vp_dev -> pci_dev -> irq , vp_interrupt , IRQF_SHARED ,
351
306
dev_name (& vdev -> dev ), vp_dev );
352
307
if (err )
353
308
goto out_del_vqs ;
354
309
355
310
vp_dev -> intx_enabled = 1 ;
356
- vp_dev -> per_vq_vectors = false;
357
311
for (i = 0 ; i < nvqs ; ++ i ) {
358
312
if (!names [i ]) {
359
313
vqs [i ] = NULL ;
360
314
continue ;
361
315
}
362
- vqs [i ] = vp_setup_vq ( vdev , i , callbacks [i ], names [i ],
316
+ vqs [i ] = vp_dev -> setup_vq ( vp_dev , i , callbacks [i ], names [i ],
363
317
VIRTIO_MSI_NO_VECTOR );
364
318
if (IS_ERR (vqs [i ])) {
365
319
err = PTR_ERR (vqs [i ]);
@@ -409,16 +363,15 @@ int vp_set_vq_affinity(struct virtqueue *vq, int cpu)
409
363
{
410
364
struct virtio_device * vdev = vq -> vdev ;
411
365
struct virtio_pci_device * vp_dev = to_vp_device (vdev );
412
- struct virtio_pci_vq_info * info = vp_dev -> vqs [vq -> index ];
413
- struct cpumask * mask ;
414
- unsigned int irq ;
415
366
416
367
if (!vq -> callback )
417
368
return - EINVAL ;
418
369
419
370
if (vp_dev -> msix_enabled ) {
420
- mask = vp_dev -> msix_affinity_masks [info -> msix_vector ];
421
- irq = pci_irq_vector (vp_dev -> pci_dev , info -> msix_vector );
371
+ int vec = vp_dev -> msix_vector_map [vq -> index ];
372
+ struct cpumask * mask = vp_dev -> msix_affinity_masks [vec ];
373
+ unsigned int irq = pci_irq_vector (vp_dev -> pci_dev , vec );
374
+
422
375
if (cpu == -1 )
423
376
irq_set_affinity_hint (irq , NULL );
424
377
else {
@@ -498,8 +451,6 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
498
451
vp_dev -> vdev .dev .parent = & pci_dev -> dev ;
499
452
vp_dev -> vdev .dev .release = virtio_pci_release_dev ;
500
453
vp_dev -> pci_dev = pci_dev ;
501
- INIT_LIST_HEAD (& vp_dev -> virtqueues );
502
- spin_lock_init (& vp_dev -> lock );
503
454
504
455
/* enable the device */
505
456
rc = pci_enable_device (pci_dev );
0 commit comments