ath10k-ct: depend on kmod-hwmon-core, it gets used when CONFIG_THERMAL is set
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / 312-mac80211-Use-rhltable-instead-of-rhashtable.patch
1 From: Herbert Xu <herbert@gondor.apana.org.au>
2 Date: Mon, 19 Sep 2016 19:00:10 +0800
3 Subject: [PATCH] mac80211: Use rhltable instead of rhashtable
4
5 mac80211 currently uses rhashtable with insecure_elasticity set
6 to true. The latter is because of duplicate objects. What's
7 more, mac80211 walks the rhashtable chains by hand which is broken
8 as rhashtable may contain multiple tables due to resizing or
9 rehashing.
10
11 This patch fixes it by converting it to the newly added rhltable
12 interface which is designed for use with duplicate objects.
13
14 With rhltable a lookup returns a list of objects instead of a
15 single one. This is then fed into the existing for_each_sta_info
16 macro.
17
18 This patch also deletes the sta_addr_hash function since rhashtable
19 defaults to jhash.
20
21 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
22 ---
23
24 --- a/net/mac80211/ieee80211_i.h
25 +++ b/net/mac80211/ieee80211_i.h
26 @@ -1233,7 +1233,7 @@ struct ieee80211_local {
27 spinlock_t tim_lock;
28 unsigned long num_sta;
29 struct list_head sta_list;
30 - struct rhashtable sta_hash;
31 + struct rhltable sta_hash;
32 struct timer_list sta_cleanup;
33 int sta_generation;
34
35 --- a/net/mac80211/rx.c
36 +++ b/net/mac80211/rx.c
37 @@ -4004,7 +4004,7 @@ static void __ieee80211_rx_handle_packet
38 __le16 fc;
39 struct ieee80211_rx_data rx;
40 struct ieee80211_sub_if_data *prev;
41 - struct rhash_head *tmp;
42 + struct rhlist_head *tmp;
43 int err = 0;
44
45 fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
46 @@ -4047,13 +4047,10 @@ static void __ieee80211_rx_handle_packet
47 goto out;
48 } else if (ieee80211_is_data(fc)) {
49 struct sta_info *sta, *prev_sta;
50 - const struct bucket_table *tbl;
51
52 prev_sta = NULL;
53
54 - tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
55 -
56 - for_each_sta_info(local, tbl, hdr->addr2, sta, tmp) {
57 + for_each_sta_info(local, hdr->addr2, sta, tmp) {
58 if (!prev_sta) {
59 prev_sta = sta;
60 continue;
61 --- a/net/mac80211/sta_info.c
62 +++ b/net/mac80211/sta_info.c
63 @@ -67,12 +67,10 @@
64
65 static const struct rhashtable_params sta_rht_params = {
66 .nelem_hint = 3, /* start small */
67 - .insecure_elasticity = true, /* Disable chain-length checks. */
68 .automatic_shrinking = true,
69 .head_offset = offsetof(struct sta_info, hash_node),
70 .key_offset = offsetof(struct sta_info, addr),
71 .key_len = ETH_ALEN,
72 - .hashfn = sta_addr_hash,
73 .max_size = CPTCFG_MAC80211_STA_HASH_MAX_SIZE,
74 };
75
76 @@ -80,8 +78,8 @@ static const struct rhashtable_params st
77 static int sta_info_hash_del(struct ieee80211_local *local,
78 struct sta_info *sta)
79 {
80 - return rhashtable_remove_fast(&local->sta_hash, &sta->hash_node,
81 - sta_rht_params);
82 + return rhltable_remove(&local->sta_hash, &sta->hash_node,
83 + sta_rht_params);
84 }
85
86 static void __cleanup_single_sta(struct sta_info *sta)
87 @@ -157,19 +155,22 @@ static void cleanup_single_sta(struct st
88 sta_info_free(local, sta);
89 }
90
91 +struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local,
92 + const u8 *addr)
93 +{
94 + return rhltable_lookup(&local->sta_hash, addr, sta_rht_params);
95 +}
96 +
97 /* protected by RCU */
98 struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
99 const u8 *addr)
100 {
101 struct ieee80211_local *local = sdata->local;
102 + struct rhlist_head *tmp;
103 struct sta_info *sta;
104 - struct rhash_head *tmp;
105 - const struct bucket_table *tbl;
106
107 rcu_read_lock();
108 - tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
109 -
110 - for_each_sta_info(local, tbl, addr, sta, tmp) {
111 + for_each_sta_info(local, addr, sta, tmp) {
112 if (sta->sdata == sdata) {
113 rcu_read_unlock();
114 /* this is safe as the caller must already hold
115 @@ -190,14 +191,11 @@ struct sta_info *sta_info_get_bss(struct
116 const u8 *addr)
117 {
118 struct ieee80211_local *local = sdata->local;
119 + struct rhlist_head *tmp;
120 struct sta_info *sta;
121 - struct rhash_head *tmp;
122 - const struct bucket_table *tbl;
123
124 rcu_read_lock();
125 - tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
126 -
127 - for_each_sta_info(local, tbl, addr, sta, tmp) {
128 + for_each_sta_info(local, addr, sta, tmp) {
129 if (sta->sdata == sdata ||
130 (sta->sdata->bss && sta->sdata->bss == sdata->bss)) {
131 rcu_read_unlock();
132 @@ -263,8 +261,8 @@ void sta_info_free(struct ieee80211_loca
133 static int sta_info_hash_add(struct ieee80211_local *local,
134 struct sta_info *sta)
135 {
136 - return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
137 - sta_rht_params);
138 + return rhltable_insert(&local->sta_hash, &sta->hash_node,
139 + sta_rht_params);
140 }
141
142 static void sta_deliver_ps_frames(struct work_struct *wk)
143 @@ -453,9 +451,9 @@ static int sta_info_insert_check(struct
144 is_multicast_ether_addr(sta->sta.addr)))
145 return -EINVAL;
146
147 - /* Strictly speaking this isn't necessary as we hold the mutex, but
148 - * the rhashtable code can't really deal with that distinction. We
149 - * do require the mutex for correctness though.
150 + /* The RCU read lock is required by rhashtable due to
151 + * asynchronous resize/rehash. We also require the mutex
152 + * for correctness.
153 */
154 rcu_read_lock();
155 lockdep_assert_held(&sdata->local->sta_mtx);
156 @@ -1043,16 +1041,11 @@ static void sta_info_cleanup(unsigned lo
157 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL));
158 }
159
160 -u32 sta_addr_hash(const void *key, u32 length, u32 seed)
161 -{
162 - return jhash(key, ETH_ALEN, seed);
163 -}
164 -
165 int sta_info_init(struct ieee80211_local *local)
166 {
167 int err;
168
169 - err = rhashtable_init(&local->sta_hash, &sta_rht_params);
170 + err = rhltable_init(&local->sta_hash, &sta_rht_params);
171 if (err)
172 return err;
173
174 @@ -1068,7 +1061,7 @@ int sta_info_init(struct ieee80211_local
175 void sta_info_stop(struct ieee80211_local *local)
176 {
177 del_timer_sync(&local->sta_cleanup);
178 - rhashtable_destroy(&local->sta_hash);
179 + rhltable_destroy(&local->sta_hash);
180 }
181
182
183 @@ -1138,17 +1131,14 @@ struct ieee80211_sta *ieee80211_find_sta
184 const u8 *localaddr)
185 {
186 struct ieee80211_local *local = hw_to_local(hw);
187 + struct rhlist_head *tmp;
188 struct sta_info *sta;
189 - struct rhash_head *tmp;
190 - const struct bucket_table *tbl;
191 -
192 - tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
193
194 /*
195 * Just return a random station if localaddr is NULL
196 * ... first in list.
197 */
198 - for_each_sta_info(local, tbl, addr, sta, tmp) {
199 + for_each_sta_info(local, addr, sta, tmp) {
200 if (localaddr &&
201 !ether_addr_equal(sta->sdata->vif.addr, localaddr))
202 continue;
203 --- a/net/mac80211/sta_info.h
204 +++ b/net/mac80211/sta_info.h
205 @@ -455,7 +455,7 @@ struct sta_info {
206 /* General information, mostly static */
207 struct list_head list, free_list;
208 struct rcu_head rcu_head;
209 - struct rhash_head hash_node;
210 + struct rhlist_head hash_node;
211 u8 addr[ETH_ALEN];
212 struct ieee80211_local *local;
213 struct ieee80211_sub_if_data *sdata;
214 @@ -638,6 +638,9 @@ rcu_dereference_protected_tid_tx(struct
215 */
216 #define STA_INFO_CLEANUP_INTERVAL (10 * HZ)
217
218 +struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local,
219 + const u8 *addr);
220 +
221 /*
222 * Get a STA info, must be under RCU read lock.
223 */
224 @@ -647,17 +650,9 @@ struct sta_info *sta_info_get(struct iee
225 struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
226 const u8 *addr);
227
228 -u32 sta_addr_hash(const void *key, u32 length, u32 seed);
229 -
230 -#define _sta_bucket_idx(_tbl, _a) \
231 - rht_bucket_index(_tbl, sta_addr_hash(_a, ETH_ALEN, (_tbl)->hash_rnd))
232 -
233 -#define for_each_sta_info(local, tbl, _addr, _sta, _tmp) \
234 - rht_for_each_entry_rcu(_sta, _tmp, tbl, \
235 - _sta_bucket_idx(tbl, _addr), \
236 - hash_node) \
237 - /* compare address and run code only if it matches */ \
238 - if (ether_addr_equal(_sta->addr, (_addr)))
239 +#define for_each_sta_info(local, _addr, _sta, _tmp) \
240 + rhl_for_each_entry_rcu(_sta, _tmp, \
241 + sta_info_hash_lookup(local, _addr), hash_node)
242
243 /*
244 * Get STA info by index, BROKEN!
245 --- a/net/mac80211/status.c
246 +++ b/net/mac80211/status.c
247 @@ -759,8 +759,8 @@ void ieee80211_tx_status(struct ieee8021
248 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
249 __le16 fc;
250 struct ieee80211_supported_band *sband;
251 + struct rhlist_head *tmp;
252 struct sta_info *sta;
253 - struct rhash_head *tmp;
254 int retry_count;
255 int rates_idx;
256 bool send_to_cooked;
257 @@ -768,7 +768,6 @@ void ieee80211_tx_status(struct ieee8021
258 struct ieee80211_bar *bar;
259 int shift = 0;
260 int tid = IEEE80211_NUM_TIDS;
261 - const struct bucket_table *tbl;
262
263 rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
264
265 @@ -777,9 +776,7 @@ void ieee80211_tx_status(struct ieee8021
266 sband = local->hw.wiphy->bands[info->band];
267 fc = hdr->frame_control;
268
269 - tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
270 -
271 - for_each_sta_info(local, tbl, hdr->addr1, sta, tmp) {
272 + for_each_sta_info(local, hdr->addr1, sta, tmp) {
273 /* skip wrong virtual interface */
274 if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr))
275 continue;