3838#include <linux/dma-mapping.h>
3939#include <linux/slab.h>
4040#include <linux/io-mapping.h>
41+ #include <linux/interrupt.h>
4142#include <linux/mlx5/driver.h>
4243#include <linux/mlx5/cq.h>
4344#include <linux/mlx5/qp.h>
@@ -208,7 +209,8 @@ static void release_bar(struct pci_dev *pdev)
208209
209210static int mlx5_enable_msix (struct mlx5_core_dev * dev )
210211{
211- struct mlx5_eq_table * table = & dev -> priv .eq_table ;
212+ struct mlx5_priv * priv = & dev -> priv ;
213+ struct mlx5_eq_table * table = & priv -> eq_table ;
212214 int num_eqs = 1 << dev -> caps .gen .log_max_eq ;
213215 int nvec ;
214216 int i ;
@@ -218,29 +220,37 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev)
218220 if (nvec <= MLX5_EQ_VEC_COMP_BASE )
219221 return - ENOMEM ;
220222
221- table -> msix_arr = kzalloc (nvec * sizeof (* table -> msix_arr ), GFP_KERNEL );
222- if (!table -> msix_arr )
223- return - ENOMEM ;
223+ priv -> msix_arr = kcalloc (nvec , sizeof (* priv -> msix_arr ), GFP_KERNEL );
224+
225+ priv -> irq_info = kcalloc (nvec , sizeof (* priv -> irq_info ), GFP_KERNEL );
226+ if (!priv -> msix_arr || !priv -> irq_info )
227+ goto err_free_msix ;
224228
225229 for (i = 0 ; i < nvec ; i ++ )
226- table -> msix_arr [i ].entry = i ;
230+ priv -> msix_arr [i ].entry = i ;
227231
228- nvec = pci_enable_msix_range (dev -> pdev , table -> msix_arr ,
232+ nvec = pci_enable_msix_range (dev -> pdev , priv -> msix_arr ,
229233 MLX5_EQ_VEC_COMP_BASE + 1 , nvec );
230234 if (nvec < 0 )
231235 return nvec ;
232236
233237 table -> num_comp_vectors = nvec - MLX5_EQ_VEC_COMP_BASE ;
234238
235239 return 0 ;
240+
241+ err_free_msix :
242+ kfree (priv -> irq_info );
243+ kfree (priv -> msix_arr );
244+ return - ENOMEM ;
236245}
237246
238247static void mlx5_disable_msix (struct mlx5_core_dev * dev )
239248{
240- struct mlx5_eq_table * table = & dev -> priv . eq_table ;
249+ struct mlx5_priv * priv = & dev -> priv ;
241250
242251 pci_disable_msix (dev -> pdev );
243- kfree (table -> msix_arr );
252+ kfree (priv -> irq_info );
253+ kfree (priv -> msix_arr );
244254}
245255
246256struct mlx5_reg_host_endianess {
@@ -507,6 +517,77 @@ static int mlx5_core_disable_hca(struct mlx5_core_dev *dev)
507517 return 0 ;
508518}
509519
520+ static int mlx5_irq_set_affinity_hint (struct mlx5_core_dev * mdev , int i )
521+ {
522+ struct mlx5_priv * priv = & mdev -> priv ;
523+ struct msix_entry * msix = priv -> msix_arr ;
524+ int irq = msix [i + MLX5_EQ_VEC_COMP_BASE ].vector ;
525+ int numa_node = dev_to_node (& mdev -> pdev -> dev );
526+ int err ;
527+
528+ if (!zalloc_cpumask_var (& priv -> irq_info [i ].mask , GFP_KERNEL )) {
529+ mlx5_core_warn (mdev , "zalloc_cpumask_var failed" );
530+ return - ENOMEM ;
531+ }
532+
533+ err = cpumask_set_cpu_local_first (i , numa_node , priv -> irq_info [i ].mask );
534+ if (err ) {
535+ mlx5_core_warn (mdev , "cpumask_set_cpu_local_first failed" );
536+ goto err_clear_mask ;
537+ }
538+
539+ err = irq_set_affinity_hint (irq , priv -> irq_info [i ].mask );
540+ if (err ) {
541+ mlx5_core_warn (mdev , "irq_set_affinity_hint failed,irq 0x%.4x" ,
542+ irq );
543+ goto err_clear_mask ;
544+ }
545+
546+ return 0 ;
547+
548+ err_clear_mask :
549+ free_cpumask_var (priv -> irq_info [i ].mask );
550+ return err ;
551+ }
552+
553+ static void mlx5_irq_clear_affinity_hint (struct mlx5_core_dev * mdev , int i )
554+ {
555+ struct mlx5_priv * priv = & mdev -> priv ;
556+ struct msix_entry * msix = priv -> msix_arr ;
557+ int irq = msix [i + MLX5_EQ_VEC_COMP_BASE ].vector ;
558+
559+ irq_set_affinity_hint (irq , NULL );
560+ free_cpumask_var (priv -> irq_info [i ].mask );
561+ }
562+
563+ static int mlx5_irq_set_affinity_hints (struct mlx5_core_dev * mdev )
564+ {
565+ int err ;
566+ int i ;
567+
568+ for (i = 0 ; i < mdev -> priv .eq_table .num_comp_vectors ; i ++ ) {
569+ err = mlx5_irq_set_affinity_hint (mdev , i );
570+ if (err )
571+ goto err_out ;
572+ }
573+
574+ return 0 ;
575+
576+ err_out :
577+ for (i -- ; i >= 0 ; i -- )
578+ mlx5_irq_clear_affinity_hint (mdev , i );
579+
580+ return err ;
581+ }
582+
583+ static void mlx5_irq_clear_affinity_hints (struct mlx5_core_dev * mdev )
584+ {
585+ int i ;
586+
587+ for (i = 0 ; i < mdev -> priv .eq_table .num_comp_vectors ; i ++ )
588+ mlx5_irq_clear_affinity_hint (mdev , i );
589+ }
590+
510591int mlx5_vector2eqn (struct mlx5_core_dev * dev , int vector , int * eqn , int * irqn )
511592{
512593 struct mlx5_eq_table * table = & dev -> priv .eq_table ;
@@ -549,7 +630,7 @@ static void free_comp_eqs(struct mlx5_core_dev *dev)
549630static int alloc_comp_eqs (struct mlx5_core_dev * dev )
550631{
551632 struct mlx5_eq_table * table = & dev -> priv .eq_table ;
552- char name [MLX5_MAX_EQ_NAME ];
633+ char name [MLX5_MAX_IRQ_NAME ];
553634 struct mlx5_eq * eq ;
554635 int ncomp_vec ;
555636 int nent ;
@@ -566,7 +647,7 @@ static int alloc_comp_eqs(struct mlx5_core_dev *dev)
566647 goto clean ;
567648 }
568649
569- snprintf (name , MLX5_MAX_EQ_NAME , "mlx5_comp%d" , i );
650+ snprintf (name , MLX5_MAX_IRQ_NAME , "mlx5_comp%d" , i );
570651 err = mlx5_create_map_eq (dev , eq ,
571652 i + MLX5_EQ_VEC_COMP_BASE , nent , 0 ,
572653 name , & dev -> priv .uuari .uars [0 ]);
@@ -730,6 +811,12 @@ static int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev)
730811 goto err_stop_eqs ;
731812 }
732813
814+ err = mlx5_irq_set_affinity_hints (dev );
815+ if (err ) {
816+ dev_err (& pdev -> dev , "Failed to alloc affinity hint cpumask\n" );
817+ goto err_free_comp_eqs ;
818+ }
819+
733820 MLX5_INIT_DOORBELL_LOCK (& priv -> cq_uar_lock );
734821
735822 mlx5_init_cq_table (dev );
@@ -739,6 +826,9 @@ static int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev)
739826
740827 return 0 ;
741828
829+ err_free_comp_eqs :
830+ free_comp_eqs (dev );
831+
742832err_stop_eqs :
743833 mlx5_stop_eqs (dev );
744834
@@ -793,6 +883,7 @@ static void mlx5_dev_cleanup(struct mlx5_core_dev *dev)
793883 mlx5_cleanup_srq_table (dev );
794884 mlx5_cleanup_qp_table (dev );
795885 mlx5_cleanup_cq_table (dev );
886+ mlx5_irq_clear_affinity_hints (dev );
796887 free_comp_eqs (dev );
797888 mlx5_stop_eqs (dev );
798889 mlx5_free_uuars (dev , & priv -> uuari );
0 commit comments