net: hns: Fix the implementation of irq affinity function
authorlipeng <lipeng321@huawei.com>
Sat, 1 Apr 2017 11:03:31 +0000 (12:03 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Apr 2017 21:48:43 +0000 (14:48 -0700)
This patch fixes the implementation of the IRQ affinity
function. This function is used to create the cpu mask
which eventually is used to initialize the cpu<->queue
association for XPS(Transmit Packet Steering).

Signed-off-by: lipeng <lipeng321@huawei.com>
Signed-off-by: Kejian Yan <yankejian@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns/hns_enet.h

index fca37e2c7f017d76aa537daede5f7af14cb8e152..73ec8c8439203874eb2a5f038db3cb994a063ddb 100644 (file)
@@ -1196,54 +1196,31 @@ static void hns_nic_ring_close(struct net_device *netdev, int idx)
        napi_disable(&priv->ring_data[idx].napi);
 }
 
-static void hns_set_irq_affinity(struct hns_nic_priv *priv)
+static int hns_nic_init_affinity_mask(int q_num, int ring_idx,
+                                     struct hnae_ring *ring, cpumask_t *mask)
 {
-       struct hnae_handle *h = priv->ae_handle;
-       struct hns_nic_ring_data *rd;
-       int i;
        int cpu;
-       cpumask_var_t mask;
 
-       if (!alloc_cpumask_var(&mask, GFP_KERNEL))
-               return;
-
-       /*diffrent irq banlance for 16core and 32core*/
-       if (h->q_num == num_possible_cpus()) {
-               for (i = 0; i < h->q_num * 2; i++) {
-                       rd = &priv->ring_data[i];
-                       if (cpu_online(rd->queue_index)) {
-                               cpumask_clear(mask);
-                               cpu = rd->queue_index;
-                               cpumask_set_cpu(cpu, mask);
-                               (void)irq_set_affinity_hint(rd->ring->irq,
-                                                           mask);
-                       }
-               }
+       /* Diffrent irq banlance between 16core and 32core.
+        * The cpu mask set by ring index according to the ring flag
+        * which indicate the ring is tx or rx.
+        */
+       if (q_num == num_possible_cpus()) {
+               if (is_tx_ring(ring))
+                       cpu = ring_idx;
+               else
+                       cpu = ring_idx - q_num;
        } else {
-               for (i = 0; i < h->q_num; i++) {
-                       rd = &priv->ring_data[i];
-                       if (cpu_online(rd->queue_index * 2)) {
-                               cpumask_clear(mask);
-                               cpu = rd->queue_index * 2;
-                               cpumask_set_cpu(cpu, mask);
-                               (void)irq_set_affinity_hint(rd->ring->irq,
-                                                           mask);
-                       }
-               }
-
-               for (i = h->q_num; i < h->q_num * 2; i++) {
-                       rd = &priv->ring_data[i];
-                       if (cpu_online(rd->queue_index * 2 + 1)) {
-                               cpumask_clear(mask);
-                               cpu = rd->queue_index * 2 + 1;
-                               cpumask_set_cpu(cpu, mask);
-                               (void)irq_set_affinity_hint(rd->ring->irq,
-                                                           mask);
-                       }
-               }
+               if (is_tx_ring(ring))
+                       cpu = ring_idx * 2;
+               else
+                       cpu = (ring_idx - q_num) * 2 + 1;
        }
 
-       free_cpumask_var(mask);
+       cpumask_clear(mask);
+       cpumask_set_cpu(cpu, mask);
+
+       return cpu;
 }
 
 static int hns_nic_init_irq(struct hns_nic_priv *priv)
@@ -1252,6 +1229,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
        struct hns_nic_ring_data *rd;
        int i;
        int ret;
+       int cpu;
 
        for (i = 0; i < h->q_num * 2; i++) {
                rd = &priv->ring_data[i];
@@ -1261,7 +1239,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
 
                snprintf(rd->ring->ring_name, RCB_RING_NAME_LEN,
                         "%s-%s%d", priv->netdev->name,
-                        (i < h->q_num ? "tx" : "rx"), rd->queue_index);
+                        (is_tx_ring(rd->ring) ? "tx" : "rx"), rd->queue_index);
 
                rd->ring->ring_name[RCB_RING_NAME_LEN - 1] = '\0';
 
@@ -1273,12 +1251,17 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv)
                        return ret;
                }
                disable_irq(rd->ring->irq);
+
+               cpu = hns_nic_init_affinity_mask(h->q_num, i,
+                                                rd->ring, &rd->mask);
+
+               if (cpu_online(cpu))
+                       irq_set_affinity_hint(rd->ring->irq,
+                                             &rd->mask);
+
                rd->ring->irq_init_flag = RCB_IRQ_INITED;
        }
 
-       /*set cpu affinity*/
-       hns_set_irq_affinity(priv);
-
        return 0;
 }
 
index 5b412de350aa28e9099ee251e0824ed66f37b2b1..fff8f8a21bd07686ad7ab6a421620e8b5e487af3 100644 (file)
@@ -37,6 +37,7 @@ enum hns_nic_state {
 struct hns_nic_ring_data {
        struct hnae_ring *ring;
        struct napi_struct napi;
+       cpumask_t mask; /* affinity mask */
        int queue_index;
        int (*poll_one)(struct hns_nic_ring_data *, int, void *);
        void (*ex_process)(struct hns_nic_ring_data *, struct sk_buff *);