@@ -593,9 +593,11 @@ static void irq_pool_free(struct mlx5_irq_pool *pool)
593593 kvfree (pool );
594594}
595595
596- static int irq_pools_init (struct mlx5_core_dev * dev , int sf_vec , int pcif_vec )
596+ static int irq_pools_init (struct mlx5_core_dev * dev , int sf_vec , int pcif_vec ,
597+ bool dynamic_vec )
597598{
598599 struct mlx5_irq_table * table = dev -> priv .irq_table ;
600+ int sf_vec_available = sf_vec ;
599601 int num_sf_ctrl ;
600602 int err ;
601603
@@ -616,6 +618,13 @@ static int irq_pools_init(struct mlx5_core_dev *dev, int sf_vec, int pcif_vec)
616618 num_sf_ctrl = DIV_ROUND_UP (mlx5_sf_max_functions (dev ),
617619 MLX5_SFS_PER_CTRL_IRQ );
618620 num_sf_ctrl = min_t (int , MLX5_IRQ_CTRL_SF_MAX , num_sf_ctrl );
621+ if (!dynamic_vec && (num_sf_ctrl + 1 ) > sf_vec_available ) {
622+ mlx5_core_dbg (dev ,
623+ "Not enough IRQs for SFs control and completion pool, required=%d avail=%d\n" ,
624+ num_sf_ctrl + 1 , sf_vec_available );
625+ return 0 ;
626+ }
627+
619628 table -> sf_ctrl_pool = irq_pool_alloc (dev , pcif_vec , num_sf_ctrl ,
620629 "mlx5_sf_ctrl" ,
621630 MLX5_EQ_SHARE_IRQ_MIN_CTRL ,
@@ -624,9 +633,11 @@ static int irq_pools_init(struct mlx5_core_dev *dev, int sf_vec, int pcif_vec)
624633 err = PTR_ERR (table -> sf_ctrl_pool );
625634 goto err_pf ;
626635 }
627- /* init sf_comp_pool */
636+ sf_vec_available -= num_sf_ctrl ;
637+
638+ /* init sf_comp_pool, remaining vectors are for the SF completions */
628639 table -> sf_comp_pool = irq_pool_alloc (dev , pcif_vec + num_sf_ctrl ,
629- sf_vec - num_sf_ctrl , "mlx5_sf_comp" ,
640+ sf_vec_available , "mlx5_sf_comp" ,
630641 MLX5_EQ_SHARE_IRQ_MIN_COMP ,
631642 MLX5_EQ_SHARE_IRQ_MAX_COMP );
632643 if (IS_ERR (table -> sf_comp_pool )) {
@@ -715,6 +726,7 @@ int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table)
715726int mlx5_irq_table_create (struct mlx5_core_dev * dev )
716727{
717728 int num_eqs = mlx5_max_eq_cap_get (dev );
729+ bool dynamic_vec ;
718730 int total_vec ;
719731 int pcif_vec ;
720732 int req_vec ;
@@ -724,21 +736,31 @@ int mlx5_irq_table_create(struct mlx5_core_dev *dev)
724736 if (mlx5_core_is_sf (dev ))
725737 return 0 ;
726738
739+ /* PCI PF vectors usage is limited by online cpus, device EQs and
740+ * PCI MSI-X capability.
741+ */
727742 pcif_vec = MLX5_CAP_GEN (dev , num_ports ) * num_online_cpus () + 1 ;
728743 pcif_vec = min_t (int , pcif_vec , num_eqs );
744+ pcif_vec = min_t (int , pcif_vec , pci_msix_vec_count (dev -> pdev ));
729745
730746 total_vec = pcif_vec ;
731747 if (mlx5_sf_max_functions (dev ))
732748 total_vec += MLX5_MAX_MSIX_PER_SF * mlx5_sf_max_functions (dev );
733749 total_vec = min_t (int , total_vec , pci_msix_vec_count (dev -> pdev ));
734- pcif_vec = min_t (int , pcif_vec , pci_msix_vec_count (dev -> pdev ));
735750
736751 req_vec = pci_msix_can_alloc_dyn (dev -> pdev ) ? 1 : total_vec ;
737752 n = pci_alloc_irq_vectors (dev -> pdev , 1 , req_vec , PCI_IRQ_MSIX );
738753 if (n < 0 )
739754 return n ;
740755
741- err = irq_pools_init (dev , total_vec - pcif_vec , pcif_vec );
756+ /* Further limit vectors of the pools based on platform for non dynamic case */
757+ dynamic_vec = pci_msix_can_alloc_dyn (dev -> pdev );
758+ if (!dynamic_vec ) {
759+ pcif_vec = min_t (int , n , pcif_vec );
760+ total_vec = min_t (int , n , total_vec );
761+ }
762+
763+ err = irq_pools_init (dev , total_vec - pcif_vec , pcif_vec , dynamic_vec );
742764 if (err )
743765 pci_free_irq_vectors (dev -> pdev );
744766
0 commit comments