From: Salil Mehta <salil.mehta@huawei.com> To: davem@davemloft.net Cc: salil.mehta@huawei.com, yisen.zhuang@huawei.com, lipeng321@huawei.com, mehta.salil@opnsrc.net, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org, linuxarm@huawei.com Subject: [PATCH V2 net-next 4/5] net: hns3: Add skb chain when num of RX buf exceeds MAX_SKB_FRAGS Date: Thu, 15 Nov 2018 09:29:24 +0000 [thread overview] Message-ID: <20181115092925.11812-5-salil.mehta@huawei.com> (raw) In-Reply-To: <20181115092925.11812-1-salil.mehta@huawei.com> From: Peng Li <lipeng321@huawei.com> MAX_SKB_FRAGS in protocol stack is defined as: MAX_SKB_FRAGS is 17 when PAGE_SIZE is 4K. If HW enable GRO, it may merge small packets and the rx buffer may be more than MAX_SKB_FRAGS. So driver will add skb chain when RX buffer num. more than MAX_SKB_FRAGS. Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> --- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 37 ++++++++++++++++++- .../net/ethernet/hisilicon/hns3/hns3_enet.h | 2 + 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 860067898471..7776089b6bc2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -2361,6 +2361,9 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb, static void hns3_rx_skb(struct hns3_enet_ring *ring, struct sk_buff *skb) { + if (skb_has_frag_list(skb)) + napi_gro_flush(&ring->tqp_vector->napi, false); + napi_gro_receive(&ring->tqp_vector->napi, skb); } @@ -2417,6 +2420,8 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, int length, prefetchw(skb->data); ring->pending_buf = 1; + ring->frag_num = 0; + ring->tail_skb = NULL; if (length <= HNS3_RX_HEAD_SIZE) { memcpy(__skb_put(skb, length), va, ALIGN(length, sizeof(long))); @@ -2435,7 +2440,7 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, int length, ring->pull_len = eth_get_headlen(va, HNS3_RX_HEAD_SIZE); __skb_put(skb, ring->pull_len); - hns3_nic_reuse_page(skb, 0, ring, ring->pull_len, + hns3_nic_reuse_page(skb, ring->frag_num++, ring, ring->pull_len, desc_cb); ring_ptr_move_fw(ring, next_to_clean); @@ -2446,6 +2451,8 @@ static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc, struct sk_buff **out_skb, bool pending) { struct sk_buff *skb = *out_skb; + struct sk_buff *head_skb = *out_skb; + struct sk_buff *new_skb; struct hns3_desc_cb *desc_cb; struct hns3_desc *pre_desc; u32 bd_base_info; @@ -2470,7 +2477,33 @@ static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc, if (!hnae3_get_bit(bd_base_info, HNS3_RXD_VLD_B)) return -ENXIO; - hns3_nic_reuse_page(skb, ring->pending_buf, ring, 0, desc_cb); + if (unlikely(ring->frag_num >= MAX_SKB_FRAGS)) { + new_skb = napi_alloc_skb(&ring->tqp_vector->napi, + HNS3_RX_HEAD_SIZE); + if (unlikely(!new_skb)) { + netdev_err(ring->tqp->handle->kinfo.netdev, + "alloc rx skb frag fail\n"); + return -ENXIO; + } + ring->frag_num = 0; + + if (ring->tail_skb) { + ring->tail_skb->next = new_skb; + ring->tail_skb = new_skb; + } else { + skb_shinfo(skb)->frag_list = new_skb; + ring->tail_skb = new_skb; + } + } + + if (ring->tail_skb) { + head_skb->truesize += hnae3_buf_size(ring); + head_skb->data_len += le16_to_cpu(desc->rx.size); + head_skb->len += le16_to_cpu(desc->rx.size); + skb = ring->tail_skb; + } + + hns3_nic_reuse_page(skb, ring->frag_num++, ring, 0, desc_cb); ring_ptr_move_fw(ring, next_to_clean); ring->pending_buf++; } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index d8c0998127be..8e56b7e44978 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -402,6 +402,7 @@ struct hns3_enet_ring { int next_to_clean; int pull_len; /* head length for current packet */ + u32 frag_num; unsigned char *va; /* first buffer address for current packet */ u32 flag; /* ring attribute */ @@ -412,6 +413,7 @@ struct hns3_enet_ring { int pending_buf; struct sk_buff *skb; + struct sk_buff *tail_skb; }; struct hns_queue; -- 2.17.1
WARNING: multiple messages have this Message-ID (diff)
From: Salil Mehta <salil.mehta@huawei.com> To: <davem@davemloft.net> Cc: <salil.mehta@huawei.com>, <yisen.zhuang@huawei.com>, <lipeng321@huawei.com>, <mehta.salil@opnsrc.net>, <netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <linux-rdma@vger.kernel.org>, <linuxarm@huawei.com> Subject: [PATCH V2 net-next 4/5] net: hns3: Add skb chain when num of RX buf exceeds MAX_SKB_FRAGS Date: Thu, 15 Nov 2018 09:29:24 +0000 [thread overview] Message-ID: <20181115092925.11812-5-salil.mehta@huawei.com> (raw) In-Reply-To: <20181115092925.11812-1-salil.mehta@huawei.com> From: Peng Li <lipeng321@huawei.com> MAX_SKB_FRAGS in protocol stack is defined as: MAX_SKB_FRAGS is 17 when PAGE_SIZE is 4K. If HW enable GRO, it may merge small packets and the rx buffer may be more than MAX_SKB_FRAGS. So driver will add skb chain when RX buffer num. more than MAX_SKB_FRAGS. Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> --- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 37 ++++++++++++++++++- .../net/ethernet/hisilicon/hns3/hns3_enet.h | 2 + 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 860067898471..7776089b6bc2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -2361,6 +2361,9 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb, static void hns3_rx_skb(struct hns3_enet_ring *ring, struct sk_buff *skb) { + if (skb_has_frag_list(skb)) + napi_gro_flush(&ring->tqp_vector->napi, false); + napi_gro_receive(&ring->tqp_vector->napi, skb); } @@ -2417,6 +2420,8 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, int length, prefetchw(skb->data); ring->pending_buf = 1; + ring->frag_num = 0; + ring->tail_skb = NULL; if (length <= HNS3_RX_HEAD_SIZE) { memcpy(__skb_put(skb, length), va, ALIGN(length, sizeof(long))); @@ -2435,7 +2440,7 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, int length, ring->pull_len = eth_get_headlen(va, HNS3_RX_HEAD_SIZE); __skb_put(skb, ring->pull_len); - hns3_nic_reuse_page(skb, 0, ring, ring->pull_len, + hns3_nic_reuse_page(skb, ring->frag_num++, ring, ring->pull_len, desc_cb); ring_ptr_move_fw(ring, next_to_clean); @@ -2446,6 +2451,8 @@ static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc, struct sk_buff **out_skb, bool pending) { struct sk_buff *skb = *out_skb; + struct sk_buff *head_skb = *out_skb; + struct sk_buff *new_skb; struct hns3_desc_cb *desc_cb; struct hns3_desc *pre_desc; u32 bd_base_info; @@ -2470,7 +2477,33 @@ static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc, if (!hnae3_get_bit(bd_base_info, HNS3_RXD_VLD_B)) return -ENXIO; - hns3_nic_reuse_page(skb, ring->pending_buf, ring, 0, desc_cb); + if (unlikely(ring->frag_num >= MAX_SKB_FRAGS)) { + new_skb = napi_alloc_skb(&ring->tqp_vector->napi, + HNS3_RX_HEAD_SIZE); + if (unlikely(!new_skb)) { + netdev_err(ring->tqp->handle->kinfo.netdev, + "alloc rx skb frag fail\n"); + return -ENXIO; + } + ring->frag_num = 0; + + if (ring->tail_skb) { + ring->tail_skb->next = new_skb; + ring->tail_skb = new_skb; + } else { + skb_shinfo(skb)->frag_list = new_skb; + ring->tail_skb = new_skb; + } + } + + if (ring->tail_skb) { + head_skb->truesize += hnae3_buf_size(ring); + head_skb->data_len += le16_to_cpu(desc->rx.size); + head_skb->len += le16_to_cpu(desc->rx.size); + skb = ring->tail_skb; + } + + hns3_nic_reuse_page(skb, ring->frag_num++, ring, 0, desc_cb); ring_ptr_move_fw(ring, next_to_clean); ring->pending_buf++; } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index d8c0998127be..8e56b7e44978 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -402,6 +402,7 @@ struct hns3_enet_ring { int next_to_clean; int pull_len; /* head length for current packet */ + u32 frag_num; unsigned char *va; /* first buffer address for current packet */ u32 flag; /* ring attribute */ @@ -412,6 +413,7 @@ struct hns3_enet_ring { int pending_buf; struct sk_buff *skb; + struct sk_buff *tail_skb; }; struct hns_queue; -- 2.17.1
next prev parent reply other threads:[~2018-11-15 9:29 UTC|newest] Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-11-15 9:29 [PATCH V2 net-next 0/5] net: hns3: Add support of hardware GRO to HNS3 Driver Salil Mehta 2018-11-15 9:29 ` Salil Mehta 2018-11-15 9:29 ` [PATCH V2 net-next 1/5] net: hns3: Enable HW GRO for Rev B(=0x21) HNS3 hardware Salil Mehta 2018-11-15 9:29 ` Salil Mehta 2018-11-15 9:29 ` [PATCH V2 net-next 2/5] net: hns3: Add handling of GRO Pkts not fully RX'ed in NAPI poll Salil Mehta 2018-11-15 9:29 ` Salil Mehta 2018-11-15 9:29 ` [PATCH V2 net-next 3/5] net: hns3: Add support for ethtool -K to enable/disable HW GRO Salil Mehta 2018-11-15 9:29 ` Salil Mehta 2018-11-15 9:29 ` Salil Mehta [this message] 2018-11-15 9:29 ` [PATCH V2 net-next 4/5] net: hns3: Add skb chain when num of RX buf exceeds MAX_SKB_FRAGS Salil Mehta 2018-11-15 9:29 ` [PATCH V2 net-next 5/5] net: hns3: Adds GRO params to SKB for the stack Salil Mehta 2018-11-15 9:29 ` Salil Mehta 2018-11-15 17:46 ` [PATCH V2 net-next 0/5] net: hns3: Add support of hardware GRO to HNS3 Driver David Miller
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20181115092925.11812-5-salil.mehta@huawei.com \ --to=salil.mehta@huawei.com \ --cc=davem@davemloft.net \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-rdma@vger.kernel.org \ --cc=linuxarm@huawei.com \ --cc=lipeng321@huawei.com \ --cc=mehta.salil@opnsrc.net \ --cc=netdev@vger.kernel.org \ --cc=yisen.zhuang@huawei.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.