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. Initialize the timer before requesting the IRQ, and cancel it again after free_irq() has drained every handler that can rearm it. Keep the first cancellation to prevent the timer callback from scheduling NAPI while the poll instance is being disabled. 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 c32e9574c8c9..d4afe6efb29e 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c @@ -2194,6 +2194,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) { @@ -2230,9 +2234,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; @@ -2269,6 +2270,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