cxgb4: Set initial IRQ affinity hints
authorNirranjan Kirubaharan <nirranjan@chelsio.com>
Fri, 7 Jun 2019 11:56:45 +0000 (04:56 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 9 Jun 2019 20:30:39 +0000 (13:30 -0700)
Spread initial IRQ affinity hints across the device node CPUs,
for nic queue and uld queue IRQs, to load balance and avoid
all interrupts on CPU0.

Signed-off-by: Nirranjan Kirubaharan <nirranjan@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c

index 7c06e2aebc9e9432ab30beb777338b7c3b436ab1..db2ec46ba6b65e3a79b74944f6415b6d0e48c195 100644 (file)
@@ -880,6 +880,7 @@ struct uld_msix_info {
        unsigned short vec;
        char desc[IFNAMSIZ + 10];
        unsigned int idx;
+       cpumask_var_t aff_mask;
 };
 
 struct vf_info {
@@ -940,9 +941,10 @@ struct adapter {
        struct cxgb4_virt_res vres;
        unsigned int swintr;
 
-       struct {
+       struct msix_info {
                unsigned short vec;
                char desc[IFNAMSIZ + 10];
+               cpumask_var_t aff_mask;
        } msix_info[MAX_INGQ + 1];
        struct uld_msix_info *msix_info_ulds; /* msix info for uld's */
        struct uld_msix_bmap msix_bmap_ulds; /* msix bitmap for all uld */
@@ -1900,5 +1902,8 @@ int cxgb4_dcb_enabled(const struct net_device *dev);
 
 int cxgb4_thermal_init(struct adapter *adap);
 int cxgb4_thermal_remove(struct adapter *adap);
+int cxgb4_set_msix_aff(struct adapter *adap, unsigned short vec,
+                      cpumask_var_t *aff_mask, int idx);
+void cxgb4_clear_msix_aff(unsigned short vec, cpumask_var_t aff_mask);
 
 #endif /* __CXGB4_H__ */
index 7d7df59f9a708819ad42cbba10649f46025f8e4c..cd957a1eea45be036b8fd5c8f946a05b05abc0a2 100644 (file)
@@ -702,9 +702,38 @@ static void name_msix_vecs(struct adapter *adap)
        }
 }
 
+int cxgb4_set_msix_aff(struct adapter *adap, unsigned short vec,
+                      cpumask_var_t *aff_mask, int idx)
+{
+       int rv;
+
+       if (!zalloc_cpumask_var(aff_mask, GFP_KERNEL)) {
+               dev_err(adap->pdev_dev, "alloc_cpumask_var failed\n");
+               return -ENOMEM;
+       }
+
+       cpumask_set_cpu(cpumask_local_spread(idx, dev_to_node(adap->pdev_dev)),
+                       *aff_mask);
+
+       rv = irq_set_affinity_hint(vec, *aff_mask);
+       if (rv)
+               dev_warn(adap->pdev_dev,
+                        "irq_set_affinity_hint %u failed %d\n",
+                        vec, rv);
+
+       return 0;
+}
+
+void cxgb4_clear_msix_aff(unsigned short vec, cpumask_var_t aff_mask)
+{
+       irq_set_affinity_hint(vec, NULL);
+       free_cpumask_var(aff_mask);
+}
+
 static int request_msix_queue_irqs(struct adapter *adap)
 {
        struct sge *s = &adap->sge;
+       struct msix_info *minfo;
        int err, ethqidx;
        int msi_index = 2;
 
@@ -714,32 +743,43 @@ static int request_msix_queue_irqs(struct adapter *adap)
                return err;
 
        for_each_ethrxq(s, ethqidx) {
-               err = request_irq(adap->msix_info[msi_index].vec,
+               minfo = &adap->msix_info[msi_index];
+               err = request_irq(minfo->vec,
                                  t4_sge_intr_msix, 0,
-                                 adap->msix_info[msi_index].desc,
+                                 minfo->desc,
                                  &s->ethrxq[ethqidx].rspq);
                if (err)
                        goto unwind;
+
+               cxgb4_set_msix_aff(adap, minfo->vec,
+                                  &minfo->aff_mask, ethqidx);
                msi_index++;
        }
        return 0;
 
 unwind:
-       while (--ethqidx >= 0)
-               free_irq(adap->msix_info[--msi_index].vec,
-                        &s->ethrxq[ethqidx].rspq);
+       while (--ethqidx >= 0) {
+               msi_index--;
+               minfo = &adap->msix_info[msi_index];
+               cxgb4_clear_msix_aff(minfo->vec, minfo->aff_mask);
+               free_irq(minfo->vec, &s->ethrxq[ethqidx].rspq);
+       }
        free_irq(adap->msix_info[1].vec, &s->fw_evtq);
        return err;
 }
 
 static void free_msix_queue_irqs(struct adapter *adap)
 {
-       int i, msi_index = 2;
        struct sge *s = &adap->sge;
+       struct msix_info *minfo;
+       int i, msi_index = 2;
 
        free_irq(adap->msix_info[1].vec, &s->fw_evtq);
-       for_each_ethrxq(s, i)
-               free_irq(adap->msix_info[msi_index++].vec, &s->ethrxq[i].rspq);
+       for_each_ethrxq(s, i) {
+               minfo = &adap->msix_info[msi_index++];
+               cxgb4_clear_msix_aff(minfo->vec, minfo->aff_mask);
+               free_irq(minfo->vec, &s->ethrxq[i].rspq);
+       }
 }
 
 /**
index 6c685b920713e8b0c4ab8b507f3715dff50b8fcd..5b602243d573fe745578e9390209a1813a1b6d57 100644 (file)
@@ -352,25 +352,32 @@ static int
 request_msix_queue_irqs_uld(struct adapter *adap, unsigned int uld_type)
 {
        struct sge_uld_rxq_info *rxq_info = adap->sge.uld_rxq_info[uld_type];
+       struct uld_msix_info *minfo;
        int err = 0;
        unsigned int idx, bmap_idx;
 
        for_each_uldrxq(rxq_info, idx) {
                bmap_idx = rxq_info->msix_tbl[idx];
-               err = request_irq(adap->msix_info_ulds[bmap_idx].vec,
+               minfo = &adap->msix_info_ulds[bmap_idx];
+               err = request_irq(minfo->vec,
                                  t4_sge_intr_msix, 0,
-                                 adap->msix_info_ulds[bmap_idx].desc,
+                                 minfo->desc,
                                  &rxq_info->uldrxq[idx].rspq);
                if (err)
                        goto unwind;
+
+               cxgb4_set_msix_aff(adap, minfo->vec,
+                                  &minfo->aff_mask, idx);
        }
        return 0;
+
 unwind:
        while (idx-- > 0) {
                bmap_idx = rxq_info->msix_tbl[idx];
+               minfo = &adap->msix_info_ulds[bmap_idx];
+               cxgb4_clear_msix_aff(minfo->vec, minfo->aff_mask);
                free_msix_idx_in_bmap(adap, bmap_idx);
-               free_irq(adap->msix_info_ulds[bmap_idx].vec,
-                        &rxq_info->uldrxq[idx].rspq);
+               free_irq(minfo->vec, &rxq_info->uldrxq[idx].rspq);
        }
        return err;
 }
@@ -379,14 +386,16 @@ static void
 free_msix_queue_irqs_uld(struct adapter *adap, unsigned int uld_type)
 {
        struct sge_uld_rxq_info *rxq_info = adap->sge.uld_rxq_info[uld_type];
+       struct uld_msix_info *minfo;
        unsigned int idx, bmap_idx;
 
        for_each_uldrxq(rxq_info, idx) {
                bmap_idx = rxq_info->msix_tbl[idx];
+               minfo = &adap->msix_info_ulds[bmap_idx];
 
+               cxgb4_clear_msix_aff(minfo->vec, minfo->aff_mask);
                free_msix_idx_in_bmap(adap, bmap_idx);
-               free_irq(adap->msix_info_ulds[bmap_idx].vec,
-                        &rxq_info->uldrxq[idx].rspq);
+               free_irq(minfo->vec, &rxq_info->uldrxq[idx].rspq);
        }
 }