mac80211: unify scan and work mutexes
authorJohannes Berg <johannes.berg@intel.com>
Fri, 30 Jul 2010 14:46:07 +0000 (16:46 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 16 Aug 2010 19:26:37 +0000 (15:26 -0400)
Having both scan and work mutexes is not just
a bit too fine grained, it also creates issues
when there's code that needs both since they
then need to be acquired in the right order,
which can be hard to do.

Therefore, use just a single mutex for both.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mlme.c
net/mac80211/scan.c
net/mac80211/work.c

index 79d56454484a7046350993200fb51c97662766da..fb4363e148f2e5685e740fa22ec27bb9b234f8b9 100644 (file)
@@ -634,7 +634,6 @@ struct ieee80211_local {
        /*
         * work stuff, potentially off-channel (in the future)
         */
-       struct mutex work_mtx;
        struct list_head work_list;
        struct timer_list work_timer;
        struct work_struct work_work;
@@ -746,9 +745,10 @@ struct ieee80211_local {
         */
        struct mutex key_mtx;
 
+       /* mutex for scan and work locking */
+       struct mutex mtx;
 
        /* Scanning and BSS list */
-       struct mutex scan_mtx;
        unsigned long scanning;
        struct cfg80211_ssid scan_ssid;
        struct cfg80211_scan_request *int_scan_req;
index 18b8df922c6073ddb03b530983a49890b2af8a23..06b9608a213075fa8e8d6c7c3693f2db78105684 100644 (file)
@@ -482,7 +482,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        __hw_addr_init(&local->mc_list);
 
        mutex_init(&local->iflist_mtx);
-       mutex_init(&local->scan_mtx);
+       mutex_init(&local->mtx);
 
        mutex_init(&local->key_mtx);
        spin_lock_init(&local->filter_lock);
@@ -791,7 +791,7 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
        struct ieee80211_local *local = hw_to_local(hw);
 
        mutex_destroy(&local->iflist_mtx);
-       mutex_destroy(&local->scan_mtx);
+       mutex_destroy(&local->mtx);
 
        wiphy_free(local->hw.wiphy);
 }
index b6c163ac22da39fd3327a30f77478e27cb81756c..17e9257a61d892fd89501681b04186e92aaa752c 100644 (file)
@@ -1751,7 +1751,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
                struct ieee80211_local *local = sdata->local;
                struct ieee80211_work *wk;
 
-               mutex_lock(&local->work_mtx);
+               mutex_lock(&local->mtx);
                list_for_each_entry(wk, &local->work_list, list) {
                        if (wk->sdata != sdata)
                                continue;
@@ -1783,7 +1783,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
                        free_work(wk);
                        break;
                }
-               mutex_unlock(&local->work_mtx);
+               mutex_unlock(&local->mtx);
 
                cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
        }
@@ -2275,7 +2275,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
 
                mutex_unlock(&ifmgd->mtx);
 
-               mutex_lock(&local->work_mtx);
+               mutex_lock(&local->mtx);
                list_for_each_entry(wk, &local->work_list, list) {
                        if (wk->sdata != sdata)
                                continue;
@@ -2294,7 +2294,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
                        free_work(wk);
                        break;
                }
-               mutex_unlock(&local->work_mtx);
+               mutex_unlock(&local->mtx);
 
                /*
                 * If somebody requests authentication and we haven't
index 872d7b6ef6b34f6dabdfbd0c491d94306d2fdf04..f31f549733b15895d84c98aecb4a11e089231eb3 100644 (file)
@@ -255,7 +255,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
 
        trace_api_scan_completed(local, aborted);
 
-       mutex_lock(&local->scan_mtx);
+       mutex_lock(&local->mtx);
 
        /*
         * It's ok to abort a not-yet-running scan (that
@@ -267,7 +267,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
                aborted = true;
 
        if (WARN_ON(!local->scan_req)) {
-               mutex_unlock(&local->scan_mtx);
+               mutex_unlock(&local->mtx);
                return;
        }
 
@@ -275,7 +275,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
        if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
                ieee80211_queue_delayed_work(&local->hw,
                                             &local->scan_work, 0);
-               mutex_unlock(&local->scan_mtx);
+               mutex_unlock(&local->mtx);
                return;
        }
 
@@ -291,7 +291,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
        local->scan_channel = NULL;
 
        /* we only have to protect scan_req and hw/sw scan */
-       mutex_unlock(&local->scan_mtx);
+       mutex_unlock(&local->mtx);
 
        ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
        if (was_hw_scan)
@@ -639,15 +639,15 @@ void ieee80211_scan_work(struct work_struct *work)
        struct ieee80211_sub_if_data *sdata = local->scan_sdata;
        unsigned long next_delay = 0;
 
-       mutex_lock(&local->scan_mtx);
+       mutex_lock(&local->mtx);
        if (!sdata || !local->scan_req) {
-               mutex_unlock(&local->scan_mtx);
+               mutex_unlock(&local->mtx);
                return;
        }
 
        if (local->hw_scan_req) {
                int rc = drv_hw_scan(local, sdata, local->hw_scan_req);
-               mutex_unlock(&local->scan_mtx);
+               mutex_unlock(&local->mtx);
                if (rc)
                        ieee80211_scan_completed(&local->hw, true);
                return;
@@ -661,14 +661,14 @@ void ieee80211_scan_work(struct work_struct *work)
                local->scan_sdata = NULL;
 
                rc = __ieee80211_start_scan(sdata, req);
-               mutex_unlock(&local->scan_mtx);
+               mutex_unlock(&local->mtx);
 
                if (rc)
                        ieee80211_scan_completed(&local->hw, true);
                return;
        }
 
-       mutex_unlock(&local->scan_mtx);
+       mutex_unlock(&local->mtx);
 
        /*
         * Avoid re-scheduling when the sdata is going away.
@@ -711,9 +711,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
 {
        int res;
 
-       mutex_lock(&sdata->local->scan_mtx);
+       mutex_lock(&sdata->local->mtx);
        res = __ieee80211_start_scan(sdata, req);
-       mutex_unlock(&sdata->local->scan_mtx);
+       mutex_unlock(&sdata->local->mtx);
 
        return res;
 }
@@ -726,7 +726,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
        int ret = -EBUSY;
        enum ieee80211_band band;
 
-       mutex_lock(&local->scan_mtx);
+       mutex_lock(&local->mtx);
 
        /* busy scanning */
        if (local->scan_req)
@@ -761,7 +761,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
 
        ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
  unlock:
-       mutex_unlock(&local->scan_mtx);
+       mutex_unlock(&local->mtx);
        return ret;
 }
 
