mirror_ubuntu-kernels/drivers/net/ethernet
Vladimir Davydov b2f963bfae e1000: fix lockdep warning in e1000_reset_task
The patch fixes the following lockdep warning, which is 100%
reproducible on network restart:

======================================================
[ INFO: possible circular locking dependency detected ]
3.12.0+ #47 Tainted: GF
-------------------------------------------------------
kworker/1:1/27 is trying to acquire lock:
 ((&(&adapter->watchdog_task)->work)){+.+...}, at: [<ffffffff8108a5b0>] flush_work+0x0/0x70

but task is already holding lock:
 (&adapter->mutex){+.+...}, at: [<ffffffffa0177c0a>] e1000_reset_task+0x4a/0xa0 [e1000]

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #1 (&adapter->mutex){+.+...}:
       [<ffffffff810bdb5d>] lock_acquire+0x9d/0x120
       [<ffffffff816b8cbc>] mutex_lock_nested+0x4c/0x390
       [<ffffffffa017233d>] e1000_watchdog+0x7d/0x5b0 [e1000]
       [<ffffffff8108b972>] process_one_work+0x1d2/0x510
       [<ffffffff8108ca80>] worker_thread+0x120/0x3a0
       [<ffffffff81092c1e>] kthread+0xee/0x110
       [<ffffffff816c3d7c>] ret_from_fork+0x7c/0xb0

-> #0 ((&(&adapter->watchdog_task)->work)){+.+...}:
       [<ffffffff810bd9c0>] __lock_acquire+0x1710/0x1810
       [<ffffffff810bdb5d>] lock_acquire+0x9d/0x120
       [<ffffffff8108a5eb>] flush_work+0x3b/0x70
       [<ffffffff8108b5d8>] __cancel_work_timer+0x98/0x140
       [<ffffffff8108b693>] cancel_delayed_work_sync+0x13/0x20
       [<ffffffffa0170cec>] e1000_down_and_stop+0x3c/0x60 [e1000]
       [<ffffffffa01775b1>] e1000_down+0x131/0x220 [e1000]
       [<ffffffffa0177c12>] e1000_reset_task+0x52/0xa0 [e1000]
       [<ffffffff8108b972>] process_one_work+0x1d2/0x510
       [<ffffffff8108ca80>] worker_thread+0x120/0x3a0
       [<ffffffff81092c1e>] kthread+0xee/0x110
       [<ffffffff816c3d7c>] ret_from_fork+0x7c/0xb0

other info that might help us debug this:

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(&adapter->mutex);
                               lock((&(&adapter->watchdog_task)->work));
                               lock(&adapter->mutex);
  lock((&(&adapter->watchdog_task)->work));

 *** DEADLOCK ***

3 locks held by kworker/1:1/27:
 #0:  (events){.+.+.+}, at: [<ffffffff8108b906>] process_one_work+0x166/0x510
 #1:  ((&adapter->reset_task)){+.+...}, at: [<ffffffff8108b906>] process_one_work+0x166/0x510
 #2:  (&adapter->mutex){+.+...}, at: [<ffffffffa0177c0a>] e1000_reset_task+0x4a/0xa0 [e1000]

stack backtrace:
CPU: 1 PID: 27 Comm: kworker/1:1 Tainted: GF            3.12.0+ #47
Hardware name: System manufacturer System Product Name/P5B-VM SE, BIOS 0501    05/31/2007
Workqueue: events e1000_reset_task [e1000]
 ffffffff820f6000 ffff88007b9dba98 ffffffff816b54a2 0000000000000002
 ffffffff820f5e50 ffff88007b9dbae8 ffffffff810ba936 ffff88007b9dbac8
 ffff88007b9dbb48 ffff88007b9d8f00 ffff88007b9d8780 ffff88007b9d8f00
