diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-03-16 15:40:59 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-30 15:37:20 -0400 |
commit | 368d06f5b0eefcbf37d677d3b65381310a251f03 (patch) | |
tree | e8e05e1e6a34583f31203c29c03dcf9f6c036aeb /net/wireless | |
parent | c8406ea8fa1adde8dc5400127281d497bbcdb84a (diff) |
wireless: convert reg_regdb_search_lock to mutex
Stanse discovered that kmalloc is being called with GFP_KERNEL while
holding this spinlock. The spinlock can be a mutex instead, which also
enables the removal of the unlock/lock around the lock/unlock of
cfg80211_mutex and the call to set_regdom.
Reported-by: Jiri Slaby <jirislaby@gmail.com>
Cc: stable@kernel.org
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/reg.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index ed89c59bb431..81fcafc60150 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -324,7 +324,7 @@ struct reg_regdb_search_request { | |||
324 | }; | 324 | }; |
325 | 325 | ||
326 | static LIST_HEAD(reg_regdb_search_list); | 326 | static LIST_HEAD(reg_regdb_search_list); |
327 | static DEFINE_SPINLOCK(reg_regdb_search_lock); | 327 | static DEFINE_MUTEX(reg_regdb_search_mutex); |
328 | 328 | ||
329 | static void reg_regdb_search(struct work_struct *work) | 329 | static void reg_regdb_search(struct work_struct *work) |
330 | { | 330 | { |
@@ -332,7 +332,7 @@ static void reg_regdb_search(struct work_struct *work) | |||
332 | const struct ieee80211_regdomain *curdom, *regdom; | 332 | const struct ieee80211_regdomain *curdom, *regdom; |
333 | int i, r; | 333 | int i, r; |
334 | 334 | ||
335 | spin_lock(®_regdb_search_lock); | 335 | mutex_lock(®_regdb_search_mutex); |
336 | while (!list_empty(®_regdb_search_list)) { | 336 | while (!list_empty(®_regdb_search_list)) { |
337 | request = list_first_entry(®_regdb_search_list, | 337 | request = list_first_entry(®_regdb_search_list, |
338 | struct reg_regdb_search_request, | 338 | struct reg_regdb_search_request, |
@@ -346,18 +346,16 @@ static void reg_regdb_search(struct work_struct *work) | |||
346 | r = reg_copy_regd(®dom, curdom); | 346 | r = reg_copy_regd(®dom, curdom); |
347 | if (r) | 347 | if (r) |
348 | break; | 348 | break; |
349 | spin_unlock(®_regdb_search_lock); | ||
350 | mutex_lock(&cfg80211_mutex); | 349 | mutex_lock(&cfg80211_mutex); |
351 | set_regdom(regdom); | 350 | set_regdom(regdom); |
352 | mutex_unlock(&cfg80211_mutex); | 351 | mutex_unlock(&cfg80211_mutex); |
353 | spin_lock(®_regdb_search_lock); | ||
354 | break; | 352 | break; |
355 | } | 353 | } |
356 | } | 354 | } |
357 | 355 | ||
358 | kfree(request); | 356 | kfree(request); |
359 | } | 357 | } |
360 | spin_unlock(®_regdb_search_lock); | 358 | mutex_unlock(®_regdb_search_mutex); |
361 | } | 359 | } |
362 | 360 | ||
363 | static DECLARE_WORK(reg_regdb_work, reg_regdb_search); | 361 | static DECLARE_WORK(reg_regdb_work, reg_regdb_search); |
@@ -375,9 +373,9 @@ static void reg_regdb_query(const char *alpha2) | |||
375 | 373 | ||
376 | memcpy(request->alpha2, alpha2, 2); | 374 | memcpy(request->alpha2, alpha2, 2); |
377 | 375 | ||
378 | spin_lock(®_regdb_search_lock); | 376 | mutex_lock(®_regdb_search_mutex); |
379 | list_add_tail(&request->list, ®_regdb_search_list); | 377 | list_add_tail(&request->list, ®_regdb_search_list); |
380 | spin_unlock(®_regdb_search_lock); | 378 | mutex_unlock(®_regdb_search_mutex); |
381 | 379 | ||
382 | schedule_work(®_regdb_work); | 380 | schedule_work(®_regdb_work); |
383 | } | 381 | } |