@@ -126,11 +126,9 @@ static void pds_vdpa_release_irq(struct pds_vdpa_device *pdsv, int qid)
126
126
static void pds_vdpa_set_vq_ready (struct vdpa_device * vdpa_dev , u16 qid , bool ready )
127
127
{
128
128
struct pds_vdpa_device * pdsv = vdpa_to_pdsv (vdpa_dev );
129
- struct pci_dev * pdev = pdsv -> vdpa_aux -> padev -> vf_pdev ;
130
129
struct device * dev = & pdsv -> vdpa_dev .dev ;
131
130
u64 driver_features ;
132
131
u16 invert_idx = 0 ;
133
- int irq ;
134
132
int err ;
135
133
136
134
dev_dbg (dev , "%s: qid %d ready %d => %d\n" ,
@@ -143,19 +141,6 @@ static void pds_vdpa_set_vq_ready(struct vdpa_device *vdpa_dev, u16 qid, bool re
143
141
invert_idx = PDS_VDPA_PACKED_INVERT_IDX ;
144
142
145
143
if (ready ) {
146
- irq = pci_irq_vector (pdev , qid );
147
- snprintf (pdsv -> vqs [qid ].irq_name , sizeof (pdsv -> vqs [qid ].irq_name ),
148
- "vdpa-%s-%d" , dev_name (dev ), qid );
149
-
150
- err = request_irq (irq , pds_vdpa_isr , 0 ,
151
- pdsv -> vqs [qid ].irq_name , & pdsv -> vqs [qid ]);
152
- if (err ) {
153
- dev_err (dev , "%s: no irq for qid %d: %pe\n" ,
154
- __func__ , qid , ERR_PTR (err ));
155
- return ;
156
- }
157
- pdsv -> vqs [qid ].irq = irq ;
158
-
159
144
/* Pass vq setup info to DSC using adminq to gather up and
160
145
* send all info at once so FW can do its full set up in
161
146
* one easy operation
@@ -164,15 +149,13 @@ static void pds_vdpa_set_vq_ready(struct vdpa_device *vdpa_dev, u16 qid, bool re
164
149
if (err ) {
165
150
dev_err (dev , "Failed to init vq %d: %pe\n" ,
166
151
qid , ERR_PTR (err ));
167
- pds_vdpa_release_irq (pdsv , qid );
168
152
ready = false;
169
153
}
170
154
} else {
171
155
err = pds_vdpa_cmd_reset_vq (pdsv , qid , invert_idx , & pdsv -> vqs [qid ]);
172
156
if (err )
173
157
dev_err (dev , "%s: reset_vq failed qid %d: %pe\n" ,
174
158
__func__ , qid , ERR_PTR (err ));
175
- pds_vdpa_release_irq (pdsv , qid );
176
159
}
177
160
178
161
pdsv -> vqs [qid ].ready = ready ;
@@ -395,6 +378,72 @@ static u8 pds_vdpa_get_status(struct vdpa_device *vdpa_dev)
395
378
return vp_modern_get_status (& pdsv -> vdpa_aux -> vd_mdev );
396
379
}
397
380
381
+ static int pds_vdpa_request_irqs (struct pds_vdpa_device * pdsv )
382
+ {
383
+ struct pci_dev * pdev = pdsv -> vdpa_aux -> padev -> vf_pdev ;
384
+ struct pds_vdpa_aux * vdpa_aux = pdsv -> vdpa_aux ;
385
+ struct device * dev = & pdsv -> vdpa_dev .dev ;
386
+ int max_vq , nintrs , qid , err ;
387
+
388
+ max_vq = vdpa_aux -> vdpa_mdev .max_supported_vqs ;
389
+
390
+ nintrs = pci_alloc_irq_vectors (pdev , max_vq , max_vq , PCI_IRQ_MSIX );
391
+ if (nintrs < 0 ) {
392
+ dev_err (dev , "Couldn't get %d msix vectors: %pe\n" ,
393
+ max_vq , ERR_PTR (nintrs ));
394
+ return nintrs ;
395
+ }
396
+
397
+ for (qid = 0 ; qid < pdsv -> num_vqs ; ++ qid ) {
398
+ int irq = pci_irq_vector (pdev , qid );
399
+
400
+ snprintf (pdsv -> vqs [qid ].irq_name , sizeof (pdsv -> vqs [qid ].irq_name ),
401
+ "vdpa-%s-%d" , dev_name (dev ), qid );
402
+
403
+ err = request_irq (irq , pds_vdpa_isr , 0 ,
404
+ pdsv -> vqs [qid ].irq_name ,
405
+ & pdsv -> vqs [qid ]);
406
+ if (err ) {
407
+ dev_err (dev , "%s: no irq for qid %d: %pe\n" ,
408
+ __func__ , qid , ERR_PTR (err ));
409
+ goto err_release ;
410
+ }
411
+
412
+ pdsv -> vqs [qid ].irq = irq ;
413
+ }
414
+
415
+ vdpa_aux -> nintrs = nintrs ;
416
+
417
+ return 0 ;
418
+
419
+ err_release :
420
+ while (qid -- )
421
+ pds_vdpa_release_irq (pdsv , qid );
422
+
423
+ pci_free_irq_vectors (pdev );
424
+
425
+ vdpa_aux -> nintrs = 0 ;
426
+
427
+ return err ;
428
+ }
429
+
430
+ static void pds_vdpa_release_irqs (struct pds_vdpa_device * pdsv )
431
+ {
432
+ struct pci_dev * pdev = pdsv -> vdpa_aux -> padev -> vf_pdev ;
433
+ struct pds_vdpa_aux * vdpa_aux = pdsv -> vdpa_aux ;
434
+ int qid ;
435
+
436
+ if (!vdpa_aux -> nintrs )
437
+ return ;
438
+
439
+ for (qid = 0 ; qid < pdsv -> num_vqs ; qid ++ )
440
+ pds_vdpa_release_irq (pdsv , qid );
441
+
442
+ pci_free_irq_vectors (pdev );
443
+
444
+ vdpa_aux -> nintrs = 0 ;
445
+ }
446
+
398
447
static void pds_vdpa_set_status (struct vdpa_device * vdpa_dev , u8 status )
399
448
{
400
449
struct pds_vdpa_device * pdsv = vdpa_to_pdsv (vdpa_dev );
@@ -405,6 +454,11 @@ static void pds_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
405
454
old_status = pds_vdpa_get_status (vdpa_dev );
406
455
dev_dbg (dev , "%s: old %#x new %#x\n" , __func__ , old_status , status );
407
456
457
+ if (status & ~old_status & VIRTIO_CONFIG_S_DRIVER_OK ) {
458
+ if (pds_vdpa_request_irqs (pdsv ))
459
+ status = old_status | VIRTIO_CONFIG_S_FAILED ;
460
+ }
461
+
408
462
pds_vdpa_cmd_set_status (pdsv , status );
409
463
410
464
/* Note: still working with FW on the need for this reset cmd */
@@ -426,6 +480,9 @@ static void pds_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
426
480
i , & pdsv -> vqs [i ].notify_pa );
427
481
}
428
482
}
483
+
484
+ if (old_status & ~status & VIRTIO_CONFIG_S_DRIVER_OK )
485
+ pds_vdpa_release_irqs (pdsv );
429
486
}
430
487
431
488
static void pds_vdpa_init_vqs_entry (struct pds_vdpa_device * pdsv , int qid ,
@@ -460,13 +517,17 @@ static int pds_vdpa_reset(struct vdpa_device *vdpa_dev)
460
517
if (err )
461
518
dev_err (dev , "%s: reset_vq failed qid %d: %pe\n" ,
462
519
__func__ , i , ERR_PTR (err ));
463
- pds_vdpa_release_irq (pdsv , i );
464
- pds_vdpa_init_vqs_entry (pdsv , i , pdsv -> vqs [i ].notify );
465
520
}
466
521
}
467
522
468
523
pds_vdpa_set_status (vdpa_dev , 0 );
469
524
525
+ if (status & VIRTIO_CONFIG_S_DRIVER_OK ) {
526
+ /* Reset the vq info */
527
+ for (i = 0 ; i < pdsv -> num_vqs && !err ; i ++ )
528
+ pds_vdpa_init_vqs_entry (pdsv , i , pdsv -> vqs [i ].notify );
529
+ }
530
+
470
531
return 0 ;
471
532
}
472
533
@@ -764,7 +825,7 @@ int pds_vdpa_get_mgmt_info(struct pds_vdpa_aux *vdpa_aux)
764
825
765
826
max_vqs = min_t (u16 , dev_intrs , max_vqs );
766
827
mgmt -> max_supported_vqs = min_t (u16 , PDS_VDPA_MAX_QUEUES , max_vqs );
767
- vdpa_aux -> nintrs = mgmt -> max_supported_vqs ;
828
+ vdpa_aux -> nintrs = 0 ;
768
829
769
830
mgmt -> ops = & pds_vdpa_mgmt_dev_ops ;
770
831
mgmt -> id_table = pds_vdpa_id_table ;
@@ -778,14 +839,5 @@ int pds_vdpa_get_mgmt_info(struct pds_vdpa_aux *vdpa_aux)
778
839
mgmt -> config_attr_mask |= BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP );
779
840
mgmt -> config_attr_mask |= BIT_ULL (VDPA_ATTR_DEV_FEATURES );
780
841
781
- err = pci_alloc_irq_vectors (pdev , vdpa_aux -> nintrs , vdpa_aux -> nintrs ,
782
- PCI_IRQ_MSIX );
783
- if (err < 0 ) {
784
- dev_err (dev , "Couldn't get %d msix vectors: %pe\n" ,
785
- vdpa_aux -> nintrs , ERR_PTR (err ));
786
- return err ;
787
- }
788
- vdpa_aux -> nintrs = err ;
789
-
790
842
return 0 ;
791
843
}
0 commit comments