Call Trace:
 [<ffffffff816b54a2>] dump_stack+0x49/0x5f
 [<ffffffff810ba936>] print_circular_bug+0x216/0x310
 [<ffffffff810bd9c0>] __lock_acquire+0x1710/0x1810
 [<ffffffff8108a5b0>] ? __flush_work+0x250/0x250
 [<ffffffff810bdb5d>] lock_acquire+0x9d/0x120
 [<ffffffff8108a5b0>] ? __flush_work+0x250/0x250
 [<ffffffff8108a5eb>] flush_work+0x3b/0x70
 [<ffffffff8108a5b0>] ? __flush_work+0x250/0x250
 [<ffffffff8108b5d8>] __cancel_work_timer+0x98/0x140
 [<ffffffff8108b693>] cancel_delayed_work_sync+0x13/0x20
 [<ffffffffa0170cec>] e1000_down_and_stop+0x3c/0x60 [e1000]
 [<ffffffffa01775b1>] e1000_down+0x131/0x220 [e1000]
 [<ffffffffa0177c12>] e1000_reset_task+0x52/0xa0 [e1000]
 [<ffffffff8108b972>] process_one_work+0x1d2/0x510
 [<ffffffff8108b906>] ? process_one_work+0x166/0x510
 [<ffffffff8108ca80>] worker_thread+0x120/0x3a0
 [<ffffffff8108c960>] ? manage_workers+0x2c0/0x2c0
 [<ffffffff81092c1e>] kthread+0xee/0x110
 [<ffffffff81092b30>] ? __init_kthread_worker+0x70/0x70
 [<ffffffff816c3d7c>] ret_from_fork+0x7c/0xb0
 [<ffffffff81092b30>] ? __init_kthread_worker+0x70/0x70

== The issue background ==

The problem occurs, because e1000_down(), which is called under
adapter->mutex by e1000_reset_task(), tries to synchronously cancel
e1000 auxiliary works (reset_task, watchdog_task, phy_info_task,
fifo_stall_task), which take adapter->mutex in their handlers. So the
question is what does adapter->mutex protect there?