@@ -775,10 +775,10 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
         * Only call this function when a scan can't be
         * queued -- mostly at suspend under RTNL.
         */
-       mutex_lock(&local->scan_mtx);
+       mutex_lock(&local->mtx);
        abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
                    (!local->scanning && local->scan_req);
-       mutex_unlock(&local->scan_mtx);
+       mutex_unlock(&local->mtx);
 
        if (abortscan)
                ieee80211_scan_completed(&local->hw, true);
index 81d4ad64184a2e76d35414586746fa6d03f8cf9d..b98af64f586279dbc60cef4c311420c668fc4b54 100644 (file)
@@ -43,7 +43,7 @@ enum work_action {
 /* utils */
 static inline void ASSERT_WORK_MTX(struct ieee80211_local *local)
 {
-       WARN_ON(!mutex_is_locked(&local->work_mtx));
+       lockdep_assert_held(&local->mtx);
 }
 
 /*
@@ -757,7 +757,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
        mgmt = (struct ieee80211_mgmt *) skb->data;
        fc = le16_to_cpu(mgmt->frame_control);
 
-       mutex_lock(&local->work_mtx);
+       mutex_lock(&local->mtx);
 
        list_for_each_entry(wk, &local->work_list, list) {
                const u8 *bssid = NULL;
@@ -833,7 +833,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
                WARN(1, "unexpected: %d", rma);
        }
 
-       mutex_unlock(&local->work_mtx);
+       mutex_unlock(&local->mtx);
 
        if (rma != WORK_ACT_DONE)
                goto out;
@@ -845,9 +845,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
        case WORK_DONE_REQUEUE:
                synchronize_rcu();
                wk->started = false; /* restart */
-               mutex_lock(&local->work_mtx);
+               mutex_lock(&local->mtx);
                list_add_tail(&wk->list, &local->work_list);
-               mutex_unlock(&local->work_mtx);
+               mutex_unlock(&local->mtx);
        }
 
  out:
