From: Yunsheng Lin linyunsheng@huawei.com
mainline inclusion from mainline-v5.13-rc1 commit 811c0830eb4ca8811ed80fe40378f622b9844835 category: feature bugzilla: NA CVE: NA
----------------------------
The actual size on wire for tso skb should be (gso_segs - 1) * hdr + skb->len instead of skb->len, which can be seen by user using 'ethtool -S ethX' cmd, and 'Byte Queue Limit' also use the send size stat to do the queue limiting, so add send_bytes in the desc_cb to record the actual send size for a skb. And send_bytes is only for tx desc_cb and page_offset is only for rx desc, so reuse the same space for both of them.
Signed-off-by: Yunsheng Lin linyunsheng@huawei.com Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Yonglong Liu liuyonglong@huawei.com Reviewed-by: li yongxin liyongxin1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 27 +++++++++++++------ .../net/ethernet/hisilicon/hns3/hns3_enet.h | 7 ++++- 2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index f85e2a1870e5f..0b7a1573705c8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -642,7 +642,7 @@ void hns3_enable_vlan_filter(struct net_device *netdev, bool enable) }
static int hns3_set_tso(struct sk_buff *skb, u32 *paylen, - u16 *mss, u32 *type_cs_vlan_tso) + u16 *mss, u32 *type_cs_vlan_tso, u32 *send_bytes) { u32 l4_offset, hdr_len; union l3_hdr_info l3; @@ -705,6 +705,8 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen, csum_replace_by_diff(&l4.tcp->check, (__force __wsum)htonl(l4_paylen));
+ *send_bytes = (skb_shinfo(skb)->gso_segs - 1) * hdr_len + skb->len; + /* find the txbd field values */ *paylen = skb->len - hdr_len; hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_TSO_B, 1); @@ -994,7 +996,8 @@ static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring, }
static int hns3_fill_skb_desc(struct hns3_enet_ring *ring, - struct sk_buff *skb, struct hns3_desc *desc) + struct sk_buff *skb, struct hns3_desc *desc, + struct hns3_desc_cb *desc_cb) { u32 ol_type_vlan_len_msec = 0; u32 type_cs_vlan_tso = 0; @@ -1023,6 +1026,8 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring, 1); }
+ desc_cb->send_bytes = skb->len; + if (skb->ip_summed == CHECKSUM_PARTIAL) { u8 ol4_proto, il4_proto;
@@ -1047,7 +1052,7 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring, }
ret = hns3_set_tso(skb, &paylen, &mss, - &type_cs_vlan_tso); + &type_cs_vlan_tso, &desc_cb->send_bytes); if (unlikely(ret < 0)) { u64_stats_update_begin(&ring->syncp); ring->stats.tx_tso_err++; @@ -1452,6 +1457,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) { struct hns3_nic_priv *priv = netdev_priv(netdev); struct hns3_enet_ring *ring = &priv->ring[skb->queue_mapping]; + struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; struct netdev_queue *dev_queue; int pre_ntu, next_to_use_head; int ret; @@ -1478,7 +1484,8 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
next_to_use_head = ring->next_to_use;
- ret = hns3_fill_skb_desc(ring, skb, &ring->desc[ring->next_to_use]); + ret = hns3_fill_skb_desc(ring, skb, &ring->desc[ring->next_to_use], + desc_cb); if (unlikely(ret < 0)) goto fill_err;
@@ -1498,10 +1505,10 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) /* Complete translate all packets */ dev_queue = netdev_get_tx_queue(netdev, ring->queue_index); if (!netdev_xmit_more()) { - netdev_tx_sent_queue(dev_queue, skb->len); + netdev_tx_sent_queue(dev_queue, desc_cb->send_bytes); hns3_tx_doorbell(ring, ret, true); } else { - dql_queued(&dev_queue->dql, skb->len); + dql_queued(&dev_queue->dql, desc_cb->send_bytes); hns3_tx_doorbell(ring, ret, netif_tx_queue_stopped(dev_queue)); }
@@ -2637,8 +2644,12 @@ static bool hns3_nic_reclaim_desc(struct hns3_enet_ring *ring, break;
desc_cb = &ring->desc_cb[ntc]; - (*pkts) += (desc_cb->type == DESC_TYPE_SKB); - (*bytes) += desc_cb->length; + + if (desc_cb->type == DESC_TYPE_SKB) { + (*pkts)++; + (*bytes) += desc_cb->send_bytes; + } + /* desc_cb will be cleaned, after hnae3_free_buffer_detach */ hns3_free_buffer_detach(ring, ntc, budget);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index 5398adfeff1f3..ab5270e084a1b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -306,7 +306,12 @@ struct hns3_desc_cb {
/* priv data for the desc, e.g. skb when use with ip stack */ void *priv; - u32 page_offset; + + union { + u32 page_offset; /* for rx */ + u32 send_bytes; /* for tx */ + }; + u32 length; /* length of the buffer */
u16 reuse_flag;