summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
diff options
context:
space:
mode:
authorYunsheng Lin <linyunsheng@huawei.com>2021-06-16 14:36:17 +0800
committerDavid S. Miller <davem@davemloft.net>2021-06-16 00:36:06 -0700
commit99f6b5fb5f63cf69c6e56bba8e5492c98c521a63 (patch)
tree372df4e19c059d3f1fcec95a4094b5daf3af85fb /drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
parentfa7711b888f24ee9291d90f8fbdaccfc80ed72c7 (diff)
net: hns3: use bounce buffer when rx page can not be reused
Currently rx page will be reused to receive future packet when the stack releases the previous skb quickly. If the old page can not be reused, a new page will be allocated and mapped, which comsumes a lot of cpu when IOMMU is in the strict mode, especially when the application and irq/NAPI happens to run on the same cpu. So allocate a new frag to memcpy the data to avoid the costly IOMMU unmapping/mapping operation, and add "frag_alloc_err" and "frag_alloc" stats in "ethtool -S ethX" cmd. The throughput improves above 50% when running single thread of iperf using TCP when IOMMU is in strict mode and iperf shares the same cpu with irq/NAPI(rx_copybreak = 2048 and mtu = 1500). Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c')
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index d7852716aaad..82061ab6930f 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -71,6 +71,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("csum_complete", csum_complete),
HNS3_TQP_STAT("multicast", rx_multicast),
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
+ HNS3_TQP_STAT("frag_alloc_err", frag_alloc_err),
+ HNS3_TQP_STAT("frag_alloc", frag_alloc),
};
#define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags)
@@ -1610,6 +1612,9 @@ static int hns3_get_tunable(struct net_device *netdev,
/* all the tx rings have the same tx_copybreak */
*(u32 *)data = priv->tx_copybreak;
break;
+ case ETHTOOL_RX_COPYBREAK:
+ *(u32 *)data = priv->rx_copybreak;
+ break;
default:
ret = -EOPNOTSUPP;
break;
@@ -1634,6 +1639,13 @@ static int hns3_set_tunable(struct net_device *netdev,
priv->ring[i].tx_copybreak = priv->tx_copybreak;
break;
+ case ETHTOOL_RX_COPYBREAK:
+ priv->rx_copybreak = *(u32 *)data;
+
+ for (i = h->kinfo.num_tqps; i < h->kinfo.num_tqps * 2; i++)
+ priv->ring[i].rx_copybreak = priv->rx_copybreak;
+
+ break;
default:
ret = -EOPNOTSUPP;
break;