net: calxedaxgmac: Fix panic caused by MTU change of active interface
authorAndreas Herrmann <andreas.herrmann@calxeda.com>
Thu, 7 Nov 2013 11:07:56 +0000 (12:07 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Nov 2013 00:25:53 +0000 (19:25 -0500)
commitb5ad795e52dae6e9f88b193a5e779b70005d005c
tree520907ecada6e8f2d3ed49e08d7483b98a6115eb
parente21dd863acec8d3bc5166fb2a0c680a9982b37db
net: calxedaxgmac: Fix panic caused by MTU change of active interface

Changing MTU size of an xgmac network interface while it is active can
cause a panic like

  skbuff: skb_over_panic: text:c03bc62c len:1090 put:1090 head:edfb6900 data:edfb6942 tail:0xedfb6d84 end:0xedfb6bc0 dev:eth0
  ------------[ cut here ]------------
  kernel BUG at net/core/skbuff.c:126!
  Internal error: Oops - BUG: 0 [#1] SMP ARM
  Modules linked in:
  CPU: 0 PID: 762 Comm: python Tainted: G        W    3.10.0-00015-g3e33cd7 #309
  task: edcfe000 ti: ed67e000 task.ti: ed67e000
  PC is at skb_panic+0x64/0x70
  LR is at wake_up_klogd+0x5c/0x68

This happens because xgmac_change_mtu modifies dev->mtu before the
network interface is quiesced. And thus there still might be buffers
in use which have a buffer size based on the old MTU.

To fix this I moved the change of dev->mtu after the call to
xgmac_stop.

Another modification is required (in xgmac_stop) to ensure that
xgmac_xmit is really not called anymore (xgmac_tx_complete might wake
up the queue again).

I've tested the fix by switching MTU size every second between 600 and
1500 while network traffic was going on. The test box survived a test
of several hours (until I've stopped it) whereas w/o this fix above
panic occurs after several minutes (at most).

Change since v1:
- remove call to netif_stop_queue at beginning of xgmac_stop
- use netif_tx_disable instead of locking+netif_stop_queue

Signed-off-by: Andreas Herrmann <andreas.herrmann@calxeda.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/calxeda/xgmac.c