Commit fd665b3d authored by Huazhong Tan's avatar Huazhong Tan Committed by David S. Miller

net: hns3: replace macro HNS3_MAX_NON_TSO_BD_NUM

Currently, the driver is able to query the device's specifications,
which includes the maximum BD number of non TSO packet, so replace
macro HNS3_MAX_NON_TSO_BD_NUM with the queried value, and rewrite
macro HNS3_MAX_NON_TSO_SIZE whose value depends on the the maximum
BD number of non TSO packet.

Also, add a new parameter max_non_tso_bd_num to function
hns3_tx_bd_num() and hns3_skb_need_linearized(), then they can get
the maximum BD number of non TSO packet from the caller instead of
calculating by themself, The note of hns3_skb_need_linearized()
should be update as well.
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c2f8ceda
...@@ -1184,21 +1184,23 @@ static unsigned int hns3_skb_bd_num(struct sk_buff *skb, unsigned int *bd_size, ...@@ -1184,21 +1184,23 @@ static unsigned int hns3_skb_bd_num(struct sk_buff *skb, unsigned int *bd_size,
return bd_num; return bd_num;
} }
static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size) static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size,
u8 max_non_tso_bd_num)
{ {
struct sk_buff *frag_skb; struct sk_buff *frag_skb;
unsigned int bd_num = 0; unsigned int bd_num = 0;
/* If the total len is within the max bd limit */ /* If the total len is within the max bd limit */
if (likely(skb->len <= HNS3_MAX_BD_SIZE && !skb_has_frag_list(skb) && if (likely(skb->len <= HNS3_MAX_BD_SIZE && !skb_has_frag_list(skb) &&
skb_shinfo(skb)->nr_frags < HNS3_MAX_NON_TSO_BD_NUM)) skb_shinfo(skb)->nr_frags < max_non_tso_bd_num))
return skb_shinfo(skb)->nr_frags + 1U; return skb_shinfo(skb)->nr_frags + 1U;
/* The below case will always be linearized, return /* The below case will always be linearized, return
* HNS3_MAX_BD_NUM_TSO + 1U to make sure it is linearized. * HNS3_MAX_BD_NUM_TSO + 1U to make sure it is linearized.
*/ */
if (unlikely(skb->len > HNS3_MAX_TSO_SIZE || if (unlikely(skb->len > HNS3_MAX_TSO_SIZE ||
(!skb_is_gso(skb) && skb->len > HNS3_MAX_NON_TSO_SIZE))) (!skb_is_gso(skb) && skb->len >
HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num))))
return HNS3_MAX_TSO_BD_NUM + 1U; return HNS3_MAX_TSO_BD_NUM + 1U;
bd_num = hns3_skb_bd_num(skb, bd_size, bd_num); bd_num = hns3_skb_bd_num(skb, bd_size, bd_num);
...@@ -1223,31 +1225,34 @@ static unsigned int hns3_gso_hdr_len(struct sk_buff *skb) ...@@ -1223,31 +1225,34 @@ static unsigned int hns3_gso_hdr_len(struct sk_buff *skb)
return skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb); return skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb);
} }
/* HW need every continuous 8 buffer data to be larger than MSS, /* HW need every continuous max_non_tso_bd_num buffer data to be larger
* we simplify it by ensuring skb_headlen + the first continuous * than MSS, we simplify it by ensuring skb_headlen + the first continuous
* 7 frags to to be larger than gso header len + mss, and the remaining * max_non_tso_bd_num - 1 frags to be larger than gso header len + mss,
* continuous 7 frags to be larger than MSS except the last 7 frags. * and the remaining continuous max_non_tso_bd_num - 1 frags to be larger
* than MSS except the last max_non_tso_bd_num - 1 frags.
*/ */
static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int *bd_size, static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int *bd_size,
unsigned int bd_num) unsigned int bd_num, u8 max_non_tso_bd_num)
{ {
unsigned int tot_len = 0; unsigned int tot_len = 0;
int i; int i;
for (i = 0; i < HNS3_MAX_NON_TSO_BD_NUM - 1U; i++) for (i = 0; i < max_non_tso_bd_num - 1U; i++)
tot_len += bd_size[i]; tot_len += bd_size[i];
/* ensure the first 8 frags is greater than mss + header */ /* ensure the first max_non_tso_bd_num frags is greater than
if (tot_len + bd_size[HNS3_MAX_NON_TSO_BD_NUM - 1U] < * mss + header
*/
if (tot_len + bd_size[max_non_tso_bd_num - 1U] <
skb_shinfo(skb)->gso_size + hns3_gso_hdr_len(skb)) skb_shinfo(skb)->gso_size + hns3_gso_hdr_len(skb))
return true; return true;
/* ensure every continuous 7 buffer is greater than mss /* ensure every continuous max_non_tso_bd_num - 1 buffer is greater
* except the last one. * than mss except the last one.
*/ */
for (i = 0; i < bd_num - HNS3_MAX_NON_TSO_BD_NUM; i++) { for (i = 0; i < bd_num - max_non_tso_bd_num; i++) {
tot_len -= bd_size[i]; tot_len -= bd_size[i];
tot_len += bd_size[i + HNS3_MAX_NON_TSO_BD_NUM - 1U]; tot_len += bd_size[i + max_non_tso_bd_num - 1U];
if (tot_len < skb_shinfo(skb)->gso_size) if (tot_len < skb_shinfo(skb)->gso_size)
return true; return true;
...@@ -1269,13 +1274,15 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring, ...@@ -1269,13 +1274,15 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct hns3_nic_priv *priv = netdev_priv(netdev); struct hns3_nic_priv *priv = netdev_priv(netdev);
u8 max_non_tso_bd_num = priv->max_non_tso_bd_num;
unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U]; unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U];
unsigned int bd_num; unsigned int bd_num;
bd_num = hns3_tx_bd_num(skb, bd_size); bd_num = hns3_tx_bd_num(skb, bd_size, max_non_tso_bd_num);
if (unlikely(bd_num > HNS3_MAX_NON_TSO_BD_NUM)) { if (unlikely(bd_num > max_non_tso_bd_num)) {
if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) && if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) &&
!hns3_skb_need_linearized(skb, bd_size, bd_num)) { !hns3_skb_need_linearized(skb, bd_size, bd_num,
max_non_tso_bd_num)) {
trace_hns3_over_8bd(skb); trace_hns3_over_8bd(skb);
goto out; goto out;
} }
...@@ -1286,7 +1293,7 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring, ...@@ -1286,7 +1293,7 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
bd_num = hns3_tx_bd_count(skb->len); bd_num = hns3_tx_bd_count(skb->len);
if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) || if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
(!skb_is_gso(skb) && (!skb_is_gso(skb) &&
bd_num > HNS3_MAX_NON_TSO_BD_NUM)) { bd_num > max_non_tso_bd_num)) {
trace_hns3_over_8bd(skb); trace_hns3_over_8bd(skb);
return -ENOMEM; return -ENOMEM;
} }
...@@ -3991,6 +3998,7 @@ static void hns3_info_show(struct hns3_nic_priv *priv) ...@@ -3991,6 +3998,7 @@ static void hns3_info_show(struct hns3_nic_priv *priv)
static int hns3_client_init(struct hnae3_handle *handle) static int hns3_client_init(struct hnae3_handle *handle)
{ {
struct pci_dev *pdev = handle->pdev; struct pci_dev *pdev = handle->pdev;
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
u16 alloc_tqps, max_rss_size; u16 alloc_tqps, max_rss_size;
struct hns3_nic_priv *priv; struct hns3_nic_priv *priv;
struct net_device *netdev; struct net_device *netdev;
...@@ -4007,6 +4015,7 @@ static int hns3_client_init(struct hnae3_handle *handle) ...@@ -4007,6 +4015,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
priv->netdev = netdev; priv->netdev = netdev;
priv->ae_handle = handle; priv->ae_handle = handle;
priv->tx_timeout_count = 0; priv->tx_timeout_count = 0;
priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num;
set_bit(HNS3_NIC_STATE_DOWN, &priv->state); set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL); handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL);
......
...@@ -167,13 +167,12 @@ enum hns3_nic_state { ...@@ -167,13 +167,12 @@ 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_NON_TSO_BD_NUM 8U
#define HNS3_MAX_TSO_BD_NUM 63U #define HNS3_MAX_TSO_BD_NUM 63U
#define HNS3_MAX_TSO_SIZE \ #define HNS3_MAX_TSO_SIZE \
(HNS3_MAX_BD_SIZE * HNS3_MAX_TSO_BD_NUM) (HNS3_MAX_BD_SIZE * HNS3_MAX_TSO_BD_NUM)
#define HNS3_MAX_NON_TSO_SIZE \ #define HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num) \
(HNS3_MAX_BD_SIZE * HNS3_MAX_NON_TSO_BD_NUM) (HNS3_MAX_BD_SIZE * (max_non_tso_bd_num))
#define HNS3_VECTOR_GL0_OFFSET 0x100 #define HNS3_VECTOR_GL0_OFFSET 0x100
#define HNS3_VECTOR_GL1_OFFSET 0x200 #define HNS3_VECTOR_GL1_OFFSET 0x200
...@@ -475,6 +474,7 @@ struct hns3_nic_priv { ...@@ -475,6 +474,7 @@ struct hns3_nic_priv {
struct hns3_enet_ring *ring; struct hns3_enet_ring *ring;
struct hns3_enet_tqp_vector *tqp_vector; struct hns3_enet_tqp_vector *tqp_vector;
u16 vector_num; u16 vector_num;
u8 max_non_tso_bd_num;
u64 tx_timeout_count; u64 tx_timeout_count;
......
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