@@ -265,6 +265,18 @@ static void ionic_intr_free(struct ionic *ionic, int index)
265265 clear_bit (index , ionic -> intrs );
266266}
267267
268+ static void ionic_irq_aff_notify (struct irq_affinity_notify * notify ,
269+ const cpumask_t * mask )
270+ {
271+ struct ionic_intr_info * intr = container_of (notify , struct ionic_intr_info , aff_notify );
272+
273+ cpumask_copy (* intr -> affinity_mask , mask );
274+ }
275+
276+ static void ionic_irq_aff_release (struct kref __always_unused * ref )
277+ {
278+ }
279+
268280static int ionic_qcq_enable (struct ionic_qcq * qcq )
269281{
270282 struct ionic_queue * q = & qcq -> q ;
@@ -299,8 +311,10 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
299311
300312 if (qcq -> flags & IONIC_QCQ_F_INTR ) {
301313 napi_enable (& qcq -> napi );
314+ irq_set_affinity_notifier (qcq -> intr .vector ,
315+ & qcq -> intr .aff_notify );
302316 irq_set_affinity_hint (qcq -> intr .vector ,
303- & qcq -> intr .affinity_mask );
317+ * qcq -> intr .affinity_mask );
304318 ionic_intr_mask (idev -> intr_ctrl , qcq -> intr .index ,
305319 IONIC_INTR_MASK_CLEAR );
306320 }
@@ -334,6 +348,7 @@ static int ionic_qcq_disable(struct ionic_lif *lif, struct ionic_qcq *qcq, int f
334348 ionic_intr_mask (idev -> intr_ctrl , qcq -> intr .index ,
335349 IONIC_INTR_MASK_SET );
336350 synchronize_irq (qcq -> intr .vector );
351+ irq_set_affinity_notifier (qcq -> intr .vector , NULL );
337352 irq_set_affinity_hint (qcq -> intr .vector , NULL );
338353 napi_disable (& qcq -> napi );
339354 }
@@ -474,6 +489,7 @@ static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq,
474489
475490static int ionic_alloc_qcq_interrupt (struct ionic_lif * lif , struct ionic_qcq * qcq )
476491{
492+ cpumask_var_t * affinity_mask ;
477493 int err ;
478494
479495 if (!(qcq -> flags & IONIC_QCQ_F_INTR )) {
@@ -505,10 +521,19 @@ static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qc
505521 }
506522
507523 /* try to get the irq on the local numa node first */
508- qcq -> intr .cpu = cpumask_local_spread (qcq -> intr .index ,
509- dev_to_node (lif -> ionic -> dev ));
510- if (qcq -> intr .cpu != -1 )
511- cpumask_set_cpu (qcq -> intr .cpu , & qcq -> intr .affinity_mask );
524+ affinity_mask = & lif -> ionic -> affinity_masks [qcq -> intr .index ];
525+ if (cpumask_empty (* affinity_mask )) {
526+ unsigned int cpu ;
527+
528+ cpu = cpumask_local_spread (qcq -> intr .index ,
529+ dev_to_node (lif -> ionic -> dev ));
530+ if (cpu != -1 )
531+ cpumask_set_cpu (cpu , * affinity_mask );
532+ }
533+
534+ qcq -> intr .affinity_mask = affinity_mask ;
535+ qcq -> intr .aff_notify .notify = ionic_irq_aff_notify ;
536+ qcq -> intr .aff_notify .release = ionic_irq_aff_release ;
512537
513538 netdev_dbg (lif -> netdev , "%s: Interrupt index %d\n" , qcq -> q .name , qcq -> intr .index );
514539 return 0 ;
@@ -3120,6 +3145,44 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
31203145 return err ;
31213146}
31223147
3148+ static int ionic_affinity_masks_alloc (struct ionic * ionic )
3149+ {
3150+ cpumask_var_t * affinity_masks ;
3151+ int nintrs = ionic -> nintrs ;
3152+ int i ;
3153+
3154+ affinity_masks = kcalloc (nintrs , sizeof (cpumask_var_t ), GFP_KERNEL );
3155+ if (!affinity_masks )
3156+ return - ENOMEM ;
3157+
3158+ for (i = 0 ; i < nintrs ; i ++ ) {
3159+ if (!zalloc_cpumask_var_node (& affinity_masks [i ], GFP_KERNEL ,
3160+ dev_to_node (ionic -> dev )))
3161+ goto err_out ;
3162+ }
3163+
3164+ ionic -> affinity_masks = affinity_masks ;
3165+
3166+ return 0 ;
3167+
3168+ err_out :
3169+ for (-- i ; i >= 0 ; i -- )
3170+ free_cpumask_var (affinity_masks [i ]);
3171+ kfree (affinity_masks );
3172+
3173+ return - ENOMEM ;
3174+ }
3175+
3176+ static void ionic_affinity_masks_free (struct ionic * ionic )
3177+ {
3178+ int i ;
3179+
3180+ for (i = 0 ; i < ionic -> nintrs ; i ++ )
3181+ free_cpumask_var (ionic -> affinity_masks [i ]);
3182+ kfree (ionic -> affinity_masks );
3183+ ionic -> affinity_masks = NULL ;
3184+ }
3185+
31233186int ionic_lif_alloc (struct ionic * ionic )
31243187{
31253188 struct device * dev = ionic -> dev ;
@@ -3211,11 +3274,15 @@ int ionic_lif_alloc(struct ionic *ionic)
32113274
32123275 ionic_debugfs_add_lif (lif );
32133276
3277+ err = ionic_affinity_masks_alloc (ionic );
3278+ if (err )
3279+ goto err_out_free_lif_info ;
3280+
32143281 /* allocate control queues and txrx queue arrays */
32153282 ionic_lif_queue_identify (lif );
32163283 err = ionic_qcqs_alloc (lif );
32173284 if (err )
3218- goto err_out_free_lif_info ;
3285+ goto err_out_free_affinity_masks ;
32193286
32203287 /* allocate rss indirection table */
32213288 tbl_sz = le16_to_cpu (lif -> ionic -> ident .lif .eth .rss_ind_tbl_sz );
@@ -3237,6 +3304,8 @@ int ionic_lif_alloc(struct ionic *ionic)
32373304
32383305err_out_free_qcqs :
32393306 ionic_qcqs_free (lif );
3307+ err_out_free_affinity_masks :
3308+ ionic_affinity_masks_free (lif -> ionic );
32403309err_out_free_lif_info :
32413310 dma_free_coherent (dev , lif -> info_sz , lif -> info , lif -> info_pa );
32423311 lif -> info = NULL ;
@@ -3410,6 +3479,8 @@ void ionic_lif_free(struct ionic_lif *lif)
34103479 if (!test_bit (IONIC_LIF_F_FW_RESET , lif -> state ))
34113480 ionic_lif_reset (lif );
34123481
3482+ ionic_affinity_masks_free (lif -> ionic );
3483+
34133484 /* free lif info */
34143485 kfree (lif -> identity );
34153486 dma_free_coherent (dev , lif -> info_sz , lif -> info , lif -> info_pa );
@@ -3487,7 +3558,7 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif)
34873558
34883559 if (qcq -> flags & IONIC_QCQ_F_INTR ) {
34893560 irq_set_affinity_hint (qcq -> intr .vector ,
3490- & qcq -> intr .affinity_mask );
3561+ * qcq -> intr .affinity_mask );
34913562 ionic_intr_mask (idev -> intr_ctrl , qcq -> intr .index ,
34923563 IONIC_INTR_MASK_CLEAR );
34933564 }
0 commit comments