linux/drivers/net/wireless/iwlwifi
Emmanuel Grumbach 1c4abec0ba iwlwifi: mvm: fix setting channel in monitor mode
There was a deadlock in monitor mode when we were setting the
channel if the channel was not 1.

======================================================
[ INFO: possible circular locking dependency detected ]
3.14.3 #4 Not tainted
-------------------------------------------------------
iw/3323 is trying to acquire lock:
 (&local->chanctx_mtx){+.+.+.}, at: [<ffffffffa062e2f2>] ieee80211_vif_release_channel+0x42/0xb0 [mac80211]

but task is already holding lock:
 (&local->iflist_mtx){+.+...}, at: [<ffffffffa0609e0a>] ieee80211_set_monitor_channel+0x5a/0x1b0 [mac80211]

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #2 (&local->iflist_mtx){+.+...}:
       [<ffffffff810d95bb>] __lock_acquire+0xb3b/0x13b0
       [<ffffffff810d9ee0>] lock_acquire+0xb0/0x1f0
       [<ffffffff817eb9c8>] mutex_lock_nested+0x78/0x4f0
       [<ffffffffa06225cf>] ieee80211_iterate_active_interfaces+0x2f/0x60 [mac80211]
       [<ffffffffa0518189>] iwl_mvm_recalc_multicast+0x49/0xa0 [iwlmvm]
       [<ffffffffa051822e>] iwl_mvm_configure_filter+0x4e/0x70 [iwlmvm]
       [<ffffffffa05e6d43>] ieee80211_configure_filter+0x153/0x5f0 [mac80211]
       [<ffffffffa05e71f5>] ieee80211_reconfig_filter+0x15/0x20 [mac80211]
       [snip]

-> #1 (&mvm->mutex){+.+.+.}:
       [<ffffffff810d95bb>] __lock_acquire+0xb3b/0x13b0
       [<ffffffff810d9ee0>] lock_acquire+0xb0/0x1f0
       [<ffffffff817eb9c8>] mutex_lock_nested+0x78/0x4f0
       [<ffffffffa0517246>] iwl_mvm_add_chanctx+0x56/0xe0 [iwlmvm]
       [<ffffffffa062ca1e>] ieee80211_new_chanctx+0x13e/0x410 [mac80211]
       [<ffffffffa062d953>] ieee80211_vif_use_channel+0x1c3/0x5a0 [mac80211]
       [<ffffffffa06035ab>] ieee80211_add_virtual_monitor+0x1ab/0x6b0 [mac80211]
       [<ffffffffa06052ea>] ieee80211_do_open+0xe6a/0x15a0 [mac80211]
       [<ffffffffa0605a79>] ieee80211_open+0x59/0x60 [mac80211]
       [snip]

-> #0 (&local->chanctx_mtx){+.+.+.}:
       [<ffffffff810d6cb7>] check_prevs_add+0x977/0x980
       [<ffffffff810d95bb>] __lock_acquire+0xb3b/0x13b0
       [<ffffffff810d9ee0>] lock_acquire+0xb0/0x1f0
       [<ffffffff817eb9c8>] mutex_lock_nested+0x78/0x4f0
       [<ffffffffa062e2f2>] ieee80211_vif_release_channel+0x42/0xb0 [mac80211]
       [<ffffffffa0609ec3>] ieee80211_set_monitor_channel+0x113/0x1b0 [mac80211]
       [<ffffffffa058fb37>] cfg80211_set_monitor_channel+0x77/0x2b0 [cfg80211]
       [<ffffffffa056e0b2>] __nl80211_set_channel+0x122/0x140 [cfg80211]
       [<ffffffffa0581374>] nl80211_set_wiphy+0x284/0xaf0 [cfg80211]
       [snip]

other info that might help us debug this:

Chain exists of:
  &local->chanctx_mtx --> &mvm->mutex --> &local->iflist_mtx

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(&local->iflist_mtx);
                               lock(&mvm->mutex);
                               lock(&local->iflist_mtx);
  lock(&local->chanctx_mtx);

 *** DEADLOCK ***

This deadlock actually occurs:
INFO: task iw:3323 blocked for more than 120 seconds.
      Not tainted 3.14.3 #4
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
iw              D ffff8800c8afcd80  4192  3323   3322 0x00000000
 ffff880078fdb7e0 0000000000000046 ffff8800c8afcd80 ffff880078fdbfd8
 00000000001d5540 00000000001d5540 ffff8801141b0000 ffff8800c8afcd80
 ffff880078ff9e38 ffff880078ff9e38 ffff880078ff9e40 0000000000000246
Call Trace:
 [<ffffffff817ea841>] schedule_preempt_disabled+0x31/0x80
 [<ffffffff817ebaed>] mutex_lock_nested+0x19d/0x4f0
 [<ffffffffa06225cf>] ? ieee80211_iterate_active_interfaces+0x2f/0x60 [mac80211]
 [<ffffffffa06225cf>] ? ieee80211_iterate_active_interfaces+0x2f/0x60 [mac80211]
 [<ffffffffa052a680>] ? iwl_mvm_power_mac_update_mode+0xc0/0xc0 [iwlmvm]
 [<ffffffffa06225cf>] ieee80211_iterate_active_interfaces+0x2f/0x60 [mac80211]
 [<ffffffffa0529357>] _iwl_mvm_power_update_binding+0x27/0x80 [iwlmvm]
 [<ffffffffa0516eb1>] iwl_mvm_unassign_vif_chanctx+0x81/0xc0 [iwlmvm]
 [<ffffffffa062d3ff>] __ieee80211_vif_release_channel+0xdf/0x470 [mac80211]
 [<ffffffffa062e2fa>] ieee80211_vif_release_channel+0x4a/0xb0 [mac80211]
 [<ffffffffa0609ec3>] ieee80211_set_monitor_channel+0x113/0x1b0 [mac80211]
 [<ffffffffa058fb37>] cfg80211_set_monitor_channel+0x77/0x2b0 [cfg80211]
 [<ffffffffa056e0b2>] __nl80211_set_channel+0x122/0x140 [cfg80211]
 [<ffffffffa0581374>] nl80211_set_wiphy+0x284/0xaf0 [cfg80211]

This fixes https://bugzilla.kernel.org/show_bug.cgi?id=75541

Cc: <stable@vger.kernel.org> [3.13+]
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
2014-05-11 13:10:08 +03:00
..
dvm Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next 2014-03-18 16:55:28 -04:00
mvm iwlwifi: mvm: fix setting channel in monitor mode 2014-05-11 13:10:08 +03:00
pcie iwlwifi: pcie: disable interrupts upon PCIe alloc 2014-05-07 22:54:32 +03:00
iwl-1000.c iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-2000.c iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-5000.c iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-6000.c iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-7000.c iwlwifi: add MODULE_FIRMWARE for 7265 2014-04-13 16:50:56 +03:00
iwl-8000.c iwlwifi: 8000: add 11n only SKU of 8000 devices 2014-02-06 21:11:30 +02:00
iwl-agn-hw.h iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-config.h iwlwifi: pcie: enable LP XTAL to reduce power consumption 2014-03-09 19:16:39 +02:00
iwl-csr.h iwlwifi: pcie: enable LP XTAL to reduce power consumption 2014-03-09 19:16:39 +02:00
iwl-debug.c iwlwifi: export symbols only conditionally 2013-03-06 16:47:56 +01:00
iwl-debug.h iwlwifi: add enter/exit D0i3 ops 2014-02-03 22:23:39 +02:00
iwl-devtrace.c iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-devtrace.h iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-drv.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless 2014-03-04 13:05:12 -05:00
iwl-drv.h iwlwifi: mvm: new NVM format in family 8000 2014-02-13 13:49:37 +02:00
iwl-eeprom-parse.c iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-eeprom-parse.h iwlwifi: mvm: new NVM format in family 8000 2014-02-13 13:49:37 +02:00
iwl-eeprom-read.c iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-eeprom-read.h iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-fh.h iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-fw-file.h iwlwifi: mvm: prepare infrastructure for more TLV flags 2014-02-23 21:32:22 +02:00
iwl-fw.h iwlwifi: mvm: configure seq_num to D0i3 2014-03-16 13:45:23 +02:00
iwl-io.c iwlwifi: pcie: enable LP XTAL to reduce power consumption 2014-03-09 19:16:39 +02:00
iwl-io.h iwlwifi: pcie: enable LP XTAL to reduce power consumption 2014-03-09 19:16:39 +02:00
iwl-modparams.h Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless 2014-03-04 13:05:12 -05:00
iwl-notif-wait.c iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-notif-wait.h iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-nvm-parse.c iwlwifi: nvm: fix VHT capability antenna-dependent fields 2014-03-09 16:39:08 +02:00
iwl-nvm-parse.h iwlwifi: mvm: new NVM format in family 8000 2014-02-13 13:49:37 +02:00
iwl-op-mode.h iwlwifi: return whether to stop from rfkill method 2014-03-09 19:16:46 +02:00
iwl-phy-db.c iwlwifi: change number of PAPD groups in PHY DB 2014-02-06 21:12:26 +02:00
iwl-phy-db.h iwlwifi: Update Copyright to 2014 2013-12-31 19:03:53 +02:00
iwl-prph.h iwlwifi: pcie: enable LP XTAL to reduce power consumption 2014-03-09 19:16:39 +02:00
iwl-trans.h iwlwifi: make various things const 2014-02-13 10:18:43 +02:00
Kconfig iwlwifi: rs: use const u16 for throughput tables 2014-02-03 22:23:37 +02:00
Makefile iwlwifi: Add 8000 HW family support 2014-02-03 22:23:31 +02:00