]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
net: hns: Optimize hns_nic_common_poll for better performance
authorlipeng <lipeng321@huawei.com>
Sat, 1 Apr 2017 11:03:36 +0000 (12:03 +0100)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Wed, 28 Jun 2017 14:24:09 +0000 (11:24 -0300)
BugLink: https://bugs.launchpad.net/bugs/1696031
After polling less than buget packages, we need check again. If
there are still some packages, we call napi_schedule add softirq
queue, this is not better way. So we return buget value instead
of napi_schedule.

Signed-off-by: lipeng <lipeng321@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>
(cherry picked from commit 36eedfde1a3602e8054c16bc295c47764647a208)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns/hns_enet.h

index eb7f69564b063157350689b93feef1eb80d28605..a2eb0eb494d672aab63e3298ca34f72e8990c565 100644 (file)
@@ -860,7 +860,7 @@ out:
        return recv_pkts;
 }
 
-static void hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
 {
        struct hnae_ring *ring = ring_data->ring;
        int num = 0;
@@ -874,22 +874,23 @@ static void hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
                ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
                        ring_data->ring, 1);
 
-               napi_schedule(&ring_data->napi);
+               return false;
+       } else {
+               return true;
        }
 }
 
-static void hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
 {
        struct hnae_ring *ring = ring_data->ring;
-       int num = 0;
+       int num;
 
        num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
 
-       if (num == 0)
-               ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
-                       ring, 0);
+       if (!num)
+               return true;
        else
-               napi_schedule(&ring_data->napi);
+               return false;
 }
 
 static inline void hns_nic_reclaim_one_desc(struct hnae_ring *ring,
@@ -990,7 +991,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data,
        return 0;
 }
 
-static void hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
 {
        struct hnae_ring *ring = ring_data->ring;
        int head;
@@ -1003,20 +1004,21 @@ static void hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
                ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
                        ring_data->ring, 1);
 
-               napi_schedule(&ring_data->napi);
+               return false;
+       } else {
+               return true;
        }
 }
 
-static void hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
+static bool hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
 {
        struct hnae_ring *ring = ring_data->ring;
        int head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
 
        if (head == ring->next_to_clean)
-               ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
-                       ring, 0);
+               return true;
        else
-               napi_schedule(&ring_data->napi);
+               return false;
 }
 
 static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
@@ -1043,15 +1045,23 @@ static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
 
 static int hns_nic_common_poll(struct napi_struct *napi, int budget)
 {
+       int clean_complete = 0;
        struct hns_nic_ring_data *ring_data =
                container_of(napi, struct hns_nic_ring_data, napi);
-       int clean_complete = ring_data->poll_one(
-                               ring_data, budget, ring_data->ex_process);
+       struct hnae_ring *ring = ring_data->ring;
 
-       if (clean_complete >= 0 && clean_complete < budget) {
-               napi_complete(napi);
-               ring_data->fini_process(ring_data);
-               return 0;
+try_again:
+       clean_complete += ring_data->poll_one(
+                               ring_data, budget - clean_complete,
+                               ring_data->ex_process);
+
+       if (clean_complete < budget) {
+               if (ring_data->fini_process(ring_data)) {
+                       napi_complete(napi);
+                       ring->q->handle->dev->ops->toggle_ring_irq(ring, 0);
+               } else {
+                       goto try_again;
+               }
        }
 
        return clean_complete;
index fff8f8a21bd07686ad7ab6a421620e8b5e487af3..1b83232082b2a22244b77a05f4125a69cc4a5f32 100644 (file)
@@ -41,7 +41,7 @@ struct hns_nic_ring_data {
        int queue_index;
        int (*poll_one)(struct hns_nic_ring_data *, int, void *);
        void (*ex_process)(struct hns_nic_ring_data *, struct sk_buff *);
-       void (*fini_process)(struct hns_nic_ring_data *);
+       bool (*fini_process)(struct hns_nic_ring_data *);
 };
 
 /* compatible the difference between two versions */