The adapter->mutex was introduced by commit 0ef4ee ("e1000: convert to
private mutex from rtnl") as a replacement for rtnl_lock() taken in the
asynchronous handlers. It targeted on fixing a similar lockdep warning
issued when e1000_down() was called under rtnl_lock(), and it fixed it,
but unfortunately it introduced the lockdep warning described above.
Anyway, that said the source of this bug is that the asynchronous works
were made to take rtnl_lock() some time ago, so let's look deeper and
find why it was added there.

The rtnl_lock() was added to asynchronous handlers by commit 338c15
("e1000: fix occasional panic on unload") in order to prevent
asynchronous handlers from execution after the module is unloaded
(e1000_down() is called) as it follows from the comment to the commit:

> Net drivers in general have an issue where timers fired
> by mod_timer or work threads with schedule_work are running
> outside of the rtnl_lock.
>
> With no other lock protection these routines are vulnerable
> to races with driver unload or reset paths.
>
> The longer term solution to this might be a redesign with
> safer locks being taken in the driver to guarantee no
> reentrance, but for now a safe and effective fix is
> to take the rtnl_lock in these routines.

I'm not sure if this locking scheme fixed the problem or just made it
unlikely, although I incline to the latter. Anyway, this was long time
ago when e1000 auxiliary works were implemented as timers scheduling
real work handlers in their routines. The e1000_down() function only
canceled the timers, but left the real handlers running if they were
running, which could result in work execution after module unload.
Today, the e1000 driver uses sane delayed works instead of the pair
timer+work to implement its delayed asynchronous handlers, and the
e1000_down() synchronously cancels all the works so that the problem
that commit 338c15 tried to cope with disappeared, and we don't need any
locks in the handlers any more. Moreover, any locking there can
potentially result in a deadlock.

So, this patch reverts commits 0ef4ee and 338c15.

Fixes: 0ef4eedc2e ("e1000: convert to private mutex from rtnl")
Fixes: 338c15e470 ("e1000: fix occasional panic on unload")
Cc: Tushar Dave <tushar.n.dave@intel.com>
Cc: Patrick McHardy <kaber@trash.net>
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
2013-11-29 23:55:40 -08:00
..
3com net: typhoon: remove unnecessary pci_set_drvdata() 2013-10-18 00:03:28 -04:00
8390 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2013-11-13 17:40:34 +09:00
adaptec net: starfire: remove unnecessary pci_set_drvdata() 2013-10-18 00:03:28 -04:00
adi adi: Remove extern from function prototypes 2013-09-24 10:09:18 -04:00
aeroflex drivers:net: Convert dma_alloc_coherent(...__GFP_ZERO) to dma_zalloc_coherent 2013-08-29 21:55:23 -04:00
allwinner
alteon
amd Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2013-11-13 17:40:34 +09:00
apple macmace: add missing platform_set_drvdata() in mace_probe() 2013-11-11 14:02:08 -05:00
arc Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2013-11-13 17:40:34 +09:00
atheros alx: Reset phy speed after resume 2013-11-14 17:14:42 -05:00
broadcom tg3: Convert to use hwmon_device_register_with_groups 2013-11-28 18:22:02 -05:00
brocade Merge branch 'for-linus-dma-masks' of git://git.linaro.org/people/rmk/linux-arm 2013-11-14 07:55:21 +09:00
cadence Remove GENERIC_HARDIRQ config option 2013-09-13 15:09:52 +02:00
calxeda net: calxedaxgmac: Fix panic caused by MTU change of active interface 2013-11-07 19:25:53 -05:00
chelsio Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2013-11-04 13:48:30 -05:00
cirrus net: ep93xx_eth: use dev_get_platdata() 2013-08-30 17:43:35 -04:00
cisco net: enic: remove unnecessary pci_set_drvdata() 2013-10-18 00:03:30 -04:00
davicom Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2013-10-23 16:49:34 -04:00
dec net: tulip: use DEFINE_PCI_DEVICE_TABLE 2013-10-22 02:19:23 -04:00
dlink net: dl2k: remove unnecessary pci_set_drvdata() 2013-10-21 17:21:00 -04:00
emulex be2net: call napi_disable() for all event queues 2013-11-28 18:54:02 -05:00
faraday drivers:net: Convert dma_alloc_coherent(...__GFP_ZERO) to dma_zalloc_coherent 2013-08-29 21:55:23 -04:00
freescale net:fec: fix WARNING caused by lack of calls to dma_mapping_error() 2013-11-14 16:37:33 -05:00
fujitsu net: fujitsu: Remove ISA depdendency from Kconfig 2013-10-07 15:52:54 -04:00
hp hp100: replace hardcoded name in /proc/interrupts with interface name 2013-09-27 17:38:32 -04:00
i825xx net:drivers/net: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO 2013-11-07 03:01:59 -05:00
ibm Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2013-11-13 17:40:34 +09:00
icplus net: icplus: remove unnecessary pci_set_drvdata() 2013-10-21 17:21:01 -04:00
intel e1000: fix lockdep warning in e1000_reset_task 2013-11-29 23:55:40 -08:00
marvell Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2013-11-19 15:50:47 -08:00
mellanox Main batch of InfiniBand/RDMA changes for 3.13: 2013-11-18 15:36:04 -08:00
micrel net: ksz884x: use DEFINE_PCI_DEVICE_TABLE 2013-10-22 02:19:23 -04:00
microchip
moxa ethernet: moxa: remove duplicate includes 2013-10-21 18:46:45 -04:00
myricom net: myri10ge: remove unnecessary pci_set_drvdata() 2013-10-21 17:21:02 -04:00
natsemi xtsonic: add missing platform_set_drvdata() in xtsonic_probe() 2013-11-11 14:02:08 -05:00
neterion Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2013-11-14 16:30:30 +09:00
nuvoton drivers:net: delete premature free_irq 2013-09-04 13:18:19 -04:00
nvidia net: Explicitly initialize u64_stats_sync structures for lockdep 2013-11-06 12:40:25 +01:00
nxp DMA-API: net: nxp/lpc_eth: use dma_coerce_mask_and_coherent() 2013-10-31 14:48:56 +00:00
octeon Merge branch 'for-linus-dma-masks' of git://git.linaro.org/people/rmk/linux-arm 2013-11-14 07:55:21 +09:00
oki-semi pch_gbe: Validate hwtstamp_config completely before applying it 2013-11-14 16:22:10 -05:00
packetengines net: packetengines: remove unnecessary pci_set_drvdata() 2013-10-21 17:21:02 -04:00
pasemi net: pasemi: remove unnecessary pci_set_drvdata() 2013-10-22 02:11:51 -04:00
qlogic Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2013-11-15 16:47:22 -08:00
rdc net: r6040: remove unnecessary pci_set_drvdata() 2013-10-22 02:11:52 -04:00
realtek net: 8139cp: fix a BUG_ON triggered by wrong bytes_compl 2013-11-29 16:18:23 -05:00
renesas sh_eth: check platform data pointer 2013-11-04 15:49:28 -05:00
seeq net: seeq: use dev_get_platdata() 2013-08-30 17:43:37 -04:00
sfc sfc: Convert to use hwmon_device_register_with_groups 2013-11-29 16:26:16 -05:00
sgi net:drivers/net: Miscellaneous conversions to ETH_ALEN 2013-10-02 17:04:45 -04:00
silan
sis net: sis190: remove unnecessary pci_set_drvdata() 2013-10-22 02:11:52 -04:00
smsc net: smc91: fix crash regression on the versatile 2013-11-29 16:23:35 -05:00
stmicro stmmac: Validate hwtstamp_config completely before applying it 2013-11-14 16:22:10 -05:00
sun net: niu: remove unnecessary pci_set_drvdata() 2013-10-23 16:58:41 -04:00
tehuti net: tehuti: remove unnecessary pci_set_drvdata() 2013-10-23 16:58:41 -04:00
ti net: ethernet: ti/cpsw: do not crash on single-MAC machines during resume 2013-11-15 17:58:19 -05:00
tile Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2013-11-14 16:30:30 +09:00
toshiba net: tc35815: remove unnecessary pci_set_drvdata() 2013-10-23 16:58:41 -04:00
tundra net: tsi108: use dev_get_platdata() 2013-08-30 17:43:38 -04:00
via via-velocity: fix netif_receive_skb use in irq disabled section. 2013-11-28 18:43:35 -05:00
wiznet net: w5100: use dev_get_platdata() 2013-08-30 17:43:38 -04:00
xilinx Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2013-11-13 17:40:34 +09:00
xircom
xscale ixp4xx_eth: Validate hwtstamp_config completely before applying it 2013-11-14 16:22:10 -05:00
dnet.c
dnet.h
ethoc.c net: ethoc: use dev_get_platdata() 2013-08-30 17:43:35 -04:00
fealnx.c net: fealnx: remove unnecessary pci_set_drvdata() 2013-10-21 17:21:01 -04:00
jme.c net: jme: remove unnecessary pci_set_drvdata() 2013-10-21 17:21:01 -04:00
jme.h jme: Remove unused #define PFX 2013-11-07 02:14:32 -05:00
Kconfig
korina.c net:drivers/net: Miscellaneous conversions to ETH_ALEN 2013-10-02 17:04:45 -04:00
lantiq_etop.c net: lantiq_etop: remove deprecated IRQF_DISABLED 2013-09-15 22:01:05 -04:00
Makefile
netx-eth.c net: netx-eth: remove unnecessary casting 2013-09-04 00:27:27 -04:00
s6gmac.c