@@ -126,11 +126,9 @@ static void pds_vdpa_release_irq(struct pds_vdpa_device *pdsv, int qid)
126126static void pds_vdpa_set_vq_ready (struct vdpa_device * vdpa_dev , u16 qid , bool ready )
127127{
128128 struct pds_vdpa_device * pdsv = vdpa_to_pdsv (vdpa_dev );
129- struct pci_dev * pdev = pdsv -> vdpa_aux -> padev -> vf_pdev ;
130129 struct device * dev = & pdsv -> vdpa_dev .dev ;
131130 u64 driver_features ;
132131 u16 invert_idx = 0 ;
133- int irq ;
134132 int err ;
135133
136134 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
143141 invert_idx = PDS_VDPA_PACKED_INVERT_IDX ;
144142
145143 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-
159144 /* Pass vq setup info to DSC using adminq to gather up and
160145 * send all info at once so FW can do its full set up in
161146 * one easy operation
@@ -164,15 +149,13 @@ static void pds_vdpa_set_vq_ready(struct vdpa_device *vdpa_dev, u16 qid, bool re
164149 if (err ) {
165150 dev_err (dev , "Failed to init vq %d: %pe\n" ,
166151 qid , ERR_PTR (err ));
167- pds_vdpa_release_irq (pdsv , qid );
168152 ready = false;
169153 }
170154 } else {
171155 err = pds_vdpa_cmd_reset_vq (pdsv , qid , invert_idx , & pdsv -> vqs [qid ]);
172156 if (err )
173157 dev_err (dev , "%s: reset_vq failed qid %d: %pe\n" ,
174158 __func__ , qid , ERR_PTR (err ));
175- pds_vdpa_release_irq (pdsv , qid );
176159 }
177160
178161 pdsv -> vqs [qid ].ready = ready ;
@@ -395,6 +378,72 @@ static u8 pds_vdpa_get_status(struct vdpa_device *vdpa_dev)
395378 return vp_modern_get_status (& pdsv -> vdpa_aux -> vd_mdev );
396379}
397380
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+
398447static void pds_vdpa_set_status (struct vdpa_device * vdpa_dev , u8 status )
399448{
400449 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)
405454 old_status = pds_vdpa_get_status (vdpa_dev );
406455 dev_dbg (dev , "%s: old %#x new %#x\n" , __func__ , old_status , status );
407456
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+
408462 pds_vdpa_cmd_set_status (pdsv , status );
409463
410464 /* 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)
426480 i , & pdsv -> vqs [i ].notify_pa );
427481 }
428482 }
483+
484+ if (old_status & ~status & VIRTIO_CONFIG_S_DRIVER_OK )
485+ pds_vdpa_release_irqs (pdsv );
429486}
430487
431488static 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)
460517 if (err )
461518 dev_err (dev , "%s: reset_vq failed qid %d: %pe\n" ,
462519 __func__ , i , ERR_PTR (err ));
463- pds_vdpa_release_irq (pdsv , i );
464- pds_vdpa_init_vqs_entry (pdsv , i , pdsv -> vqs [i ].notify );
465520 }
466521 }
467522
468523 pds_vdpa_set_status (vdpa_dev , 0 );
469524
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+
470531 return 0 ;
471532}
472533
@@ -764,7 +825,7 @@ int pds_vdpa_get_mgmt_info(struct pds_vdpa_aux *vdpa_aux)
764825
765826 max_vqs = min_t (u16 , dev_intrs , max_vqs );
766827 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 ;
768829
769830 mgmt -> ops = & pds_vdpa_mgmt_dev_ops ;
770831 mgmt -> id_table = pds_vdpa_id_table ;
@@ -778,14 +839,5 @@ int pds_vdpa_get_mgmt_info(struct pds_vdpa_aux *vdpa_aux)
778839 mgmt -> config_attr_mask |= BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP );
779840 mgmt -> config_attr_mask |= BIT_ULL (VDPA_ATTR_DEV_FEATURES );
780841
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-
790842 return 0 ;
791843}
0 commit comments