From: lipeng <lipeng...@huawei.com> 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 <lipeng...@huawei.com> reviewed-by: Yisen Zhuang <yisen.zhu...@huawei.com> Signed-off-by: Salil Mehta <salil.me...@huawei.com> --- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 50 ++++++++++++++++----------- drivers/net/ethernet/hisilicon/hns/hns_enet.h | 2 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index 646f601..a083660 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -861,7 +861,7 @@ static int hns_nic_rx_poll_one(struct hns_nic_ring_data *ring_data, 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; @@ -875,22 +875,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, @@ -991,7 +992,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; @@ -1004,20 +1005,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) @@ -1044,15 +1046,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; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h index fff8f8a..1b83232 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h @@ -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 */ -- 2.7.4