• Bob Copeland's avatar
    ath5k: fix spin_lock_irqsave/spin_lock_bh nesting in mesh · 7dd6753f
    Bob Copeland authored
    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: default avatarBob Copeland <me@bobcopeland.com>
    Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
    7dd6753f
mac80211-ops.c 22 KB