Skip to content
  • Luis R. Rodriguez's avatar
    cfg80211: fix possible circular lock on reg_regdb_search() · a85d0d7f
    Luis R. Rodriguez authored
    
    
    When call_crda() is called we kick off a witch hunt search
    for the same regulatory domain on our internal regulatory
    database and that work gets kicked off on a workqueue, this
    is done while the cfg80211_mutex is held. If that workqueue
    kicks off it will first lock reg_regdb_search_mutex and
    later cfg80211_mutex but to ensure two CPUs will not contend
    against cfg80211_mutex the right thing to do is to have the
    reg_regdb_search() wait until the cfg80211_mutex is let go.
    
    The lockdep report is pasted below.
    
    cfg80211: Calling CRDA to update world regulatory domain
    
    ======================================================
    [ INFO: possible circular locking dependency detected ]
    3.3.8 #3 Tainted: G           O
    -------------------------------------------------------
    kworker/0:1/235 is trying to acquire lock:
     (cfg80211_mutex){+.+...}, at: [<816468a4>] set_regdom+0x78c/0x808 [cfg80211]
    
    but task is already holding lock:
     (reg_regdb_search_mutex){+.+...}, at: [<81646828>] set_regdom+0x710/0x808 [cfg80211]
    
    which lock already depends on the new lock.
    
    the existing dependency chain (in reverse order) is:
    
    -> #2 (reg_regdb_search_mutex){+.+...}:
           [<800a8384>] lock_acquire+0x60/0x88
           [<802950a8>] mutex_lock_nested+0x54/0x31c
           [<81645778>] is_world_regdom+0x9f8/0xc74 [cfg80211]
    
    -> #1 (reg_mutex#2){+.+...}:
           [<800a8384>] lock_acquire+0x60/0x88
           [<802950a8>] mutex_lock_nested+0x54/0x31c
           [<8164539c>] is_world_regdom+0x61c/0xc74 [cfg80211]
    
    -> #0 (cfg80211_mutex){+.+...}:
           [<800a77b8>] __lock_acquire+0x10d4/0x17bc
           [<800a8384>] lock_acquire+0x60/0x88
           [<802950a8>] mutex_lock_nested+0x54/0x31c
           [<816468a4>] set_regdom+0x78c/0x808 [cfg80211]
    
    other info that might help us debug this:
    
    Chain exists of:
      cfg80211_mutex --> reg_mutex#2 --> reg_regdb_search_mutex
    
     Possible unsafe locking scenario:
    
           CPU0                    CPU1
           ----                    ----
      lock(reg_regdb_search_mutex);
                                   lock(reg_mutex#2);
                                   lock(reg_regdb_search_mutex);
      lock(cfg80211_mutex);
    
     *** DEADLOCK ***
    
    3 locks held by kworker/0:1/235:
     #0:  (events){.+.+..}, at: [<80089a00>] process_one_work+0x230/0x460
     #1:  (reg_regdb_work){+.+...}, at: [<80089a00>] process_one_work+0x230/0x460
     #2:  (reg_regdb_search_mutex){+.+...}, at: [<81646828>] set_regdom+0x710/0x808 [cfg80211]
    
    stack backtrace:
    Call Trace:
    [<80290fd4>] dump_stack+0x8/0x34
    [<80291bc4>] print_circular_bug+0x2ac/0x2d8
    [<800a77b8>] __lock_acquire+0x10d4/0x17bc
    [<800a8384>] lock_acquire+0x60/0x88
    [<802950a8>] mutex_lock_nested+0x54/0x31c
    [<816468a4>] set_regdom+0x78c/0x808 [cfg80211]
    
    Reported-by: default avatarFelix Fietkau <nbd@openwrt.org>
    Tested-by: default avatarFelix Fietkau <nbd@openwrt.org>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarLuis R. Rodriguez <mcgrof@do-not-panic.com>
    Reviewed-by: default avatarJohannes Berg <johannes@sipsolutions.net>
    Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
    a85d0d7f