Commit 0ad49045 authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: fix link sta hash table handling

There are two issues here: we unhash the link stations only
directly before freeing the station they belong to, and we
also don't unhash all the links correctly in all cases. Fix
these issues.

Fixes: ba6ddab9 ("wifi: mac80211: maintain link-sta hash table")
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9aebce6c
......@@ -358,7 +358,7 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
if (!(sta->sta.valid_links & BIT(i)))
continue;
sta_remove_link(sta, i, true);
sta_remove_link(sta, i, false);
}
/*
......@@ -846,6 +846,8 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
return 0;
out_remove:
if (sta->sta.valid_links)
link_sta_info_hash_del(local, &sta->deflink);
sta_info_hash_del(local, sta);
list_del_rcu(&sta->list);
out_drop_sta:
......@@ -1140,7 +1142,7 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
{
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
int ret;
int ret, i;
might_sleep();
......@@ -1168,6 +1170,18 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
*/
drv_sync_rx_queues(local, sta);
for (i = 0; i < ARRAY_SIZE(sta->link); i++) {
struct link_sta_info *link_sta;
if (!(sta->sta.valid_links & BIT(i)))
continue;
link_sta = rcu_dereference_protected(sta->link[i],
lockdep_is_held(&local->sta_mtx));
link_sta_info_hash_del(local, link_sta);
}
ret = sta_info_hash_del(local, sta);
if (WARN_ON(ret))
return ret;
......
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