gmac_stop() cancels the RX coalescing timer before disabling and freeing the IRQ. An RX interrupt racing with that cancellation can rearm the timer, leaving it queued after the netdev and its private port state have been freed. gmac_open() also initializes the timer after enabling RX interrupts. With RX coalescing configured, an interrupt can start an uninitialized timer on first open, or one that setup then reinitializes while queued on reopen. Initialize the timer before requesting the IRQ. Keep the early stop-path cancellation as a best-effort drain of an existing timer; an RX interrupt can still rearm it before IRQ teardown. napi_disable() handles concurrent scheduling attempts. Cancel the timer again after free_irq() has drained the handler, so no timer callback can outlive the port. This was found by code inspection and tested on the D-Link DIR-685. Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet") Signed-off-by: Linus Walleij --- drivers/net/ethernet/cortina/gemini.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index d0d161654f49..24a66fc34738 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c @@ -2243,6 +2243,10 @@ static int gmac_open(struct net_device *netdev) struct gemini_ethernet_port *port = netdev_priv(netdev); int err; + hrtimer_setup(&port->rx_coalesce_timer, + &gmac_coalesce_delay_expired, + CLOCK_MONOTONIC, HRTIMER_MODE_REL); + err = request_irq(netdev->irq, gmac_irq, IRQF_SHARED, netdev->name, netdev); if (err) { @@ -2279,9 +2283,6 @@ static int gmac_open(struct net_device *netdev) gmac_enable_tx_rx(netdev); netif_tx_start_all_queues(netdev); - hrtimer_setup(&port->rx_coalesce_timer, &gmac_coalesce_delay_expired, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - netdev_dbg(netdev, "opened\n"); return 0; @@ -2318,6 +2319,7 @@ static int gmac_stop(struct net_device *netdev) phy_stop(netdev->phydev); free_irq(netdev->irq, netdev); + hrtimer_cancel(&port->rx_coalesce_timer); gmac_update_hw_stats(netdev); return 0; -- 2.56.0