From 907676b130711fd1f627824559e92259db2061d1 Mon Sep 17 00:00:00 2001 From: Yunsheng Lin Date: Wed, 16 Jun 2021 14:36:13 +0800 Subject: 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 Signed-off-by: Yunsheng Lin Signed-off-by: Guangbin Huang Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 43 +++++++++++++++++++------ 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3_enet.h') 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 { -- cgit