| From foo@baz Wed 06 Nov 2019 04:08:37 PM CET |
| From: Jiangfeng Xiao <xiaojiangfeng@huawei.com> |
| Date: Mon, 28 Oct 2019 13:09:46 +0800 |
| Subject: net: hisilicon: Fix ping latency when deal with high throughput |
| |
| From: Jiangfeng Xiao <xiaojiangfeng@huawei.com> |
| |
| [ Upstream commit e56bd641ca61beb92b135298d5046905f920b734 ] |
| |
| This is due to error in over budget processing. |
| When dealing with high throughput, the used buffers |
| that exceeds the budget is not cleaned up. In addition, |
| it takes a lot of cycles to clean up the used buffer, |
| and then the buffer where the valid data is located can take effect. |
| |
| Signed-off-by: Jiangfeng Xiao <xiaojiangfeng@huawei.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/ethernet/hisilicon/hip04_eth.c | 15 +++++++++------ |
| 1 file changed, 9 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/net/ethernet/hisilicon/hip04_eth.c |
| +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c |
| @@ -174,6 +174,7 @@ struct hip04_priv { |
| dma_addr_t rx_phys[RX_DESC_NUM]; |
| unsigned int rx_head; |
| unsigned int rx_buf_size; |
| + unsigned int rx_cnt_remaining; |
| |
| struct device_node *phy_node; |
| struct phy_device *phy; |
| @@ -487,7 +488,6 @@ static int hip04_rx_poll(struct napi_str |
| struct hip04_priv *priv = container_of(napi, struct hip04_priv, napi); |
| struct net_device *ndev = priv->ndev; |
| struct net_device_stats *stats = &ndev->stats; |
| - unsigned int cnt = hip04_recv_cnt(priv); |
| struct rx_desc *desc; |
| struct sk_buff *skb; |
| unsigned char *buf; |
| @@ -500,8 +500,8 @@ static int hip04_rx_poll(struct napi_str |
| |
| /* clean up tx descriptors */ |
| tx_remaining = hip04_tx_reclaim(ndev, false); |
| - |
| - while (cnt && !last) { |
| + priv->rx_cnt_remaining += hip04_recv_cnt(priv); |
| + while (priv->rx_cnt_remaining && !last) { |
| buf = priv->rx_buf[priv->rx_head]; |
| skb = build_skb(buf, priv->rx_buf_size); |
| if (unlikely(!skb)) { |
| @@ -547,11 +547,13 @@ refill: |
| hip04_set_recv_desc(priv, phys); |
| |
| priv->rx_head = RX_NEXT(priv->rx_head); |
| - if (rx >= budget) |
| + if (rx >= budget) { |
| + --priv->rx_cnt_remaining; |
| goto done; |
| + } |
| |
| - if (--cnt == 0) |
| - cnt = hip04_recv_cnt(priv); |
| + if (--priv->rx_cnt_remaining == 0) |
| + priv->rx_cnt_remaining += hip04_recv_cnt(priv); |
| } |
| |
| if (!(priv->reg_inten & RCV_INT)) { |
| @@ -636,6 +638,7 @@ static int hip04_mac_open(struct net_dev |
| int i; |
| |
| priv->rx_head = 0; |
| + priv->rx_cnt_remaining = 0; |
| priv->tx_head = 0; |
| priv->tx_tail = 0; |
| hip04_reset_ppe(priv); |