mirror of
https://github.com/torvalds/linux
synced 2024-09-20 02:57:25 +00:00
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: ba6ddab94f
("wifi: mac80211: maintain link-sta hash table")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
9aebce6c97
commit
0ad49045f2
|
@ -358,7 +358,7 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
|
||||||
if (!(sta->sta.valid_links & BIT(i)))
|
if (!(sta->sta.valid_links & BIT(i)))
|
||||||
continue;
|
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;
|
return 0;
|
||||||
out_remove:
|
out_remove:
|
||||||
|
if (sta->sta.valid_links)
|
||||||
|
link_sta_info_hash_del(local, &sta->deflink);
|
||||||
sta_info_hash_del(local, sta);
|
sta_info_hash_del(local, sta);
|
||||||
list_del_rcu(&sta->list);
|
list_del_rcu(&sta->list);
|
||||||
out_drop_sta:
|
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_local *local;
|
||||||
struct ieee80211_sub_if_data *sdata;
|
struct ieee80211_sub_if_data *sdata;
|
||||||
int ret;
|
int ret, i;
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
|
@ -1168,6 +1170,18 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
|
||||||
*/
|
*/
|
||||||
drv_sync_rx_queues(local, 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);
|
ret = sta_info_hash_del(local, sta);
|
||||||
if (WARN_ON(ret))
|
if (WARN_ON(ret))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in a new issue