summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-06-16 16:22:12 +0200
committerJohannes Berg <johannes.berg@intel.com>2015-07-17 15:38:03 +0200
commitac100ce52a2d3b6261a06939d22e4382d9aa0bb2 (patch)
treeb61743db78d5d934803b70e73ce73a8eb035eded
parent981d94a80174e4f33bd5015fb49051bfc2eb00d2 (diff)
downloadlinux-sh-ac100ce52a2d3b6261a06939d22e4382d9aa0bb2.tar.gz
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: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/sta_info.c3
-rw-r--r--net/mac80211/sta_info.h5
2 files changed, 6 insertions, 2 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 666ddac3c87c..d573a499750e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -68,7 +68,7 @@ static const struct rhashtable_params sta_rht_params = {
.nelem_hint = 3, /* start small */
.automatic_shrinking = true,
.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,
.hashfn = sta_addr_hash,
.max_size = CONFIG_MAC80211_STA_HASH_MAX_SIZE,
@@ -320,6 +320,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
#endif
+ memcpy(sta->addr, addr, ETH_ALEN);
memcpy(sta->sta.addr, addr, ETH_ALEN);
sta->local = local;
sta->sdata = sdata;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index db76103b4445..422984986263 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -278,6 +278,8 @@ struct ieee80211_fast_tx {
* @list: global linked list entry
* @free_list: list entry for keeping track of stations to free
* @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
* @sdata: virtual interface this station belongs to
* @ptk: peer keys negotiated with this station, if any
@@ -377,6 +379,7 @@ struct sta_info {
struct list_head list, free_list;
struct rcu_head rcu_head;
struct rhash_head hash_node;
+ u8 addr[ETH_ALEN];
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
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);
_sta_bucket_idx(tbl, _addr), \
hash_node) \
/* 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!