Commit ac100ce5 authored by Johannes Berg's avatar Johannes Berg

mac80211: duplicate station's MAC address for hash table

Currently, the station hash table lookup (or iteration) must
access two cachelines for each station - the one with the hash
table node, and the one with the MAC address.

Duplicate the MAC address next to the hash node to get rid of
this. Since the MAC address is static there's no consistency
problem introduced by this.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 981d94a8
...@@ -68,7 +68,7 @@ static const struct rhashtable_params sta_rht_params = { ...@@ -68,7 +68,7 @@ static const struct rhashtable_params sta_rht_params = {
.nelem_hint = 3, /* start small */ .nelem_hint = 3, /* start small */
.automatic_shrinking = true, .automatic_shrinking = true,
.head_offset = offsetof(struct sta_info, hash_node), .head_offset = offsetof(struct sta_info, hash_node),
.key_offset = offsetof(struct sta_info, sta.addr), .key_offset = offsetof(struct sta_info, addr),
.key_len = ETH_ALEN, .key_len = ETH_ALEN,
.hashfn = sta_addr_hash, .hashfn = sta_addr_hash,
.max_size = CONFIG_MAC80211_STA_HASH_MAX_SIZE, .max_size = CONFIG_MAC80211_STA_HASH_MAX_SIZE,
...@@ -320,6 +320,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, ...@@ -320,6 +320,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta->nonpeer_pm = NL80211_MESH_POWER_ACTIVE; sta->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
#endif #endif
memcpy(sta->addr, addr, ETH_ALEN);
memcpy(sta->sta.addr, addr, ETH_ALEN); memcpy(sta->sta.addr, addr, ETH_ALEN);
sta->local = local; sta->local = local;
sta->sdata = sdata; sta->sdata = sdata;
......
...@@ -278,6 +278,8 @@ struct ieee80211_fast_tx { ...@@ -278,6 +278,8 @@ struct ieee80211_fast_tx {
* @list: global linked list entry * @list: global linked list entry
* @free_list: list entry for keeping track of stations to free * @free_list: list entry for keeping track of stations to free
* @hash_node: hash node for rhashtable * @hash_node: hash node for rhashtable
* @addr: station's MAC address - duplicated from public part to
* let the hash table work with just a single cacheline
* @local: pointer to the global information * @local: pointer to the global information
* @sdata: virtual interface this station belongs to * @sdata: virtual interface this station belongs to
* @ptk: peer keys negotiated with this station, if any * @ptk: peer keys negotiated with this station, if any
...@@ -377,6 +379,7 @@ struct sta_info { ...@@ -377,6 +379,7 @@ struct sta_info {
struct list_head list, free_list; struct list_head list, free_list;
struct rcu_head rcu_head; struct rcu_head rcu_head;
struct rhash_head hash_node; struct rhash_head hash_node;
u8 addr[ETH_ALEN];
struct ieee80211_local *local; struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
...@@ -607,7 +610,7 @@ u32 sta_addr_hash(const void *key, u32 length, u32 seed); ...@@ -607,7 +610,7 @@ u32 sta_addr_hash(const void *key, u32 length, u32 seed);
_sta_bucket_idx(tbl, _addr), \ _sta_bucket_idx(tbl, _addr), \
hash_node) \ hash_node) \
/* compare address and run code only if it matches */ \ /* compare address and run code only if it matches */ \
if (ether_addr_equal(_sta->sta.addr, (_addr))) if (ether_addr_equal(_sta->addr, (_addr)))
/* /*
* Get STA info by index, BROKEN! * Get STA info by index, BROKEN!
......
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