ath10k-ct: depend on kmod-hwmon-core, it gets used when CONFIG_THERMAL is set
[lede.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;