diff mbox series

[SRU,Disco] net: hns3: fix for not calculating tx bd num correctly

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

Commit Message

dann frazier April 10, 2019, 5:08 p.m. UTC
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(-)

Comments

You-Sheng Yang April 11, 2019, 4:14 a.m. UTC | #1
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
>  
>
Seth Forshee April 11, 2019, 2:17 p.m. UTC | #2
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>
Seth Forshee April 11, 2019, 2:45 p.m. UTC | #3
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 mbox series

Patch

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