Commit 0f5ffd24 authored by Bob Copeland's avatar Bob Copeland Committed by Johannes Berg

mac80211: hold sta->lock across plink switch statements

Rather than unlock at the end of each case, do it once after
all is said and done.
Signed-off-by: default avatarBob Copeland <bob@cozybit.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 4efec451
...@@ -575,7 +575,6 @@ static void mesh_plink_timer(unsigned long data) ...@@ -575,7 +575,6 @@ static void mesh_plink_timer(unsigned long data)
rand % sta->plink_timeout; rand % sta->plink_timeout;
++sta->plink_retries; ++sta->plink_retries;
mod_plink_timer(sta, sta->plink_timeout); mod_plink_timer(sta, sta->plink_timeout);
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_OPEN; action = WLAN_SP_MESH_PEERING_OPEN;
break; break;
} }
...@@ -587,19 +586,17 @@ static void mesh_plink_timer(unsigned long data) ...@@ -587,19 +586,17 @@ static void mesh_plink_timer(unsigned long data)
reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
sta->plink_state = NL80211_PLINK_HOLDING; sta->plink_state = NL80211_PLINK_HOLDING;
mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_CLOSE; action = WLAN_SP_MESH_PEERING_CLOSE;
break; break;
case NL80211_PLINK_HOLDING: case NL80211_PLINK_HOLDING:
/* holding timer */ /* holding timer */
del_timer(&sta->plink_timer); del_timer(&sta->plink_timer);
mesh_plink_fsm_restart(sta); mesh_plink_fsm_restart(sta);
spin_unlock_bh(&sta->lock);
break; break;
default: default:
spin_unlock_bh(&sta->lock);
break; break;
} }
spin_unlock_bh(&sta->lock);
if (action) if (action)
mesh_plink_frame_tx(sdata, action, sta->sta.addr, mesh_plink_frame_tx(sdata, action, sta->sta.addr,
llid, plid, reason); llid, plid, reason);
...@@ -856,12 +853,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -856,12 +853,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
reason = 0; reason = 0;
spin_lock_bh(&sta->lock); spin_lock_bh(&sta->lock);
switch (sta->plink_state) { switch (sta->plink_state) {
/* spin_unlock as soon as state is updated at each case */
case NL80211_PLINK_LISTEN: case NL80211_PLINK_LISTEN:
switch (event) { switch (event) {
case CLS_ACPT: case CLS_ACPT:
mesh_plink_fsm_restart(sta); mesh_plink_fsm_restart(sta);
spin_unlock_bh(&sta->lock);
break; break;
case OPN_ACPT: case OPN_ACPT:
sta->plink_state = NL80211_PLINK_OPN_RCVD; sta->plink_state = NL80211_PLINK_OPN_RCVD;
...@@ -874,11 +869,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -874,11 +869,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
/* set the non-peer mode to active during peering */ /* set the non-peer mode to active during peering */
changed |= ieee80211_mps_local_status_update(sdata); changed |= ieee80211_mps_local_status_update(sdata);
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_OPEN; action = WLAN_SP_MESH_PEERING_OPEN;
break; break;
default: default:
spin_unlock_bh(&sta->lock);
break; break;
} }
break; break;
...@@ -897,14 +890,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -897,14 +890,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
mshcfg->dot11MeshHoldingTimeout)) mshcfg->dot11MeshHoldingTimeout))
sta->ignore_plink_timer = true; sta->ignore_plink_timer = true;
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_CLOSE; action = WLAN_SP_MESH_PEERING_CLOSE;
break; break;
case OPN_ACPT: case OPN_ACPT:
/* retry timer is left untouched */ /* retry timer is left untouched */
sta->plink_state = NL80211_PLINK_OPN_RCVD; sta->plink_state = NL80211_PLINK_OPN_RCVD;
sta->plid = plid; sta->plid = plid;
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_CONFIRM; action = WLAN_SP_MESH_PEERING_CONFIRM;
break; break;
case CNF_ACPT: case CNF_ACPT:
...@@ -913,10 +904,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -913,10 +904,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
mshcfg->dot11MeshConfirmTimeout)) mshcfg->dot11MeshConfirmTimeout))
sta->ignore_plink_timer = true; sta->ignore_plink_timer = true;
spin_unlock_bh(&sta->lock);
break; break;
default: default:
spin_unlock_bh(&sta->lock);
break; break;
} }
break; break;
...@@ -935,17 +924,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -935,17 +924,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
mshcfg->dot11MeshHoldingTimeout)) mshcfg->dot11MeshHoldingTimeout))
sta->ignore_plink_timer = true; sta->ignore_plink_timer = true;
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_CLOSE; action = WLAN_SP_MESH_PEERING_CLOSE;
break; break;
case OPN_ACPT: case OPN_ACPT:
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_CONFIRM; action = WLAN_SP_MESH_PEERING_CONFIRM;
break; break;
case CNF_ACPT: case CNF_ACPT:
del_timer(&sta->plink_timer); del_timer(&sta->plink_timer);
sta->plink_state = NL80211_PLINK_ESTAB; sta->plink_state = NL80211_PLINK_ESTAB;
spin_unlock_bh(&sta->lock);
changed |= mesh_plink_inc_estab_count(sdata); changed |= mesh_plink_inc_estab_count(sdata);
changed |= mesh_set_ht_prot_mode(sdata); changed |= mesh_set_ht_prot_mode(sdata);
changed |= mesh_set_short_slot_time(sdata); changed |= mesh_set_short_slot_time(sdata);
...@@ -956,7 +942,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -956,7 +942,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
mshcfg->power_mode); mshcfg->power_mode);
break; break;
default: default:
spin_unlock_bh(&sta->lock);
break; break;
} }
break; break;
...@@ -975,13 +960,11 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -975,13 +960,11 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
mshcfg->dot11MeshHoldingTimeout)) mshcfg->dot11MeshHoldingTimeout))
sta->ignore_plink_timer = true; sta->ignore_plink_timer = true;
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_CLOSE; action = WLAN_SP_MESH_PEERING_CLOSE;
break; break;
case OPN_ACPT: case OPN_ACPT:
del_timer(&sta->plink_timer); del_timer(&sta->plink_timer);
sta->plink_state = NL80211_PLINK_ESTAB; sta->plink_state = NL80211_PLINK_ESTAB;
spin_unlock_bh(&sta->lock);
changed |= mesh_plink_inc_estab_count(sdata); changed |= mesh_plink_inc_estab_count(sdata);
changed |= mesh_set_ht_prot_mode(sdata); changed |= mesh_set_ht_prot_mode(sdata);
changed |= mesh_set_short_slot_time(sdata); changed |= mesh_set_short_slot_time(sdata);
...@@ -993,7 +976,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -993,7 +976,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
mshcfg->power_mode); mshcfg->power_mode);
break; break;
default: default:
spin_unlock_bh(&sta->lock);
break; break;
} }
break; break;
...@@ -1006,17 +988,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -1006,17 +988,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
changed |= __mesh_plink_deactivate(sta); changed |= __mesh_plink_deactivate(sta);
sta->plink_state = NL80211_PLINK_HOLDING; sta->plink_state = NL80211_PLINK_HOLDING;
mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
spin_unlock_bh(&sta->lock);
changed |= mesh_set_ht_prot_mode(sdata); changed |= mesh_set_ht_prot_mode(sdata);
changed |= mesh_set_short_slot_time(sdata); changed |= mesh_set_short_slot_time(sdata);
action = WLAN_SP_MESH_PEERING_CLOSE; action = WLAN_SP_MESH_PEERING_CLOSE;
break; break;
case OPN_ACPT: case OPN_ACPT:
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_CONFIRM; action = WLAN_SP_MESH_PEERING_CONFIRM;
break; break;
default: default:
spin_unlock_bh(&sta->lock);
break; break;
} }
break; break;
...@@ -1026,26 +1005,24 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, ...@@ -1026,26 +1005,24 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
if (del_timer(&sta->plink_timer)) if (del_timer(&sta->plink_timer))
sta->ignore_plink_timer = 1; sta->ignore_plink_timer = 1;
mesh_plink_fsm_restart(sta); mesh_plink_fsm_restart(sta);
spin_unlock_bh(&sta->lock);
break; break;
case OPN_ACPT: case OPN_ACPT:
case CNF_ACPT: case CNF_ACPT:
case OPN_RJCT: case OPN_RJCT:
case CNF_RJCT: case CNF_RJCT:
spin_unlock_bh(&sta->lock);
action = WLAN_SP_MESH_PEERING_CLOSE; action = WLAN_SP_MESH_PEERING_CLOSE;
break; break;
default: default:
spin_unlock_bh(&sta->lock); break;
} }
break; break;
default: default:
/* should not get here, PLINK_BLOCKED is dealt with at the /* should not get here, PLINK_BLOCKED is dealt with at the
* beginning of the function * beginning of the function
*/ */
spin_unlock_bh(&sta->lock);
break; break;
} }
spin_unlock_bh(&sta->lock);
if (action) { if (action) {
mesh_plink_frame_tx(sdata, action, sta->sta.addr, mesh_plink_frame_tx(sdata, action, sta->sta.addr,
sta->llid, sta->plid, sta->reason); sta->llid, sta->plid, sta->reason);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment