From: "hailong.fan" Under certain conditions, a WARN_ON will be triggered if avail equals 1. For example, when a VLAN packet is to send, stmmac_vlan_insert consumes one unit of space, and the data itself consumes another. actually requiring 2 units of space in total. --- V0-V1: 1. Stop their queues earlier V2-V1: 1. add fixes tag 2. Add stmmac_extra_space to count the additional required space Fixes: 30d932279dc2 ("net: stmmac: Add support for VLAN Insertion Offload") Signed-off-by: hailong.fan --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 7b90ecd3a..9a665a3b2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -4476,6 +4476,15 @@ static bool stmmac_has_ip_ethertype(struct sk_buff *skb) (proto == htons(ETH_P_IP) || proto == htons(ETH_P_IPV6)); } +static inline int stmmac_extra_space(struct stmmac_priv *priv, + struct sk_buff *skb) +{ + if (!priv->dma_cap.vlins || !skb_vlan_tag_present(skb)) + return 0; + + return 1; +} + /** * stmmac_xmit - Tx entry point of the driver * @skb : the socket buffer @@ -4529,7 +4538,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) } } - if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) { + if (unlikely(stmmac_tx_avail(priv, queue) < + nfrags + 1 + stmmac_extra_space(priv, skb))) { if (!netif_tx_queue_stopped(netdev_get_tx_queue(dev, queue))) { netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); @@ -4675,7 +4685,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) print_pkt(skb->data, skb->len); } - if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) { + if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 2))) { netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n", __func__); netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); -- 2.34.1