aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-04-03 08:31:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-08 16:44:41 -0400
commit49ec6fa22028054f292c9c290415b88281f7b783 (patch)
tree1defae1fef6cdff58ae0420d4d269d721e5de364 /net
parentd8c17e159758c2a4f8c3319fe8a6cf313f7a6733 (diff)
mac80211: fix possible sta-debugfs work lockup
Because we queue the sta-debugfs-adding work on our mac80211 workqueue (which needs to be flushed under RTNL) and that work needs the RTNL, it can currently deadlock, thanks to Reinette Chatre for pointing out the lockdep warning about this. This patch fixes it by moving this work to the common kernel workqueue (using schedule_work) and canceling it as appropriate. It also fixes a related problem: When a STA is pinned by the debugfs adding work and sta_info_flush() runs concurrently it is not guaranteed that all STAs are removed from the driver before the corresponding interface is removed which may lead to bugs. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Cc: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/sta_info.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 7e1e87257647..bfdaf5c82f9d 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -351,7 +351,7 @@ int sta_info_insert(struct sta_info *sta)
351 * NOTE: due to auto-freeing semantics this may only be done 351 * NOTE: due to auto-freeing semantics this may only be done
352 * if the insertion is successful! 352 * if the insertion is successful!
353 */ 353 */
354 queue_work(local->hw.workqueue, &local->sta_debugfs_add); 354 schedule_work(&local->sta_debugfs_add);
355#endif 355#endif
356 356
357 if (ieee80211_vif_is_mesh(&sdata->vif)) 357 if (ieee80211_vif_is_mesh(&sdata->vif))
@@ -476,16 +476,23 @@ void __sta_info_unlink(struct sta_info **sta)
476 * 476 *
477 * The rules are not trivial, but not too complex either: 477 * The rules are not trivial, but not too complex either:
478 * (1) pin_status is only modified under the sta_lock 478 * (1) pin_status is only modified under the sta_lock
479 * (2) sta_info_debugfs_add_work() will set the status 479 * (2) STAs may only be pinned under the RTNL so that
480 * sta_info_flush() is guaranteed to actually destroy
481 * all STAs that are active for a given interface, this
482 * is required for correctness because otherwise we
483 * could notify a driver that an interface is going
484 * away and only after that (!) notify it about a STA
485 * on that interface going away.
486 * (3) sta_info_debugfs_add_work() will set the status
480 * to PINNED when it found an item that needs a new 487 * to PINNED when it found an item that needs a new
481 * debugfs directory created. In that case, that item 488 * debugfs directory created. In that case, that item
482 * must not be freed although all *RCU* users are done 489 * must not be freed although all *RCU* users are done
483 * with it. Hence, we tell the caller of _unlink() 490 * with it. Hence, we tell the caller of _unlink()
484 * that the item is already gone (as can happen when 491 * that the item is already gone (as can happen when
485 * two tasks try to unlink/destroy at the same time) 492 * two tasks try to unlink/destroy at the same time)
486 * (3) We set the pin_status to DESTROY here when we 493 * (4) We set the pin_status to DESTROY here when we
487 * find such an item. 494 * find such an item.
488 * (4) sta_info_debugfs_add_work() will reset the pin_status 495 * (5) sta_info_debugfs_add_work() will reset the pin_status
489 * from PINNED to NORMAL when it is done with the item, 496 * from PINNED to NORMAL when it is done with the item,
490 * but will check for DESTROY before resetting it in 497 * but will check for DESTROY before resetting it in
491 * which case it will free the item. 498 * which case it will free the item.
@@ -617,6 +624,8 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
617 struct sta_info *sta, *tmp; 624 struct sta_info *sta, *tmp;
618 unsigned long flags; 625 unsigned long flags;
619 626
627 /* We need to keep the RTNL across the whole pinned status. */
628 rtnl_lock();
620 while (1) { 629 while (1) {
621 sta = NULL; 630 sta = NULL;
622 631
@@ -637,10 +646,9 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
637 rate_control_add_sta_debugfs(sta); 646 rate_control_add_sta_debugfs(sta);
638 647
639 sta = __sta_info_unpin(sta); 648 sta = __sta_info_unpin(sta);
640 rtnl_lock();
641 sta_info_destroy(sta); 649 sta_info_destroy(sta);
642 rtnl_unlock();
643 } 650 }
651 rtnl_unlock();
644} 652}
645#endif 653#endif
646 654
@@ -700,6 +708,15 @@ void sta_info_stop(struct ieee80211_local *local)
700{ 708{
701 del_timer(&local->sta_cleanup); 709 del_timer(&local->sta_cleanup);
702 cancel_work_sync(&local->sta_flush_work); 710 cancel_work_sync(&local->sta_flush_work);
711#ifdef CONFIG_MAC80211_DEBUGFS
712 /*
713 * Make sure the debugfs adding work isn't pending after this
714 * because we're about to be destroyed. It doesn't matter
715 * whether it ran or not since we're going to flush all STAs
716 * anyway.
717 */
718 cancel_work_sync(&local->sta_debugfs_add);
719#endif
703 720
704 rtnl_lock(); 721 rtnl_lock();
705 sta_info_flush(local, NULL); 722 sta_info_flush(local, NULL);