From: willy tarreau Date: Thu, 16 Jan 2014 07:20:09 +0000 (+0100) Subject: net: mvneta: do not schedule in mvneta_tx_timeout X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=290213667ab53a95456397763205e4b1e30f46b5;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git net: mvneta: do not schedule in mvneta_tx_timeout If a queue timeout is reported, we can oops because of some schedules while the caller is atomic, as shown below : mvneta d0070000.ethernet eth0: tx timeout BUG: scheduling while atomic: bash/1528/0x00000100 Modules linked in: slhttp_ethdiv(C) [last unloaded: slhttp_ethdiv] CPU: 2 PID: 1528 Comm: bash Tainted: G WC 3.13.0-rc4-mvebu-nf #180 [] (unwind_backtrace+0x1/0x98) from [] (show_stack+0xb/0xc) [] (show_stack+0xb/0xc) from [] (dump_stack+0x4f/0x64) [] (dump_stack+0x4f/0x64) from [] (__schedule_bug+0x37/0x4c) [] (__schedule_bug+0x37/0x4c) from [] (__schedule+0x325/0x3ec) [] (__schedule+0x325/0x3ec) from [] (schedule_timeout+0xb7/0x118) [] (schedule_timeout+0xb7/0x118) from [] (msleep+0xf/0x14) [] (msleep+0xf/0x14) from [] (mvneta_stop_dev+0x21/0x194) [] (mvneta_stop_dev+0x21/0x194) from [] (mvneta_tx_timeout+0x19/0x24) [] (mvneta_tx_timeout+0x19/0x24) from [] (dev_watchdog+0x18b/0x1c4) [] (dev_watchdog+0x18b/0x1c4) from [] (call_timer_fn.isra.27+0x17/0x5c) [] (call_timer_fn.isra.27+0x17/0x5c) from [] (run_timer_softirq+0x115/0x170) [] (run_timer_softirq+0x115/0x170) from [] (__do_softirq+0xbd/0x1a8) [] (__do_softirq+0xbd/0x1a8) from [] (irq_exit+0x61/0x98) [] (irq_exit+0x61/0x98) from [] (handle_IRQ+0x27/0x60) [] (handle_IRQ+0x27/0x60) from [] (armada_370_xp_handle_irq+0x33/0xc8) [] (armada_370_xp_handle_irq+0x33/0xc8) from [] (__irq_usr+0x49/0x60) Ben Hutchings attempted to propose a better fix consisting in using a scheduled work for this, but while it fixed this panic, it caused other random freezes and panics proving that the reset sequence in the driver is unreliable and that additional fixes should be investigated. When sending multiple streams over a link limited to 100 Mbps, Tx timeouts happen from time to time, and the driver correctly recovers only when the function is disabled. Cc: Thomas Petazzoni Cc: Gregory CLEMENT Cc: Ben Hutchings Tested-by: Arnaud Ebalard Signed-off-by: Willy Tarreau Signed-off-by: David S. Miller --- diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 40d3e8bb7eed..84220c12e727 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -2244,16 +2244,6 @@ static void mvneta_stop_dev(struct mvneta_port *pp) mvneta_rx_reset(pp); } -/* tx timeout callback - display a message and stop/start the network device */ -static void mvneta_tx_timeout(struct net_device *dev) -{ - struct mvneta_port *pp = netdev_priv(dev); - - netdev_info(dev, "tx timeout\n"); - mvneta_stop_dev(pp); - mvneta_start_dev(pp); -} - /* Return positive if MTU is valid */ static int mvneta_check_mtu_valid(struct net_device *dev, int mtu) { @@ -2634,7 +2624,6 @@ static const struct net_device_ops mvneta_netdev_ops = { .ndo_set_rx_mode = mvneta_set_rx_mode, .ndo_set_mac_address = mvneta_set_mac_addr, .ndo_change_mtu = mvneta_change_mtu, - .ndo_tx_timeout = mvneta_tx_timeout, .ndo_get_stats64 = mvneta_get_stats64, .ndo_do_ioctl = mvneta_ioctl, };