be2net: assign CPU affinity hints to be2net IRQs
authorPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Thu, 26 Mar 2015 07:05:08 +0000 (03:05 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 29 Mar 2015 19:34:00 +0000 (12:34 -0700)
This patch provides hints to irqbalance to map be2net IRQs to
specific CPU cores. cpumask_set_cpu_local_first() is used, which first
maps IRQs to near NUMA cores; when those cores are exhausted, IRQs are
mapped to far NUMA cores.

Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_main.c

index eb39673ed6a6b4c3a52f7ba487fa8538b4763a37..a2fe1f394c30264e1e1862636eb86c2ce8cdfe07 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <linux/u64_stats_sync.h>
+#include <linux/cpumask.h>
 
 #include "be_hw.h"
 #include "be_roce.h"
@@ -183,6 +184,7 @@ struct be_eq_obj {
        u16 spurious_intr;
        struct napi_struct napi;
        struct be_adapter *adapter;
+       cpumask_var_t  affinity_mask;
 
 #ifdef CONFIG_NET_RX_BUSY_POLL
 #define BE_EQ_IDLE             0
index d8df78b6554d03176a7b4f3fd00eb30c6bd76e6a..3541207a8fed25db5889f0a449e5a24214daaab1 100644 (file)
@@ -2342,6 +2342,7 @@ static void be_evt_queues_destroy(struct be_adapter *adapter)
                        napi_hash_del(&eqo->napi);
                        netif_napi_del(&eqo->napi);
                }
+               free_cpumask_var(eqo->affinity_mask);
                be_queue_free(adapter, &eqo->q);
        }
 }
@@ -2357,6 +2358,11 @@ static int be_evt_queues_create(struct be_adapter *adapter)
                                    adapter->cfg_num_qs);
 
        for_all_evt_queues(adapter, eqo, i) {
+               if (!zalloc_cpumask_var(&eqo->affinity_mask, GFP_KERNEL))
+                       return -ENOMEM;
+               cpumask_set_cpu_local_first(i, dev_to_node(&adapter->pdev->dev),
+                                           eqo->affinity_mask);
+
                netif_napi_add(adapter->netdev, &eqo->napi, be_poll,
                               BE_NAPI_WEIGHT);
                napi_hash_add(&eqo->napi);
@@ -3028,6 +3034,8 @@ static int be_msix_register(struct be_adapter *adapter)
                status = request_irq(vec, be_msix, 0, eqo->desc, eqo);
                if (status)
                        goto err_msix;
+
+               irq_set_affinity_hint(vec, eqo->affinity_mask);
        }
 
        return 0;
@@ -3072,7 +3080,7 @@ static void be_irq_unregister(struct be_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
        struct be_eq_obj *eqo;
-       int i;
+       int i, vec;
 
        if (!adapter->isr_registered)
                return;
@@ -3084,8 +3092,11 @@ static void be_irq_unregister(struct be_adapter *adapter)
        }
 
        /* MSIx */
-       for_all_evt_queues(adapter, eqo, i)
-               free_irq(be_msix_vec_get(adapter, eqo), eqo);
+       for_all_evt_queues(adapter, eqo, i) {
+               vec = be_msix_vec_get(adapter, eqo);
+               irq_set_affinity_hint(vec, NULL);
+               free_irq(vec, eqo);
+       }
 
 done:
        adapter->isr_registered = false;