Commit 5f543a54 authored by Yunsheng Lin's avatar Yunsheng Lin Committed by David S. Miller

net: hns3: fix for not calculating tx bd num correctly

When there is only one byte in a frag, the current calculation
using "(size + HNS3_MAX_BD_SIZE - 1) >> HNS3_MAX_BD_SIZE_OFFSET"
will return zero, because HNS3_MAX_BD_SIZE is 65535 and
HNS3_MAX_BD_SIZE_OFFSET is 16. So it will cause tx error when
a frag's size is one byte.

This patch fixes it by using DIV_ROUND_UP.

Fixes: 3fe13ed9 ("net: hns3: avoid mult + div op in critical data path")
Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 408f13ef
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "hns3_enet.h" #include "hns3_enet.h"
#define hns3_set_field(origin, shift, val) ((origin) |= ((val) << (shift))) #define hns3_set_field(origin, shift, val) ((origin) |= ((val) << (shift)))
#define hns3_tx_bd_count(S) DIV_ROUND_UP(S, HNS3_MAX_BD_SIZE)
static void hns3_clear_all_ring(struct hnae3_handle *h); static void hns3_clear_all_ring(struct hnae3_handle *h);
static void hns3_force_clear_all_rx_ring(struct hnae3_handle *h); static void hns3_force_clear_all_rx_ring(struct hnae3_handle *h);
...@@ -1079,7 +1080,7 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, ...@@ -1079,7 +1080,7 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
desc_cb->length = size; desc_cb->length = size;
frag_buf_num = (size + HNS3_MAX_BD_SIZE - 1) >> HNS3_MAX_BD_SIZE_OFFSET; frag_buf_num = hns3_tx_bd_count(size);
sizeoflast = size & HNS3_TX_LAST_SIZE_M; sizeoflast = size & HNS3_TX_LAST_SIZE_M;
sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE; sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE;
...@@ -1124,14 +1125,13 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum, ...@@ -1124,14 +1125,13 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
int i; int i;
size = skb_headlen(skb); size = skb_headlen(skb);
buf_num = (size + HNS3_MAX_BD_SIZE - 1) >> HNS3_MAX_BD_SIZE_OFFSET; buf_num = hns3_tx_bd_count(size);
frag_num = skb_shinfo(skb)->nr_frags; frag_num = skb_shinfo(skb)->nr_frags;
for (i = 0; i < frag_num; i++) { for (i = 0; i < frag_num; i++) {
frag = &skb_shinfo(skb)->frags[i]; frag = &skb_shinfo(skb)->frags[i];
size = skb_frag_size(frag); size = skb_frag_size(frag);
bdnum_for_frag = (size + HNS3_MAX_BD_SIZE - 1) >> bdnum_for_frag = hns3_tx_bd_count(size);
HNS3_MAX_BD_SIZE_OFFSET;
if (unlikely(bdnum_for_frag > HNS3_MAX_BD_PER_FRAG)) if (unlikely(bdnum_for_frag > HNS3_MAX_BD_PER_FRAG))
return -ENOMEM; return -ENOMEM;
...@@ -1139,8 +1139,7 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum, ...@@ -1139,8 +1139,7 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
} }
if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) { if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) >> buf_num = hns3_tx_bd_count(skb->len);
HNS3_MAX_BD_SIZE_OFFSET;
if (ring_space(ring) < buf_num) if (ring_space(ring) < buf_num)
return -EBUSY; return -EBUSY;
/* manual split the send packet */ /* manual split the send packet */
...@@ -1169,7 +1168,7 @@ static int hns3_nic_maybe_stop_tx(struct sk_buff **out_skb, int *bnum, ...@@ -1169,7 +1168,7 @@ static int hns3_nic_maybe_stop_tx(struct sk_buff **out_skb, int *bnum,
buf_num = skb_shinfo(skb)->nr_frags + 1; buf_num = skb_shinfo(skb)->nr_frags + 1;
if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) { if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE; buf_num = hns3_tx_bd_count(skb->len);
if (ring_space(ring) < buf_num) if (ring_space(ring) < buf_num)
return -EBUSY; return -EBUSY;
/* manual split the send packet */ /* manual split the send packet */
......
...@@ -193,7 +193,6 @@ enum hns3_nic_state { ...@@ -193,7 +193,6 @@ enum hns3_nic_state {
#define HNS3_VECTOR_INITED 1 #define HNS3_VECTOR_INITED 1
#define HNS3_MAX_BD_SIZE 65535 #define HNS3_MAX_BD_SIZE 65535
#define HNS3_MAX_BD_SIZE_OFFSET 16
#define HNS3_MAX_BD_PER_FRAG 8 #define HNS3_MAX_BD_PER_FRAG 8
#define HNS3_MAX_BD_PER_PKT MAX_SKB_FRAGS #define HNS3_MAX_BD_PER_PKT MAX_SKB_FRAGS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment