lkml.org 
[lkml]   [2019]   [Jan]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH net-next 10/12] net: hns3: add 8 BD limit for tx flow
    Date
    From: Peng Li <lipeng321@huawei.com>

    A single transmit packet can span up to 8 descriptors according
    to the HW limit. If a skb has more than 8 frags, driver uses
    skb_copy to get a new skb which has less frags.

    Signed-off-by: Peng Li <lipeng321@huawei.com>
    Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
    ---
    .../net/ethernet/hisilicon/hns3/hns3_enet.c | 28 ++++++++++++++++++-
    1 file changed, 27 insertions(+), 1 deletion(-)

    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
    index 93e3e38ba852..216f3dd25cd6 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
    @@ -1133,6 +1133,7 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
    struct hns3_enet_ring *ring)
    {
    struct sk_buff *skb = *out_skb;
    + struct sk_buff *new_skb = NULL;
    struct skb_frag_struct *frag;
    int bdnum_for_frag;
    int frag_num;
    @@ -1155,7 +1156,19 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
    buf_num += bdnum_for_frag;
    }

    - if (buf_num > ring_space(ring))
    + if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
    + buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
    + if (ring_space(ring) < buf_num)
    + return -EBUSY;
    + /* manual split the send packet */
    + new_skb = skb_copy(skb, GFP_ATOMIC);
    + if (!new_skb)
    + return -ENOMEM;
    + dev_kfree_skb_any(skb);
    + *out_skb = new_skb;
    + }
    +
    + if (unlikely(ring_space(ring) < buf_num))
    return -EBUSY;

    *bnum = buf_num;
    @@ -1166,11 +1179,24 @@ static int hns3_nic_maybe_stop_tx(struct sk_buff **out_skb, int *bnum,
    struct hns3_enet_ring *ring)
    {
    struct sk_buff *skb = *out_skb;
    + struct sk_buff *new_skb = NULL;
    int buf_num;

    /* No. of segments (plus a header) */
    buf_num = skb_shinfo(skb)->nr_frags + 1;

    + if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
    + buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
    + if (ring_space(ring) < buf_num)
    + return -EBUSY;
    + /* manual split the send packet */
    + new_skb = skb_copy(skb, GFP_ATOMIC);
    + if (!new_skb)
    + return -ENOMEM;
    + dev_kfree_skb_any(skb);
    + *out_skb = new_skb;
    + }
    +
    if (unlikely(ring_space(ring) < buf_num))
    return -EBUSY;

    --
    2.20.1

    \
     
     \ /
      Last update: 2019-01-26 17:51    [W:2.743 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site