@@ -890,7 +890,7 @@ static void ieee80211_work_work(struct work_struct *work)
 
        ieee80211_recalc_idle(local);
 
-       mutex_lock(&local->work_mtx);
+       mutex_lock(&local->mtx);
 
        list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
                bool started = wk->started;
@@ -995,17 +995,13 @@ static void ieee80211_work_work(struct work_struct *work)
                run_again(local, jiffies + HZ/2);
        }
 
-       mutex_lock(&local->scan_mtx);
-
        if (list_empty(&local->work_list) && local->scan_req &&
            !local->scanning)
                ieee80211_queue_delayed_work(&local->hw,
                                             &local->scan_work,
                                             round_jiffies_relative(0));
 
-       mutex_unlock(&local->scan_mtx);
-
-       mutex_unlock(&local->work_mtx);
+       mutex_unlock(&local->mtx);
 
        ieee80211_recalc_idle(local);
 
@@ -1035,16 +1031,15 @@ void ieee80211_add_work(struct ieee80211_work *wk)
        wk->started = false;
 
        local = wk->sdata->local;
-       mutex_lock(&local->work_mtx);
+       mutex_lock(&local->mtx);
        list_add_tail(&wk->list, &local->work_list);
-       mutex_unlock(&local->work_mtx);
+       mutex_unlock(&local->mtx);
 
        ieee80211_queue_work(&local->hw, &local->work_work);
 }
 
 void ieee80211_work_init(struct ieee80211_local *local)
 {
-       mutex_init(&local->work_mtx);
        INIT_LIST_HEAD(&local->work_list);
        setup_timer(&local->work_timer, ieee80211_work_timer,
                    (unsigned long)local);
@@ -1057,7 +1052,7 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_work *wk;
 
-       mutex_lock(&local->work_mtx);
+       mutex_lock(&local->mtx);
        list_for_each_entry(wk, &local->work_list, list) {
                if (wk->sdata != sdata)
                        continue;
@@ -1065,19 +1060,19 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
                wk->started = true;
                wk->timeout = jiffies;
        }
-       mutex_unlock(&local->work_mtx);
+       mutex_unlock(&local->mtx);
 
        /* run cleanups etc. */
        ieee80211_work_work(&local->work_work);
 
-       mutex_lock(&local->work_mtx);
+       mutex_lock(&local->mtx);
        list_for_each_entry(wk, &local->work_list, list) {
                if (wk->sdata != sdata)
                        continue;
                WARN_ON(1);
                break;
        }
-       mutex_unlock(&local->work_mtx);
+       mutex_unlock(&local->mtx);
 }
 
 ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
@@ -1163,7 +1158,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_work *wk, *tmp;
        bool found = false;
 
-       mutex_lock(&local->work_mtx);
+       mutex_lock(&local->mtx);
        list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
                if ((unsigned long) wk == cookie) {
                        wk->timeout = jiffies;
@@ -1171,7 +1166,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
                        break;
                }
        }
-       mutex_unlock(&local->work_mtx);
+       mutex_unlock(&local->mtx);
 
        if (!found)
                return -ENOENT;