Message ID | 20190410170807.26896-1-dann.frazier@canonical.com |
---|---|
State | New |
Headers | show |
Series | [SRU,Disco] net: hns3: fix for not calculating tx bd num correctly | expand |
Acked-By: You-Sheng Yang <vicamo.yang@canonical.com> On 2019/4/11 1:08 AM, dann frazier wrote: > From: Yunsheng Lin <linyunsheng@huawei.com> > > BugLink: https://bugs.launchpad.net/bugs/1824194 > > 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: 3fe13ed95dd3 ("net: hns3: avoid mult + div op in critical data path") > Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (cherry picked from commit 5f543a54eec08228ab0cc0a49cf5d79dd32c9e5e) > Signed-off-by: dann frazier <dann.frazier@canonical.com> > --- > drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 13 ++++++------- > drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 1 - > 2 files changed, 6 insertions(+), 8 deletions(-) > > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c > index 1c1f17ec6be2d..162cb9afa0e70 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c > @@ -22,6 +22,7 @@ > #include "hns3_enet.h" > > #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_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, > > 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 = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE; > > @@ -1124,14 +1125,13 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum, > int i; > > 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; > for (i = 0; i < frag_num; i++) { > frag = &skb_shinfo(skb)->frags[i]; > size = skb_frag_size(frag); > - bdnum_for_frag = (size + HNS3_MAX_BD_SIZE - 1) >> > - HNS3_MAX_BD_SIZE_OFFSET; > + bdnum_for_frag = hns3_tx_bd_count(size); > if (unlikely(bdnum_for_frag > HNS3_MAX_BD_PER_FRAG)) > return -ENOMEM; > > @@ -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)) { > - buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) >> > - HNS3_MAX_BD_SIZE_OFFSET; > + buf_num = hns3_tx_bd_count(skb->len); > if (ring_space(ring) < buf_num) > return -EBUSY; > /* manual split the send packet */ > @@ -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; > > 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) > return -EBUSY; > /* manual split the send packet */ > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h > index 1db0bd41d2096..75669cd0c3114 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h > @@ -193,7 +193,6 @@ enum hns3_nic_state { > #define HNS3_VECTOR_INITED 1 > > #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_PKT MAX_SKB_FRAGS > >
On Wed, Apr 10, 2019 at 11:08:07AM -0600, dann frazier wrote: > From: Yunsheng Lin <linyunsheng@huawei.com> > > BugLink: https://bugs.launchpad.net/bugs/1824194 > > 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: 3fe13ed95dd3 ("net: hns3: avoid mult + div op in critical data path") > Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (cherry picked from commit 5f543a54eec08228ab0cc0a49cf5d79dd32c9e5e) > Signed-off-by: dann frazier <dann.frazier@canonical.com> Upsteam cherry pick, limited impact, positive testing. Acked-by: Seth Forshee <seth.forshee@canonical.com>
On Wed, Apr 10, 2019 at 11:08:07AM -0600, dann frazier wrote: > From: Yunsheng Lin <linyunsheng@huawei.com> > > BugLink: https://bugs.launchpad.net/bugs/1824194 > > 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: 3fe13ed95dd3 ("net: hns3: avoid mult + div op in critical data path") > Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (cherry picked from commit 5f543a54eec08228ab0cc0a49cf5d79dd32c9e5e) > Signed-off-by: dann frazier <dann.frazier@canonical.com> Applied to disco/master-next, thanks!
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 1c1f17ec6be2d..162cb9afa0e70 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -22,6 +22,7 @@ #include "hns3_enet.h" #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_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, 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 = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE; @@ -1124,14 +1125,13 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum, int i; 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; for (i = 0; i < frag_num; i++) { frag = &skb_shinfo(skb)->frags[i]; size = skb_frag_size(frag); - bdnum_for_frag = (size + HNS3_MAX_BD_SIZE - 1) >> - HNS3_MAX_BD_SIZE_OFFSET; + bdnum_for_frag = hns3_tx_bd_count(size); if (unlikely(bdnum_for_frag > HNS3_MAX_BD_PER_FRAG)) return -ENOMEM; @@ -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)) { - buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) >> - HNS3_MAX_BD_SIZE_OFFSET; + buf_num = hns3_tx_bd_count(skb->len); if (ring_space(ring) < buf_num) return -EBUSY; /* manual split the send packet */ @@ -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; 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) return -EBUSY; /* manual split the send packet */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index 1db0bd41d2096..75669cd0c3114 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -193,7 +193,6 @@ enum hns3_nic_state { #define HNS3_VECTOR_INITED 1 #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_PKT MAX_SKB_FRAGS