mac80211: use rhashtable for station table
We currently have a hand-rolled table with 256 entries and are using the last byte of the MAC address as the hash. This hash is obviously very fast, but collisions are easily created and we waste a lot of space in the common case of just connecting as a client to an AP where we just have a single station. The other common case of an AP is also suboptimal due to the size of the hash table and the ease of causing collisions. Convert all of this to use rhashtable with jhash, which gives us the advantage of a far better hash function (with random perturbation to avoid hash collision attacks) and of course that the hash table grows and shrinks dynamically with chain length, improving both cases above. Use a specialised hash function (using jhash, but with fixed length) to achieve better compiler optimisation as suggested by Sergey Ryazanov. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -3423,7 +3423,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
__le16 fc;
|
||||
struct ieee80211_rx_data rx;
|
||||
struct ieee80211_sub_if_data *prev;
|
||||
struct sta_info *sta, *tmp, *prev_sta;
|
||||
struct sta_info *sta, *prev_sta;
|
||||
struct rhash_head *tmp;
|
||||
int err = 0;
|
||||
|
||||
fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
|
||||
@@ -3458,9 +3459,13 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
ieee80211_scan_rx(local, skb);
|
||||
|
||||
if (ieee80211_is_data(fc)) {
|
||||
const struct bucket_table *tbl;
|
||||
|
||||
prev_sta = NULL;
|
||||
|
||||
for_each_sta_info(local, hdr->addr2, sta, tmp) {
|
||||
tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
|
||||
|
||||
for_each_sta_info(local, tbl, hdr->addr2, sta, tmp) {
|
||||
if (!prev_sta) {
|
||||
prev_sta = sta;
|
||||
continue;
|
||||
|
Reference in New Issue
Block a user