* [net PatchV4] Octeontx2-vf: Fix max packet length errors
@ 2025-07-24 7:06 Hariprasad Kelam
2025-07-25 21:39 ` Jakub Kicinski
0 siblings, 1 reply; 2+ messages in thread
From: Hariprasad Kelam @ 2025-07-24 7:06 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Hariprasad Kelam, Sunil Goutham, Geetha sowjanya,
Subbaraya Sundeep, Bharat Bhushan, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Tomasz Duszynski,
Simon Horman
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>
---
v4 * Update commit description with hardware limitation details.
v3 * Define driver specific counter for storing dropped packets.
v2 * Add the packet length check for rep dev
Increment tx_dropped counter on failure
.../net/ethernet/marvell/octeontx2/nic/otx2_common.c | 3 ++-
.../net/ethernet/marvell/octeontx2/nic/otx2_common.h | 1 +
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 3 +++
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c | 10 ++++++++++
drivers/net/ethernet/marvell/octeontx2/nic/rep.c | 12 +++++++++++-
drivers/net/ethernet/marvell/octeontx2/nic/rep.h | 1 +
6 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
index 6b5c9536d26d..e480c8692baa 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
@@ -124,7 +124,8 @@ void otx2_get_dev_stats(struct otx2_nic *pfvf)
dev_stats->rx_ucast_frames;
dev_stats->tx_bytes = OTX2_GET_TX_STATS(TX_OCTS);
- dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP);
+ dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP) +
+ dev_stats->tx_discards;
dev_stats->tx_bcast_frames = OTX2_GET_TX_STATS(TX_BCAST);
dev_stats->tx_mcast_frames = OTX2_GET_TX_STATS(TX_MCAST);
dev_stats->tx_ucast_frames = OTX2_GET_TX_STATS(TX_UCAST);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
index ca0e6ab12ceb..a58c902eb75d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
@@ -149,6 +149,7 @@ struct otx2_dev_stats {
u64 tx_bcast_frames;
u64 tx_mcast_frames;
u64 tx_drops;
+ u64 tx_discards;
};
/* Driver counted stats */
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index db7c466fdc39..f9cf6a8f2f9b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -2153,6 +2153,7 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct otx2_nic *pf = netdev_priv(netdev);
int qidx = skb_get_queue_mapping(skb);
+ struct otx2_dev_stats *dev_stats;
struct otx2_snd_queue *sq;
struct netdev_queue *txq;
int sq_idx;
@@ -2165,6 +2166,8 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
/* Check for minimum and maximum packet length */
if (skb->len <= ETH_HLEN ||
(!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) {
+ dev_stats = &pf->hw.dev_stats;
+ dev_stats->tx_discards++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
index 8a8b598bd389..3bb55e4a11d3 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
@@ -391,9 +391,19 @@ static netdev_tx_t otx2vf_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct otx2_nic *vf = netdev_priv(netdev);
int qidx = skb_get_queue_mapping(skb);
+ struct otx2_dev_stats *dev_stats;
struct otx2_snd_queue *sq;
struct netdev_queue *txq;
+ /* Check for minimum and maximum packet length */
+ if (skb->len <= ETH_HLEN ||
+ (!skb_shinfo(skb)->gso_size && skb->len > vf->tx_max_pktlen)) {
+ dev_stats = &vf->hw.dev_stats;
+ dev_stats->tx_discards++;
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
sq = &vf->qset.sq[qidx];
txq = netdev_get_tx_queue(netdev, qidx);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
index 2cd3da3b6843..d2412d027f6f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
@@ -371,7 +371,7 @@ static void rvu_rep_get_stats(struct work_struct *work)
stats->rx_mcast_frames = rsp->rx.mcast;
stats->tx_bytes = rsp->tx.octs;
stats->tx_frames = rsp->tx.ucast + rsp->tx.bcast + rsp->tx.mcast;
- stats->tx_drops = rsp->tx.drop;
+ stats->tx_drops = rsp->tx.drop + stats->tx_discards;
exit:
mutex_unlock(&priv->mbox.lock);
}
@@ -418,6 +418,16 @@ static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device *dev)
struct otx2_nic *pf = rep->mdev;
struct otx2_snd_queue *sq;
struct netdev_queue *txq;
+ struct rep_stats *stats;
+
+ /* Check for minimum and maximum packet length */
+ if (skb->len <= ETH_HLEN ||
+ (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) {
+ stats = &rep->stats;
+ stats->tx_discards++;
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
sq = &pf->qset.sq[rep->rep_id];
txq = netdev_get_tx_queue(dev, 0);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.h b/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
index 38446b3e4f13..277615ed7174 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
@@ -27,6 +27,7 @@ struct rep_stats {
u64 tx_bytes;
u64 tx_frames;
u64 tx_drops;
+ u64 tx_discards;
};
struct rep_dev {
--
2.34.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [net PatchV4] Octeontx2-vf: Fix max packet length errors
2025-07-24 7:06 [net PatchV4] Octeontx2-vf: Fix max packet length errors Hariprasad Kelam
@ 2025-07-25 21:39 ` Jakub Kicinski
0 siblings, 0 replies; 2+ messages in thread
From: Jakub Kicinski @ 2025-07-25 21:39 UTC (permalink / raw)
To: Hariprasad Kelam
Cc: netdev, linux-kernel, Sunil Goutham, Geetha sowjanya,
Subbaraya Sundeep, Bharat Bhushan, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni, Tomasz Duszynski, Simon Horman
On Thu, 24 Jul 2025 12:36:22 +0530 Hariprasad Kelam wrote:
> @@ -2165,6 +2166,8 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
> /* Check for minimum and maximum packet length */
> if (skb->len <= ETH_HLEN ||
> (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) {
> + dev_stats = &pf->hw.dev_stats;
> + dev_stats->tx_discards++;
> dev_kfree_skb(skb);
> return NETDEV_TX_OK;
> }
This is a multi-queue device and the counter is per device.
The counter should really be an atomic_long_t, to avoid races.
--
pw-bot: cr
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-07-25 21:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-24 7:06 [net PatchV4] Octeontx2-vf: Fix max packet length errors Hariprasad Kelam
2025-07-25 21:39 ` Jakub Kicinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).