mvpp2_tx_hw_tstamp() takes an extra reference on skbs that need a TX timestamp and stores them in port->tx_hwtstamp_queue[]. The reference is dropped by mvpp2_isr_handle_ptp_queue() when the hardware reports the timestamp. Nothing drains the queues when the port is stopped, so skbs still waiting for a timestamp keep their reference until their queue slot is reused, and are leaked for good when the port is removed. Free the queued skbs in mvpp2_stop(), after the interrupts have been released. Fixes: f5015a594c50 ("net: mvpp2: ptp: add support for transmit timestamping") Cc: stable@vger.kernel.org Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex Signed-off-by: Wentao Liang --- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index 317af54369cf..fc020b8c8830 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -3419,6 +3419,22 @@ static void mvpp2_isr_handle_ptp(struct mvpp2_port *port) mvpp2_isr_handle_ptp_queue(port, 1); } +static void mvpp2_tx_hwtstamp_flush(struct mvpp2_port *port) +{ + struct mvpp2_hwtstamp_queue *queue; + int nq, i; + + for (nq = 0; nq < ARRAY_SIZE(port->tx_hwtstamp_queue); nq++) { + queue = &port->tx_hwtstamp_queue[nq]; + for (i = 0; i < ARRAY_SIZE(queue->skb); i++) { + if (!queue->skb[i]) + continue; + dev_kfree_skb_any(queue->skb[i]); + queue->skb[i] = NULL; + } + } +} + static void mvpp2_isr_handle_link(struct mvpp2_port *port, struct phylink_pcs *pcs, bool link) { @@ -4914,6 +4930,7 @@ static int mvpp2_stop(struct net_device *dev) free_irq(port->port_irq, port); mvpp2_irqs_deinit(port); + mvpp2_tx_hwtstamp_flush(port); if (!port->has_tx_irqs) { for (thread = 0; thread < port->priv->nthreads; thread++) { port_pcpu = per_cpu_ptr(port->pcpu, thread); -- 2.34.1