Browse Source

mac80211: annotate station rcu dereferences

The new RCU lockdep support warns about these
in some contexts -- make it aware of the locks
used to protect all this. Different locks are
used in different contexts which unfortunately
means we can't get perfect checking.

Also remove rcu_dereference() from two places
that don't actually dereference the pointers.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Johannes Berg 15 years ago
parent
commit
0379185b6c
2 changed files with 18 additions and 6 deletions
  1. 2 2
      net/mac80211/main.c
  2. 16 4
      net/mac80211/sta_info.c

+ 2 - 2
net/mac80211/main.c

@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
 			switch (sdata->vif.type) {
 			switch (sdata->vif.type) {
 			case NL80211_IFTYPE_AP:
 			case NL80211_IFTYPE_AP:
 				sdata->vif.bss_conf.enable_beacon =
 				sdata->vif.bss_conf.enable_beacon =
-					!!rcu_dereference(sdata->u.ap.beacon);
+					!!sdata->u.ap.beacon;
 				break;
 				break;
 			case NL80211_IFTYPE_ADHOC:
 			case NL80211_IFTYPE_ADHOC:
 				sdata->vif.bss_conf.enable_beacon =
 				sdata->vif.bss_conf.enable_beacon =
-					!!rcu_dereference(sdata->u.ibss.presp);
+					!!sdata->u.ibss.presp;
 				break;
 				break;
 			case NL80211_IFTYPE_MESH_POINT:
 			case NL80211_IFTYPE_MESH_POINT:
 				sdata->vif.bss_conf.enable_beacon = true;
 				sdata->vif.bss_conf.enable_beacon = true;

+ 16 - 4
net/mac80211/sta_info.c

@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_local *local = sdata->local;
 	struct sta_info *sta;
 	struct sta_info *sta;
 
 
-	sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+	sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+				    rcu_read_lock_held() ||
+				    lockdep_is_held(&local->sta_lock) ||
+				    lockdep_is_held(&local->sta_mtx));
 	while (sta) {
 	while (sta) {
 		if (sta->sdata == sdata &&
 		if (sta->sdata == sdata &&
 		    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
 		    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
 			break;
 			break;
-		sta = rcu_dereference(sta->hnext);
+		sta = rcu_dereference_check(sta->hnext,
+					    rcu_read_lock_held() ||
+					    lockdep_is_held(&local->sta_lock) ||
+					    lockdep_is_held(&local->sta_mtx));
 	}
 	}
 	return sta;
 	return sta;
 }
 }
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_local *local = sdata->local;
 	struct sta_info *sta;
 	struct sta_info *sta;
 
 
-	sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+	sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+				    rcu_read_lock_held() ||
+				    lockdep_is_held(&local->sta_lock) ||
+				    lockdep_is_held(&local->sta_mtx));
 	while (sta) {
 	while (sta) {
 		if ((sta->sdata == sdata ||
 		if ((sta->sdata == sdata ||
 		     sta->sdata->bss == sdata->bss) &&
 		     sta->sdata->bss == sdata->bss) &&
 		    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
 		    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
 			break;
 			break;
-		sta = rcu_dereference(sta->hnext);
+		sta = rcu_dereference_check(sta->hnext,
+					    rcu_read_lock_held() ||
+					    lockdep_is_held(&local->sta_lock) ||
+					    lockdep_is_held(&local->sta_mtx));
 	}
 	}
 	return sta;
 	return sta;
 }
 }