@@ -830,6 +830,7 @@ static int xe_irq_msix_init(struct xe_device *xe)
830830 }
831831
832832 xe -> irq .msix .nvec = nvec ;
833+ xa_init_flags (& xe -> irq .msix .indexes , XA_FLAGS_ALLOC );
833834 return 0 ;
834835}
835836
@@ -879,8 +880,32 @@ static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg)
879880 return IRQ_HANDLED ;
880881}
881882
882- static int xe_irq_msix_request_irq (struct xe_device * xe , irq_handler_t handler ,
883- const char * name , u16 msix )
883+ static int xe_irq_msix_alloc_vector (struct xe_device * xe , void * irq_buf ,
884+ bool dynamic_msix , u16 * msix )
885+ {
886+ struct xa_limit limit ;
887+ int ret ;
888+ u32 id ;
889+
890+ limit = (dynamic_msix ) ? XA_LIMIT (NUM_OF_STATIC_MSIX , xe -> irq .msix .nvec - 1 ) :
891+ XA_LIMIT (* msix , * msix );
892+ ret = xa_alloc (& xe -> irq .msix .indexes , & id , irq_buf , limit , GFP_KERNEL );
893+ if (ret )
894+ return ret ;
895+
896+ if (dynamic_msix )
897+ * msix = id ;
898+
899+ return 0 ;
900+ }
901+
902+ static void xe_irq_msix_release_vector (struct xe_device * xe , u16 msix )
903+ {
904+ xa_erase (& xe -> irq .msix .indexes , msix );
905+ }
906+
907+ static int xe_irq_msix_request_irq_internal (struct xe_device * xe , irq_handler_t handler ,
908+ void * irq_buf , const char * name , u16 msix )
884909{
885910 struct pci_dev * pdev = to_pci_dev (xe -> drm .dev );
886911 int ret , irq ;
@@ -889,59 +914,90 @@ static int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler,
889914 if (irq < 0 )
890915 return irq ;
891916
892- ret = request_irq (irq , handler , IRQF_SHARED , name , xe );
917+ ret = request_irq (irq , handler , IRQF_SHARED , name , irq_buf );
893918 if (ret < 0 )
894919 return ret ;
895920
896921 return 0 ;
897922}
898923
899- static void xe_irq_msix_free_irq (struct xe_device * xe , u16 msix )
924+ int xe_irq_msix_request_irq (struct xe_device * xe , irq_handler_t handler , void * irq_buf ,
925+ const char * name , bool dynamic_msix , u16 * msix )
926+ {
927+ int ret ;
928+
929+ ret = xe_irq_msix_alloc_vector (xe , irq_buf , dynamic_msix , msix );
930+ if (ret )
931+ return ret ;
932+
933+ ret = xe_irq_msix_request_irq_internal (xe , handler , irq_buf , name , * msix );
934+ if (ret ) {
935+ drm_err (& xe -> drm , "Failed to request IRQ for MSI-X %u\n" , * msix );
936+ xe_irq_msix_release_vector (xe , * msix );
937+ return ret ;
938+ }
939+
940+ return 0 ;
941+ }
942+
943+ void xe_irq_msix_free_irq (struct xe_device * xe , u16 msix )
900944{
901945 struct pci_dev * pdev = to_pci_dev (xe -> drm .dev );
902946 int irq ;
947+ void * irq_buf ;
948+
949+ irq_buf = xa_load (& xe -> irq .msix .indexes , msix );
950+ if (!irq_buf )
951+ return ;
903952
904953 irq = pci_irq_vector (pdev , msix );
905954 if (irq < 0 ) {
906955 drm_err (& xe -> drm , "MSI-X %u can't be released, there is no matching IRQ\n" , msix );
907956 return ;
908957 }
909958
910- free_irq (irq , xe );
959+ free_irq (irq , irq_buf );
960+ xe_irq_msix_release_vector (xe , msix );
911961}
912962
913- static int xe_irq_msix_request_irqs (struct xe_device * xe )
963+ int xe_irq_msix_request_irqs (struct xe_device * xe )
914964{
915965 int err ;
966+ u16 msix ;
916967
917- err = xe_irq_msix_request_irq ( xe , guc2host_irq_handler ,
918- DRIVER_NAME "-guc2host" , GUC2HOST_MSIX );
919- if ( err ) {
920- drm_err ( & xe -> drm , "Failed to request MSI-X IRQ %d: %d\n" , GUC2HOST_MSIX , err );
968+ msix = GUC2HOST_MSIX ;
969+ err = xe_irq_msix_request_irq ( xe , guc2host_irq_handler , xe ,
970+ DRIVER_NAME "-guc2host" , false, & msix );
971+ if ( err )
921972 return err ;
922- }
923973
924- err = xe_irq_msix_request_irq (xe , xe_irq_msix_default_hwe_handler ,
925- DRIVER_NAME "-default-msix" , DEFAULT_MSIX );
974+ msix = DEFAULT_MSIX ;
975+ err = xe_irq_msix_request_irq (xe , xe_irq_msix_default_hwe_handler , xe ,
976+ DRIVER_NAME "-default-msix" , false, & msix );
926977 if (err ) {
927- drm_err (& xe -> drm , "Failed to request MSI-X IRQ %d: %d\n" , DEFAULT_MSIX , err );
928978 xe_irq_msix_free_irq (xe , GUC2HOST_MSIX );
929979 return err ;
930980 }
931981
932982 return 0 ;
933983}
934984
935- static void xe_irq_msix_free (struct xe_device * xe )
985+ void xe_irq_msix_free (struct xe_device * xe )
936986{
937- xe_irq_msix_free_irq (xe , GUC2HOST_MSIX );
938- xe_irq_msix_free_irq (xe , DEFAULT_MSIX );
987+ unsigned long msix ;
988+ u32 * dummy ;
989+
990+ xa_for_each (& xe -> irq .msix .indexes , msix , dummy )
991+ xe_irq_msix_free_irq (xe , msix );
992+ xa_destroy (& xe -> irq .msix .indexes );
939993}
940994
941- static void xe_irq_msix_synchronize_irq (struct xe_device * xe )
995+ void xe_irq_msix_synchronize_irq (struct xe_device * xe )
942996{
943997 struct pci_dev * pdev = to_pci_dev (xe -> drm .dev );
998+ unsigned long msix ;
999+ u32 * dummy ;
9441000
945- synchronize_irq ( pci_irq_vector ( pdev , GUC2HOST_MSIX ));
946- synchronize_irq (pci_irq_vector (pdev , DEFAULT_MSIX ));
1001+ xa_for_each ( & xe -> irq . msix . indexes , msix , dummy )
1002+ synchronize_irq (pci_irq_vector (pdev , msix ));
9471003}
0 commit comments