diff options
author | Yunsheng Lin <linyunsheng@huawei.com> | 2021-06-16 09:36:13 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-06-16 10:36:06 +0300 |
commit | 907676b130711fd1f627824559e92259db2061d1 (patch) | |
tree | b5a7a41d1f7c3194ea21d216aa2b716d53078ef5 /drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | |
parent | 8677d78c3d860c156ccd335e2b97728298c2cbb1 (diff) | |
download | linux-907676b130711fd1f627824559e92259db2061d1.tar.xz |
net: hns3: use tx bounce buffer for small packets
when the packet or frag size is small, it causes both security and
performance issue. As dma can't map sub-page, this means some extra
kernel data is visible to devices. On the other hand, the overhead
of dma map and unmap is huge when IOMMU is on.
So add a queue based tx shared bounce buffer to memcpy the small
packet when the len of the xmitted skb is below tx_copybreak.
Add tx_spare_buf_size module param to set the size of tx spare
buffer, and add set/get_tunable to set or query the tx_copybreak.
The throughtput improves from 30 Gbps to 90+ Gbps when running 16
netperf threads with 32KB UDP message size when IOMMU is in the
strict mode(tx_copybreak = 2000 and mtu = 1500).
Suggested-by: Barry Song <song.bao.hua@hisilicon.com>
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_enet.h')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index 9d18b9430b54..8d147c1dab2c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -304,6 +304,8 @@ enum hns3_desc_type { DESC_TYPE_SKB = 1 << 0, DESC_TYPE_FRAGLIST_SKB = 1 << 1, DESC_TYPE_PAGE = 1 << 2, + DESC_TYPE_BOUNCE_ALL = 1 << 3, + DESC_TYPE_BOUNCE_HEAD = 1 << 4, }; struct hns3_desc_cb { @@ -405,6 +407,9 @@ struct ring_stats { u64 tx_tso_err; u64 over_max_recursion; u64 hw_limitation; + u64 tx_bounce; + u64 tx_spare_full; + u64 copy_bits_err; }; struct { u64 rx_pkts; @@ -423,6 +428,15 @@ struct ring_stats { }; }; +struct hns3_tx_spare { + dma_addr_t dma; + void *buf; + u32 next_to_use; + u32 next_to_clean; + u32 last_to_clean; + u32 len; +}; + struct hns3_enet_ring { struct hns3_desc *desc; /* dma map address space */ struct hns3_desc_cb *desc_cb; @@ -445,18 +459,28 @@ struct hns3_enet_ring { * next_to_use */ int next_to_clean; - union { - int last_to_use; /* last idx used by xmit */ - u32 pull_len; /* memcpy len for current rx packet */ - }; - u32 frag_num; - void *va; /* first buffer address for current packet */ - u32 flag; /* ring attribute */ int pending_buf; - struct sk_buff *skb; - struct sk_buff *tail_skb; + union { + /* for Tx ring */ + struct { + u32 fd_qb_tx_sample; + int last_to_use; /* last idx used by xmit */ + u32 tx_copybreak; + struct hns3_tx_spare *tx_spare; + }; + + /* for Rx ring */ + struct { + u32 pull_len; /* memcpy len for current rx packet */ + u32 frag_num; + /* first buffer address for current packet */ + unsigned char *va; + struct sk_buff *skb; + struct sk_buff *tail_skb; + }; + }; } ____cacheline_internodealigned_in_smp; enum hns3_flow_level_range { @@ -540,6 +564,7 @@ struct hns3_nic_priv { struct hns3_enet_coalesce tx_coal; struct hns3_enet_coalesce rx_coal; + u32 tx_copybreak; }; union l3_hdr_info { |