@@ -325,8 +325,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
ewma_init(&sta->chain_signal_avg[i], 1024, 8);
if (sta_prepare_rate_control(local, sta, gfp)) {
- kfree(sta);
- return NULL;
+ goto free_sta;
}
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
@@ -375,10 +374,15 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
tx_latency = rcu_dereference(local->tx_latency);
/* init stations Tx latency statistics && TID bins */
- if (tx_latency)
+ if (tx_latency) {
sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS *
sizeof(struct ieee80211_tx_latency_stat),
GFP_ATOMIC);
+ if (!sta->tx_lat) {
+ rcu_read_unlock();
+ goto free_rate_ctrl;
+ }
+ }
/*
* if Tx latency and bins are enabled and the previous allocation
@@ -392,12 +396,28 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta->tx_lat[i].bins = kcalloc(sta->tx_lat[i].bin_count,
sizeof(u32),
GFP_ATOMIC);
+ if (!sta->tx_lat[i].bins) {
+ rcu_read_unlock();
+ goto free_bins;
+ }
}
rcu_read_unlock();
sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
+ goto out;
+free_bins:
+ while (i > 0)
+ kfree(sta->tx_lat[--i].bins);
+ kfree(sta->tx_lat);
+free_rate_ctrl:
+ if (sta->rate_ctrl)
+ rate_control_free_sta(sta);
+free_sta:
+ kfree(sta);
+ sta = NULL;
+out:
return sta;
}
Signed-off-by: ZHAO Gang <gamerh2o@gmail.com> --- net/mac80211/sta_info.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-)