ath5k: fix spin_lock_irqsave/spin_lock_bh nesting in mesh
Lockdep found an inconsistent lock state when joining a mesh with
ath5k. The problem is that ath5k takes the lock for its beacon state,
ah->block, with spin_lock_irqsave(), while mesh internally takes the
sync_offset_lock with spin_lock_bh() in mesh_sync_offset_adjust_tbtt(),
which in turn is called under ah->block.
This could deadlock if the beacon tasklet was run on the processor
that held the beacon lock during the do_softirq() in spin_unlock_bh().
We probably shouldn't hold the lock around the callbacks, but the
easiest fix is to switch to spin_lock_bh for ah->block: it doesn't
need interrupts disabled anyway as the data in question is only accessed
in softirq or process context.
Fixes the following lockdep warning:
[ 446.892304] WARNING: at kernel/softirq.c:159 _local_bh_enable_ip+0x38/0xa6()
[ 446.892306] Hardware name: MacBook1,1
[ 446.892309] Modules linked in: tcp_lp fuse sunrpc cpufreq_ondemand acpi_cpufreq mperf ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 nf_conntrack_ipv4 ip6table_filter nf_defrag_ipv4 xt_state nf_conntrack ip6_tables ext2 arc4 btusb bluetooth snd_hda_codec_idt snd_hda_intel carl9170 snd_hda_codec coretemp joydev ath5k snd_hwdep snd_seq isight_firmware ath snd_seq_device snd_pcm applesmc appletouch mac80211 input_polldev snd_timer microcode cfg80211 snd lpc_ich pcspkr i2c_i801 mfd_core soundcore rfkill snd_page_alloc sky2 tpm_infineon virtio_net kvm_intel kvm i915 drm_kms_helper drm i2c_algo_bit i2c_core video
[ 446.892385] Pid: 1892, comm: iw Not tainted 3.6.0-rc1-wl+ #296
[ 446.892387] Call Trace:
[ 446.892394] [<
c0432958>] warn_slowpath_common+0x7c/0x91
[ 446.892398] [<
c04399d7>] ? _local_bh_enable_ip+0x38/0xa6
[ 446.892403] [<
c04399d7>] ? _local_bh_enable_ip+0x38/0xa6
[ 446.892459] [<
f7f9ae3b>] ? mesh_sync_offset_adjust_tbtt+0x95/0x99 [mac80211]
[ 446.892464] [<
c043298f>] warn_slowpath_null+0x22/0x24
[ 446.892468] [<
c04399d7>] _local_bh_enable_ip+0x38/0xa6
[ 446.892473] [<
c0439a52>] local_bh_enable_ip+0xd/0xf
[ 446.892479] [<
c088004f>] _raw_spin_unlock_bh+0x34/0x37
[ 446.892527] [<
f7f9ae3b>] mesh_sync_offset_adjust_tbtt+0x95/0x99 [mac80211]
[ 446.892569] [<
f7f7650f>] ieee80211_beacon_get_tim+0x28f/0x4e0 [mac80211]
[ 446.892575] [<
c047ceeb>] ? trace_hardirqs_on_caller+0x10e/0x13f
[ 446.892591] [<
f7fdc541>] ath5k_beacon_update+0x40/0x26b [ath5k]
[ 446.892597] [<
c047ad67>] ? lock_acquired+0x1f5/0x21e
[ 446.892612] [<
f7fdf9fb>] ? ath5k_bss_info_changed+0x167/0x1b2 [ath5k]
[ 446.892617] [<
c087f9ea>] ? _raw_spin_lock_irqsave+0x78/0x82
[ 446.892632] [<
f7fdf9fb>] ? ath5k_bss_info_changed+0x167/0x1b2 [ath5k]
[ 446.892647] [<
f7fdfa09>] ath5k_bss_info_changed+0x175/0x1b2 [ath5k]
[ 446.892651] [<
c0479dd4>] ? lock_is_held+0x73/0x7b
[ 446.892662] [<
c0458fd5>] ? __might_sleep+0xa7/0x17a
[ 446.892698] [<
f7f5d8f7>] ieee80211_bss_info_change_notify+0x1ed/0x21a [mac80211]
[ 446.892703] [<
c0449875>] ? queue_work+0x24/0x32
[ 446.892718] [<
f7fdf894>] ? ath5k_configure_filter+0x163/0x163 [ath5k]
[ 446.892766] [<
f7f95fa4>] ieee80211_start_mesh+0xb9/0xbd [mac80211]
[ 446.892806] [<
f7f6e610>] ieee80211_join_mesh+0x10c/0x116 [mac80211]
[ 446.892834] [<
f7a96b90>] __cfg80211_join_mesh+0x176/0x1b3 [cfg80211]
[ 446.892855] [<
f7a96c1c>] cfg80211_join_mesh+0x4f/0x6a [cfg80211]
[ 446.892875] [<
f7a89891>] nl80211_join_mesh+0x1de/0x1ed [cfg80211]
[ 446.892908] [<
f7a8db99>] ? nl80211_set_wiphy+0x4cf/0x4cf [cfg80211]
[ 446.892919] [<
c07cfa36>] genl_rcv_msg+0x1d5/0x1f3
[ 446.892940] [<
c07cf861>] ? genl_rcv+0x25/0x25
[ 446.892946] [<
c07cf009>] netlink_rcv_skb+0x37/0x78
[ 446.892950] [<
c07cf85a>] genl_rcv+0x1e/0x25
[ 446.892955] [<
c07cebf3>] netlink_unicast+0xc3/0x12d
[ 446.892959] [<
c07cee46>] netlink_sendmsg+0x1e9/0x213
[ 446.892966] [<
c079f282>] sock_sendmsg+0x79/0x96
[ 446.892972] [<
c04eb90d>] ? might_fault+0x9d/0xa3
[ 446.892978] [<
c07a81d8>] ? copy_from_user+0x8/0xa
[ 446.892983] [<
c07a852c>] ? verify_iovec+0x43/0x77
[ 446.892987] [<
c079f4d8>] __sys_sendmsg+0x180/0x215
[ 446.892993] [<
c045f107>] ? sched_clock_cpu+0x134/0x144
[ 446.892997] [<
c047992f>] ? trace_hardirqs_off+0xb/0xd
[ 446.893002] [<
c047bf88>] ? __lock_acquire+0x46b/0xb6e
[ 446.893006] [<
c047992f>] ? trace_hardirqs_off+0xb/0xd
[ 446.893010] [<
c045f149>] ? local_clock+0x32/0x49
[ 446.893015] [<
c0479ec1>] ? lock_release_holdtime.part.9+0x4b/0x51
[ 446.893020] [<
c0479dd4>] ? lock_is_held+0x73/0x7b
[ 446.893025] [<
c050d127>] ? fcheck_files+0x97/0xcd
[ 446.893029] [<
c050d4df>] ? fget_light+0x2d/0x81
[ 446.893034] [<
c07a01f3>] sys_sendmsg+0x3b/0x52
[ 446.893038] [<
c07a07b4>] sys_socketcall+0x238/0x2a2
[ 446.893044] [<
c0885edf>] sysenter_do_call+0x12/0x38
[ 446.893047] ---[ end trace
a9af5998f929270f ]---
[ 447.627222]
[ 447.627232] =================================
[ 447.627237] [ INFO: inconsistent lock state ]
[ 447.627244] 3.6.0-rc1-wl+ #296 Tainted: G W
[ 447.627248] ---------------------------------
[ 447.627253] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
[ 447.627260] swapper/0/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
[ 447.627264] (&(&ah->block)->rlock){+.?...}, at: [<
f7fdd2d1>] ath5k_tasklet_beacon+0x91/0xa7 [ath5k]
[ 447.627299] {SOFTIRQ-ON-W} state was registered at:
[ 447.627304] [<
c047cdbf>] mark_held_locks+0x59/0x77
[ 447.627316] [<
c047ceeb>] trace_hardirqs_on_caller+0x10e/0x13f
[ 447.627324] [<
c047cf27>] trace_hardirqs_on+0xb/0xd
[ 447.627332] [<
c0439a3d>] _local_bh_enable_ip+0x9e/0xa6
[ 447.627342] [<
c0439a52>] local_bh_enable_ip+0xd/0xf
[ 447.627349] [<
c088004f>] _raw_spin_unlock_bh+0x34/0x37
[ 447.627359] [<
f7f9ae3b>] mesh_sync_offset_adjust_tbtt+0x95/0x99 [mac80211]
[ 447.627451] [<
f7f7650f>] ieee80211_beacon_get_tim+0x28f/0x4e0 [mac80211]
[ 447.627526] [<
f7fdc541>] ath5k_beacon_update+0x40/0x26b [ath5k]
[ 447.627547] [<
f7fdfa09>] ath5k_bss_info_changed+0x175/0x1b2 [ath5k]
[ 447.627569] [<
f7f5d8f7>] ieee80211_bss_info_change_notify+0x1ed/0x21a [mac80211]
[ 447.627628] [<
f7f95fa4>] ieee80211_start_mesh+0xb9/0xbd [mac80211]
[ 447.627712] [<
f7f6e610>] ieee80211_join_mesh+0x10c/0x116 [mac80211]
[ 447.627782] [<
f7a96b90>] __cfg80211_join_mesh+0x176/0x1b3 [cfg80211]
[ 447.627816] [<
f7a96c1c>] cfg80211_join_mesh+0x4f/0x6a [cfg80211]
[ 447.627845] [<
f7a89891>] nl80211_join_mesh+0x1de/0x1ed [cfg80211]
[ 447.627872] [<
c07cfa36>] genl_rcv_msg+0x1d5/0x1f3
[ 447.627881] [<
c07cf009>] netlink_rcv_skb+0x37/0x78
[ 447.627891] [<
c07cf85a>] genl_rcv+0x1e/0x25
[ 447.627898] [<
c07cebf3>] netlink_unicast+0xc3/0x12d
[ 447.627907] [<
c07cee46>] netlink_sendmsg+0x1e9/0x213
[ 447.627915] [<
c079f282>] sock_sendmsg+0x79/0x96
[ 447.627926] [<
c079f4d8>] __sys_sendmsg+0x180/0x215
[ 447.627934] [<
c07a01f3>] sys_sendmsg+0x3b/0x52
[ 447.627941] [<
c07a07b4>] sys_socketcall+0x238/0x2a2
[ 447.627949] [<
c0885edf>] sysenter_do_call+0x12/0x38
[ 447.627959] irq event stamp:
1929200
[ 447.627963] hardirqs last enabled at (
1929200): [<
c043a0e9>] tasklet_hi_action+0x3e/0xbf
[ 447.627972] hardirqs last disabled at (
1929199): [<
c043a0c0>] tasklet_hi_action+0x15/0xbf
[ 447.627981] softirqs last enabled at (
1929196): [<
c043999d>] _local_bh_enable+0x12/0x14
[ 447.627989] softirqs last disabled at (
1929197): [<
c040443b>] do_softirq+0x63/0xb8
[ 447.627999]
[ 447.627999] other info that might help us debug this:
[ 447.628004] Possible unsafe locking scenario:
[ 447.628004]
[ 447.628009] CPU0
[ 447.628012] ----
[ 447.628016] lock(&(&ah->block)->rlock);
[ 447.628023] <Interrupt>
[ 447.628027] lock(&(&ah->block)->rlock);
[ 447.628034]
[ 447.628034] *** DEADLOCK ***
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>