diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-07-29 20:08:07 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-04 16:44:14 -0400 |
commit | 42935ecaf4e784d0815afa9a7e5fe7e141157ca3 (patch) | |
tree | dc0a0dcfff761e98d8a2a23a7edc8f9182c2774c /net/mac80211/mlme.c | |
parent | 64344d78228f6346a0462ba2d5fc03494aef4e6b (diff) |
mac80211: redefine usage of the mac80211 workqueue
The mac80211 workqueue exists to enable mac80211 and drivers
to queue their own work on a single threaded workqueue. mac80211
takes care to flush the workqueue during suspend but we never
really had requirements on drivers for how they should use
the workqueue in consideration for suspend.
We extend mac80211 to document how the mac80211 workqueue should
be used, how it should not be used and finally move raw access to
the workqueue to mac80211 only. Drivers and mac80211 use helpers
to queue work onto the mac80211 workqueue:
* ieee80211_queue_work()
* ieee80211_queue_delayed_work()
These helpers will now warn if mac80211 already completed its
suspend cycle and someone is trying to queue work. mac80211
flushes the mac80211 workqueue prior to suspend a few times,
but we haven't taken the care to ensure drivers won't add more
work after suspend. To help with this we add a warning when
someone tries to add work and mac80211 already completed the
suspend cycle.
Drivers should ensure they cancel any work or delayed work
in the mac80211 stop() callback.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ee83125ed179..0779ba150b26 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -565,7 +565,7 @@ static void ieee80211_chswitch_timer(unsigned long data) | |||
565 | return; | 565 | return; |
566 | } | 566 | } |
567 | 567 | ||
568 | queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); | 568 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); |
569 | } | 569 | } |
570 | 570 | ||
571 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 571 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
@@ -597,7 +597,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
597 | sdata->local->csa_channel = new_ch; | 597 | sdata->local->csa_channel = new_ch; |
598 | 598 | ||
599 | if (sw_elem->count <= 1) { | 599 | if (sw_elem->count <= 1) { |
600 | queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); | 600 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); |
601 | } else { | 601 | } else { |
602 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | 602 | ieee80211_stop_queues_by_reason(&sdata->local->hw, |
603 | IEEE80211_QUEUE_STOP_REASON_CSA); | 603 | IEEE80211_QUEUE_STOP_REASON_CSA); |
@@ -763,7 +763,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
763 | if (local->quiescing || local->suspended) | 763 | if (local->quiescing || local->suspended) |
764 | return; | 764 | return; |
765 | 765 | ||
766 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); | 766 | ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work); |
767 | } | 767 | } |
768 | 768 | ||
769 | /* MLME */ | 769 | /* MLME */ |
@@ -950,7 +950,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
950 | * due to work needing to be done. Hence, queue the STAs work | 950 | * due to work needing to be done. Hence, queue the STAs work |
951 | * again for that. | 951 | * again for that. |
952 | */ | 952 | */ |
953 | queue_work(local->hw.workqueue, &ifmgd->work); | 953 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
954 | return RX_MGMT_CFG80211_AUTH_TO; | 954 | return RX_MGMT_CFG80211_AUTH_TO; |
955 | } | 955 | } |
956 | 956 | ||
@@ -995,7 +995,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | |||
995 | * due to work needing to be done. Hence, queue the STAs work | 995 | * due to work needing to be done. Hence, queue the STAs work |
996 | * again for that. | 996 | * again for that. |
997 | */ | 997 | */ |
998 | queue_work(local->hw.workqueue, &ifmgd->work); | 998 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
999 | return RX_MGMT_CFG80211_AUTH_TO; | 999 | return RX_MGMT_CFG80211_AUTH_TO; |
1000 | } | 1000 | } |
1001 | 1001 | ||
@@ -1124,7 +1124,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata, | |||
1124 | * due to work needing to be done. Hence, queue the STAs work | 1124 | * due to work needing to be done. Hence, queue the STAs work |
1125 | * again for that. | 1125 | * again for that. |
1126 | */ | 1126 | */ |
1127 | queue_work(local->hw.workqueue, &ifmgd->work); | 1127 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
1128 | return RX_MGMT_CFG80211_ASSOC_TO; | 1128 | return RX_MGMT_CFG80211_ASSOC_TO; |
1129 | } | 1129 | } |
1130 | 1130 | ||
@@ -1232,8 +1232,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif) | |||
1232 | { | 1232 | { |
1233 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1233 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
1234 | 1234 | ||
1235 | queue_work(sdata->local->hw.workqueue, | 1235 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); |
1236 | &sdata->u.mgd.beacon_loss_work); | ||
1237 | } | 1236 | } |
1238 | EXPORT_SYMBOL(ieee80211_beacon_loss); | 1237 | EXPORT_SYMBOL(ieee80211_beacon_loss); |
1239 | 1238 | ||
@@ -1888,7 +1887,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1888 | case IEEE80211_STYPE_DISASSOC: | 1887 | case IEEE80211_STYPE_DISASSOC: |
1889 | case IEEE80211_STYPE_ACTION: | 1888 | case IEEE80211_STYPE_ACTION: |
1890 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); | 1889 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); |
1891 | queue_work(local->hw.workqueue, &sdata->u.mgd.work); | 1890 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
1892 | return RX_QUEUED; | 1891 | return RX_QUEUED; |
1893 | } | 1892 | } |
1894 | 1893 | ||
@@ -2026,7 +2025,7 @@ static void ieee80211_sta_timer(unsigned long data) | |||
2026 | return; | 2025 | return; |
2027 | } | 2026 | } |
2028 | 2027 | ||
2029 | queue_work(local->hw.workqueue, &ifmgd->work); | 2028 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
2030 | } | 2029 | } |
2031 | 2030 | ||
2032 | static void ieee80211_sta_work(struct work_struct *work) | 2031 | static void ieee80211_sta_work(struct work_struct *work) |
@@ -2051,13 +2050,11 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2051 | return; | 2050 | return; |
2052 | 2051 | ||
2053 | /* | 2052 | /* |
2054 | * Nothing should have been stuffed into the workqueue during | 2053 | * ieee80211_queue_work() should have picked up most cases, |
2055 | * the suspend->resume cycle. If this WARN is seen then there | 2054 | * here we'll pick the the rest. |
2056 | * is a bug with either the driver suspend or something in | ||
2057 | * mac80211 stuffing into the workqueue which we haven't yet | ||
2058 | * cleared during mac80211's suspend cycle. | ||
2059 | */ | 2055 | */ |
2060 | if (WARN_ON(local->suspended)) | 2056 | if (WARN(local->suspended, "STA MLME work scheduled while " |
2057 | "going to suspend\n")) | ||
2061 | return; | 2058 | return; |
2062 | 2059 | ||
2063 | ifmgd = &sdata->u.mgd; | 2060 | ifmgd = &sdata->u.mgd; |
@@ -2113,9 +2110,9 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2113 | mutex_unlock(&ifmgd->mtx); | 2110 | mutex_unlock(&ifmgd->mtx); |
2114 | 2111 | ||
2115 | if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) | 2112 | if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) |
2116 | queue_delayed_work(local->hw.workqueue, | 2113 | ieee80211_queue_delayed_work(&local->hw, |
2117 | &local->scan_work, | 2114 | &local->scan_work, |
2118 | round_jiffies_relative(0)); | 2115 | round_jiffies_relative(0)); |
2119 | return; | 2116 | return; |
2120 | } | 2117 | } |
2121 | 2118 | ||
@@ -2196,8 +2193,7 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) | |||
2196 | if (local->quiescing) | 2193 | if (local->quiescing) |
2197 | return; | 2194 | return; |
2198 | 2195 | ||
2199 | queue_work(sdata->local->hw.workqueue, | 2196 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); |
2200 | &sdata->u.mgd.beacon_loss_work); | ||
2201 | } | 2197 | } |
2202 | 2198 | ||
2203 | static void ieee80211_sta_conn_mon_timer(unsigned long data) | 2199 | static void ieee80211_sta_conn_mon_timer(unsigned long data) |
@@ -2210,7 +2206,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data) | |||
2210 | if (local->quiescing) | 2206 | if (local->quiescing) |
2211 | return; | 2207 | return; |
2212 | 2208 | ||
2213 | queue_work(local->hw.workqueue, &ifmgd->monitor_work); | 2209 | ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); |
2214 | } | 2210 | } |
2215 | 2211 | ||
2216 | static void ieee80211_sta_monitor_work(struct work_struct *work) | 2212 | static void ieee80211_sta_monitor_work(struct work_struct *work) |
@@ -2229,10 +2225,10 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | |||
2229 | IEEE80211_STA_CONNECTION_POLL); | 2225 | IEEE80211_STA_CONNECTION_POLL); |
2230 | 2226 | ||
2231 | /* let's probe the connection once */ | 2227 | /* let's probe the connection once */ |
2232 | queue_work(sdata->local->hw.workqueue, | 2228 | ieee80211_queue_work(&sdata->local->hw, |
2233 | &sdata->u.mgd.monitor_work); | 2229 | &sdata->u.mgd.monitor_work); |
2234 | /* and do all the other regular work too */ | 2230 | /* and do all the other regular work too */ |
2235 | queue_work(sdata->local->hw.workqueue, | 2231 | ieee80211_queue_work(&sdata->local->hw, |
2236 | &sdata->u.mgd.work); | 2232 | &sdata->u.mgd.work); |
2237 | } | 2233 | } |
2238 | } | 2234 | } |
@@ -2393,7 +2389,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2393 | list_add(&wk->list, &sdata->u.mgd.work_list); | 2389 | list_add(&wk->list, &sdata->u.mgd.work_list); |
2394 | mutex_unlock(&ifmgd->mtx); | 2390 | mutex_unlock(&ifmgd->mtx); |
2395 | 2391 | ||
2396 | queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); | 2392 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); |
2397 | return 0; | 2393 | return 0; |
2398 | } | 2394 | } |
2399 | 2395 | ||
@@ -2467,7 +2463,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2467 | else | 2463 | else |
2468 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; | 2464 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; |
2469 | 2465 | ||
2470 | queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); | 2466 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); |
2471 | 2467 | ||
2472 | err = 0; | 2468 | err = 0; |
2473 | 2469 | ||