1
linux/drivers/net/wireless
Reinette Chatre fbc9f97bbf iwlwifi: do not cancel delayed work inside spin_lock_irqsave
Calling cancel_delayed_work() from inside
spin_lock_irqsave, introduces a potential deadlock.

As explained by Johannes Berg <johannes@sipsolutions.net>

A - lock
T - timer

phase                   CPU 1           CPU 2
---------------------------------------------

some place that calls
cancel_timer_sync()
(which is the | code)
                                        lock-irq(A)
|                                       "lock-irq"(T)
|                                       "unlock"(T)
|                                       wait(T)
                                        unlock(A)

timer softirq
                        "lock"(T)
                        run(T)
                        "unlock"(T)

irq handler
          lock(A)
          unlock(A)

Now all that again, interleaved, leading to deadlock:

                                        lock-irq(A)
                        "lock"(T)
                         run(T)
IRQ during or maybe
before run(T) -->        lock(A)
                                        "lock-irq"(T)
                                        wait(T)

We fix this by moving the call to cancel_delayed_work() into workqueue.
There are cases where the work may not actually be queued or running
at the time we are trying to cancel it, but cancel_delayed_work() is
able to deal with this.

Also cleanup iwl_set_mode related to this call. This function
(iwl_set_mode) is only called when bringing interface up and there will
thus not be any scanning done. No need to try to cancel scanning.

Fixes http://bugzilla.kernel.org/show_bug.cgi?id=13224, which was also
reported at http://marc.info/?l=linux-wireless&m=124081921903223&w=2 .

Tested-by: Miles Lane <miles.lane@gmail.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Acked-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
2009-05-20 14:29:53 -04:00
..
ar9170 ar9170usb: fix hang on resume 2009-04-20 16:36:26 -04:00
ath5k ath5k: fix exp off-by-one when computing OFDM delta slope 2009-05-20 14:07:51 -04:00
ath9k Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2009-04-24 07:46:51 -07:00
b43 b43: Do radio lock assertion in software 2009-04-16 10:39:14 -04:00
b43legacy dma-mapping: replace all DMA_30BIT_MASK macro with DMA_BIT_MASK(30) 2009-04-07 08:31:11 -07:00
hostap hostap: convert to net_device_ops 2009-03-21 22:55:36 -07:00
ipw2x00 dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
iwlwifi iwlwifi: do not cancel delayed work inside spin_lock_irqsave 2009-05-20 14:29:53 -04:00
libertas libertas: don't leak skb on receive error 2009-04-16 10:39:08 -04:00
libertas_tf
orinoco orinoco: correct timeout logic in __orinoco_hw_set_tkip_key() 2009-04-16 10:39:17 -04:00
p54 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2009-04-24 07:46:51 -07:00
prism54 dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
rt2x00 rt2x00: Don't free register information on suspend 2009-04-20 16:36:26 -04:00
rtl818x rtl8187: use DMA-aware buffers with usb_control_msg 2009-05-11 15:07:01 -04:00
zd1211rw Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6 2009-03-17 15:01:30 -07:00
adm8211.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
adm8211.h
airo_cs.c
airo.c airo: airo_get_encode{,ext} potential buffer overflow 2009-05-11 15:07:01 -04:00
airo.h
arlan-main.c Merge branch 'linus' into percpu-cpumask-x86-for-linus-2 2009-03-28 04:26:01 +01:00
arlan-proc.c
arlan.h
at76c50x-usb.c at76c50x-usb: Add device ID for OQO model 01+ 2009-04-16 10:39:09 -04:00
at76c50x-usb.h
atmel_cs.c
atmel_pci.c
atmel.c atmel: fix netdev ops conversion 2009-04-21 02:08:51 -07:00
atmel.h
i82586.h
i82593.h
Kconfig ar9170: update Makefile, Kconfig and MAINTAINERS 2009-03-27 20:13:09 -04:00
mac80211_hwsim.c mac80211/iwlwifi: move virtual A-MDPU queue bookkeeping to iwlwifi 2009-03-27 20:13:23 -04:00
Makefile ar9170: single module build 2009-03-27 20:13:19 -04:00
mwl8k.c mwl8: fix build warning. 2009-04-21 16:43:33 -04:00
netwave_cs.c netwave: convert to net_device_ops 2009-03-21 22:43:57 -07:00
ray_cs.c raylan: convert to net_device_ops 2009-03-21 22:51:19 -07:00
ray_cs.h
rayctl.h
rndis_wlan.c rndis_wlan: fix initialization order for workqueue&workers 2009-04-28 15:59:48 -04:00
strip.c strip: convert to net_device_ops 2009-03-21 22:43:57 -07:00
wavelan_cs.c wavelan: convert to net_device_ops 2009-03-21 22:43:59 -07:00
wavelan_cs.h
wavelan_cs.p.h wavelan: convert to internal net_device_stats 2009-03-21 22:43:58 -07:00
wavelan.c wireless: convert wavelan to net_device_ops 2009-03-27 00:46:46 -07:00
wavelan.h
wavelan.p.h wireless: convert wavelan to net_device_ops 2009-03-27 00:46:46 -07:00
wl3501_cs.c wl3501: convert to net_device_ops 2009-03-21 22:51:20 -07:00
wl3501.h wl3501: convert to internal net_device_stats 2009-03-21 22:51:19 -07:00
zd1201.c wireless: remove duplicated .ndo_set_mac_address 2009-03-29 13:52:21 -07:00
zd1201.h zd1201: convert to internal net_device_stats 2009-03-21 22:51:20 -07:00