linux/drivers/net/wireless/iwlwifi
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
..
iwl3945-base.c iwlwifi: do not cancel delayed work inside spin_lock_irqsave 2009-05-20 14:29:53 -04:00
iwl-1000.c iwlwifi: correct device name for 1000 series 2009-03-16 18:09:36 -04:00
iwl-3945-fh.h iwlwifi: update copyright year to 2009 2009-01-29 16:00:15 -05:00
iwl-3945-hw.h iwl3945: set TFD_QUEUE_MAX to correct value 2009-03-27 20:12:58 -04:00
iwl-3945-led.c iwl3945: use iwl_led structure 2009-03-16 18:09:46 -04:00
iwl-3945-led.h iwl3945: use iwl_led structure 2009-03-16 18:09:46 -04:00
iwl-3945-rs.c iwl3945: control rate decrease 2009-03-27 20:12:59 -04:00
iwl-3945.c iwlwifi: DMA fixes 2009-04-21 16:43:34 -04:00
iwl-3945.h iwlwifi: DMA fixes 2009-04-21 16:43:34 -04:00
iwl-4965-hw.h iwlwifi: use pci registers defined in pci_regs.h 2009-02-13 13:46:04 -05:00
iwl-4965.c mac80211/iwlwifi: move virtual A-MDPU queue bookkeeping to iwlwifi 2009-03-27 20:13:23 -04:00
iwl-5000-hw.h iwlwifi: update copyright year to 2009 2009-01-29 16:00:15 -05:00
iwl-5000.c mac80211/iwlwifi: move virtual A-MDPU queue bookkeeping to iwlwifi 2009-03-27 20:13:23 -04:00
iwl-6000-hw.h iwlwifi: add recognition of Intel WiFi Link 6000 and 6050 Series 2009-01-29 16:01:02 -05:00
iwl-6000.c iwlwifi: fix device id registration for 6000 series 2x2 devices 2009-05-11 15:07:02 -04:00
iwl-agn-rs.c iwlwifi: verify the antenna selection when receive fixed rate debugfs 2009-03-16 18:09:45 -04:00
iwl-agn-rs.h iwlwifi: HT performance improvement changes 2009-03-16 18:09:44 -04:00
iwl-agn.c iwlwifi: do not cancel delayed work inside spin_lock_irqsave 2009-05-20 14:29:53 -04:00
iwl-calib.c wireless: replace uses of __constant_{endian} 2009-02-09 15:03:43 -05:00
iwl-calib.h iwlwifi: update copyright year to 2009 2009-01-29 16:00:15 -05:00
iwl-commands.h wireless: replace uses of __constant_{endian} 2009-02-09 15:03:43 -05:00
iwl-core.c mac80211/iwlwifi: move virtual A-MDPU queue bookkeeping to iwlwifi 2009-03-27 20:13:23 -04:00
iwl-core.h iwl3945: use iwl_cmd_queue_free 2009-03-27 20:12:59 -04:00
iwl-csr.h iwlwifi: fix EEPROM validation mask to include OTP only devices 2009-04-21 16:43:30 -04:00
iwl-debug.h iwlwifi: don't use implicit priv in IWL_DEBUG 2009-02-09 15:03:34 -05:00
iwl-debugfs.c iwlwifi: show current driver status in user readable format 2009-03-27 20:13:20 -04:00
iwl-dev.h iwlwifi: DMA fixes 2009-04-21 16:43:34 -04:00
iwl-eeprom.c iwlwifi: fix FAT channel config for 5000 series 2009-02-13 13:46:08 -05:00
iwl-eeprom.h iwlwifi: fix FAT channel config for 5000 series 2009-02-13 13:46:08 -05:00
iwl-fh.h iwlwifi: update copyright year to 2009 2009-01-29 16:00:15 -05:00
iwl-hcmd.c iwlwifi: don't use implicit priv in IWL_DEBUG 2009-02-09 15:03:34 -05:00
iwl-helpers.h mac80211/iwlwifi: move virtual A-MDPU queue bookkeeping to iwlwifi 2009-03-27 20:13:23 -04:00
iwl-io.h iwlwifi: print contents of control register when error occurs 2009-03-16 18:09:47 -04:00
iwl-led.c iwlwifi: fix led naming 2009-02-09 15:03:43 -05:00
iwl-led.h iwl3945: use iwl_led structure 2009-03-16 18:09:46 -04:00
iwl-power.c iwlcore: dont commit power command if interface is not up 2009-03-27 20:12:58 -04:00
iwl-power.h wireless: replace uses of __constant_{endian} 2009-02-09 15:03:43 -05:00
iwl-prph.h iwlwifi: update copyright year to 2009 2009-01-29 16:00:15 -05:00
iwl-rfkill.c iwlwifi: don't use implicit priv in IWL_DEBUG 2009-02-09 15:03:34 -05:00
iwl-rfkill.h iwlwifi: update copyright year to 2009 2009-01-29 16:00:15 -05:00
iwl-rx.c iwlwifi: don't use implicit priv in IWL_DEBUG 2009-02-09 15:03:34 -05:00
iwl-scan.c iwlwifi: do not cancel delayed work inside spin_lock_irqsave 2009-05-20 14:29:53 -04:00
iwl-spectrum.c iwlwifi: don't use implicit priv in IWL_DEBUG 2009-02-09 15:03:34 -05:00
iwl-spectrum.h iwlwifi: update copyright year to 2009 2009-01-29 16:00:15 -05:00
iwl-sta.c iwlwifi: update key flags at time key is set 2009-05-04 16:22:10 -04:00
iwl-sta.h iwl3945: unify set key flow with iwlwifi 2009-03-05 14:39:36 -05:00
iwl-tx.c iwlwifi: DMA fixes 2009-04-21 16:43:34 -04:00
Kconfig iwl3945: use iwl_led structure 2009-03-16 18:09:46 -04:00
Makefile iwl3945: use iwl_led structure 2009-03-16 18:09:46 -04:00