cfg80211: fix possible circular lock on reg_regdb_search()

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.

Change-Id: Ibb44a5325876d77f1549d3938d56d8fbd051b9ba
CRs-Fixed: 655287
Signed-off-by: Santhosh Kumar Padma <skpadma@codeaurora.org>
This commit is contained in:
Luis R. Rodriguez 2014-04-29 11:44:45 +05:30 committed by Zhao Wei Liew
parent 886ccee9f7
commit 3ef1721715

View file

@ -340,6 +340,9 @@ static void reg_regdb_search(struct work_struct *work)
struct reg_regdb_search_request *request;
const struct ieee80211_regdomain *curdom, *regdom;
int i, r;
bool set_reg = false;
mutex_lock(&cfg80211_mutex);
mutex_lock(&reg_regdb_search_mutex);
while (!list_empty(&reg_regdb_search_list)) {
@ -355,9 +358,7 @@ static void reg_regdb_search(struct work_struct *work)
r = reg_copy_regd(&regdom, curdom);
if (r)
break;
mutex_lock(&cfg80211_mutex);
set_regdom(regdom);
mutex_unlock(&cfg80211_mutex);
set_reg = true;
break;
}
}
@ -365,6 +366,11 @@ static void reg_regdb_search(struct work_struct *work)
kfree(request);
}
mutex_unlock(&reg_regdb_search_mutex);
if (set_reg)
set_regdom(regdom);
mutex_unlock(&cfg80211_mutex);
}
static DECLARE_WORK(reg_regdb_work, reg_regdb_search);