Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Octeontx2-vf: Fix max packet length errors

Once driver submits the packets to the hardware, each packet
traverse through multiple transmit levels in the following
order:
SMQ -> TL4 -> TL3 -> TL2 -> TL1

The SMQ supports configurable minimum and maximum packet sizes.
It enters to a hang state, if driver submits packets with
out of bound lengths.

To avoid the same, implement packet length validation before
submitting packets to the hardware. Increment tx_dropped counter
on failure.

Fixes: 3184fb5ba96e ("octeontx2-vf: Virtual function driver support")
Fixes: 22f858796758 ("octeontx2-pf: Add basic net_device_ops")
Fixes: 3ca6c4c882a7 ("octeontx2-pf: Add packet transmission support")
Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
Link: https://patch.msgid.link/20250821062528.1697992-1-hkelam@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Hariprasad Kelam and committed by
Jakub Kicinski
a64494aa abadf0ff

+30 -2
+3 -1
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
··· 124 124 dev_stats->rx_ucast_frames; 125 125 126 126 dev_stats->tx_bytes = OTX2_GET_TX_STATS(TX_OCTS); 127 - dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP); 127 + dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP) + 128 + (unsigned long)atomic_long_read(&dev_stats->tx_discards); 129 + 128 130 dev_stats->tx_bcast_frames = OTX2_GET_TX_STATS(TX_BCAST); 129 131 dev_stats->tx_mcast_frames = OTX2_GET_TX_STATS(TX_MCAST); 130 132 dev_stats->tx_ucast_frames = OTX2_GET_TX_STATS(TX_UCAST);
+1
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
··· 153 153 u64 tx_bcast_frames; 154 154 u64 tx_mcast_frames; 155 155 u64 tx_drops; 156 + atomic_long_t tx_discards; 156 157 }; 157 158 158 159 /* Driver counted stats */
+3
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
··· 2220 2220 { 2221 2221 struct otx2_nic *pf = netdev_priv(netdev); 2222 2222 int qidx = skb_get_queue_mapping(skb); 2223 + struct otx2_dev_stats *dev_stats; 2223 2224 struct otx2_snd_queue *sq; 2224 2225 struct netdev_queue *txq; 2225 2226 int sq_idx; ··· 2233 2232 /* Check for minimum and maximum packet length */ 2234 2233 if (skb->len <= ETH_HLEN || 2235 2234 (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) { 2235 + dev_stats = &pf->hw.dev_stats; 2236 + atomic_long_inc(&dev_stats->tx_discards); 2236 2237 dev_kfree_skb(skb); 2237 2238 return NETDEV_TX_OK; 2238 2239 }
+10
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
··· 417 417 { 418 418 struct otx2_nic *vf = netdev_priv(netdev); 419 419 int qidx = skb_get_queue_mapping(skb); 420 + struct otx2_dev_stats *dev_stats; 420 421 struct otx2_snd_queue *sq; 421 422 struct netdev_queue *txq; 423 + 424 + /* Check for minimum and maximum packet length */ 425 + if (skb->len <= ETH_HLEN || 426 + (!skb_shinfo(skb)->gso_size && skb->len > vf->tx_max_pktlen)) { 427 + dev_stats = &vf->hw.dev_stats; 428 + atomic_long_inc(&dev_stats->tx_discards); 429 + dev_kfree_skb(skb); 430 + return NETDEV_TX_OK; 431 + } 422 432 423 433 sq = &vf->qset.sq[qidx]; 424 434 txq = netdev_get_tx_queue(netdev, qidx);
+12 -1
drivers/net/ethernet/marvell/octeontx2/nic/rep.c
··· 371 371 stats->rx_mcast_frames = rsp->rx.mcast; 372 372 stats->tx_bytes = rsp->tx.octs; 373 373 stats->tx_frames = rsp->tx.ucast + rsp->tx.bcast + rsp->tx.mcast; 374 - stats->tx_drops = rsp->tx.drop; 374 + stats->tx_drops = rsp->tx.drop + 375 + (unsigned long)atomic_long_read(&stats->tx_discards); 375 376 exit: 376 377 mutex_unlock(&priv->mbox.lock); 377 378 } ··· 419 418 struct otx2_nic *pf = rep->mdev; 420 419 struct otx2_snd_queue *sq; 421 420 struct netdev_queue *txq; 421 + struct rep_stats *stats; 422 + 423 + /* Check for minimum and maximum packet length */ 424 + if (skb->len <= ETH_HLEN || 425 + (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) { 426 + stats = &rep->stats; 427 + atomic_long_inc(&stats->tx_discards); 428 + dev_kfree_skb(skb); 429 + return NETDEV_TX_OK; 430 + } 422 431 423 432 sq = &pf->qset.sq[rep->rep_id]; 424 433 txq = netdev_get_tx_queue(dev, 0);
+1
drivers/net/ethernet/marvell/octeontx2/nic/rep.h
··· 27 27 u64 tx_bytes; 28 28 u64 tx_frames; 29 29 u64 tx_drops; 30 + atomic_long_t tx_discards; 30 31 }; 31 32 32 33 struct rep_dev {