Skip to content

Commit a13e8d4

Browse files
committed
Merge tag 'mac80211-for-davem-2017-11-20' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says: ==================== A few things: * straggler timer conversions from Kees * memory leak fix in hwsim * fix some fallout from regdb changes if wireless is built-in * also free aggregation sessions in startup state when station goes away, to avoid crashing the timer ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents b48b1f7 + 33ddd81 commit a13e8d4

File tree

17 files changed

+155
-137
lines changed

17 files changed

+155
-137
lines changed

drivers/net/wireless/mac80211_hwsim.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3108,6 +3108,7 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
31083108
{
31093109
struct hwsim_new_radio_params param = { 0 };
31103110
const char *hwname = NULL;
3111+
int ret;
31113112

31123113
param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
31133114
param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE];
@@ -3147,7 +3148,9 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
31473148
param.regd = hwsim_world_regdom_custom[idx];
31483149
}
31493150

3150-
return mac80211_hwsim_new_radio(info, &param);
3151+
ret = mac80211_hwsim_new_radio(info, &param);
3152+
kfree(hwname);
3153+
return ret;
31513154
}
31523155

31533156
static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)

net/mac80211/agg-rx.c

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -151,21 +151,17 @@ EXPORT_SYMBOL(ieee80211_stop_rx_ba_session);
151151
* After accepting the AddBA Request we activated a timer,
152152
* resetting it after each frame that arrives from the originator.
153153
*/
154-
static void sta_rx_agg_session_timer_expired(unsigned long data)
154+
static void sta_rx_agg_session_timer_expired(struct timer_list *t)
155155
{
156-
/* not an elegant detour, but there is no choice as the timer passes
157-
* only one argument, and various sta_info are needed here, so init
158-
* flow in sta_info_create gives the TID as data, while the timer_to_id
159-
* array gives the sta through container_of */
160-
u8 *ptid = (u8 *)data;
161-
u8 *timer_to_id = ptid - *ptid;
162-
struct sta_info *sta = container_of(timer_to_id, struct sta_info,
163-
timer_to_tid[0]);
156+
struct tid_ampdu_rx *tid_rx_timer =
157+
from_timer(tid_rx_timer, t, session_timer);
158+
struct sta_info *sta = tid_rx_timer->sta;
159+
u8 tid = tid_rx_timer->tid;
164160
struct tid_ampdu_rx *tid_rx;
165161
unsigned long timeout;
166162

167163
rcu_read_lock();
168-
tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]);
164+
tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
169165
if (!tid_rx) {
170166
rcu_read_unlock();
171167
return;
@@ -180,21 +176,18 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
180176
rcu_read_unlock();
181177

182178
ht_dbg(sta->sdata, "RX session timer expired on %pM tid %d\n",
183-
sta->sta.addr, (u16)*ptid);
179+
sta->sta.addr, tid);
184180

185-
set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired);
181+
set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired);
186182
ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
187183
}
188184

189-
static void sta_rx_agg_reorder_timer_expired(unsigned long data)
185+
static void sta_rx_agg_reorder_timer_expired(struct timer_list *t)
190186
{
191-
u8 *ptid = (u8 *)data;
192-
u8 *timer_to_id = ptid - *ptid;
193-
struct sta_info *sta = container_of(timer_to_id, struct sta_info,
194-
timer_to_tid[0]);
187+
struct tid_ampdu_rx *tid_rx = from_timer(tid_rx, t, reorder_timer);
195188

196189
rcu_read_lock();
197-
ieee80211_release_reorder_timeout(sta, *ptid);
190+
ieee80211_release_reorder_timeout(tid_rx->sta, tid_rx->tid);
198191
rcu_read_unlock();
199192
}
200193

@@ -356,14 +349,12 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
356349
spin_lock_init(&tid_agg_rx->reorder_lock);
357350

358351
/* rx timer */
359-
setup_deferrable_timer(&tid_agg_rx->session_timer,
360-
sta_rx_agg_session_timer_expired,
361-
(unsigned long)&sta->timer_to_tid[tid]);
352+
timer_setup(&tid_agg_rx->session_timer,
353+
sta_rx_agg_session_timer_expired, TIMER_DEFERRABLE);
362354

363355
/* rx reorder timer */
364-
setup_timer(&tid_agg_rx->reorder_timer,
365-
sta_rx_agg_reorder_timer_expired,
366-
(unsigned long)&sta->timer_to_tid[tid]);
356+
timer_setup(&tid_agg_rx->reorder_timer,
357+
sta_rx_agg_reorder_timer_expired, 0);
367358

368359
/* prepare reordering buffer */
369360
tid_agg_rx->reorder_buf =
@@ -399,6 +390,8 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
399390
tid_agg_rx->auto_seq = auto_seq;
400391
tid_agg_rx->started = false;
401392
tid_agg_rx->reorder_buf_filtered = 0;
393+
tid_agg_rx->tid = tid;
394+
tid_agg_rx->sta = sta;
402395
status = WLAN_STATUS_SUCCESS;
403396

404397
/* activate it for RX */

net/mac80211/agg-tx.c

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,11 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
330330

331331
spin_lock_bh(&sta->lock);
332332

333+
/* free struct pending for start, if present */
334+
tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
335+
kfree(tid_tx);
336+
sta->ampdu_mlme.tid_start_tx[tid] = NULL;
337+
333338
tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
334339
if (!tid_tx) {
335340
spin_unlock_bh(&sta->lock);
@@ -422,15 +427,12 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
422427
* add Block Ack response will arrive from the recipient.
423428
* If this timer expires sta_addba_resp_timer_expired will be executed.
424429
*/
425-
static void sta_addba_resp_timer_expired(unsigned long data)
430+
static void sta_addba_resp_timer_expired(struct timer_list *t)
426431
{
427-
/* not an elegant detour, but there is no choice as the timer passes
428-
* only one argument, and both sta_info and TID are needed, so init
429-
* flow in sta_info_create gives the TID as data, while the timer_to_id
430-
* array gives the sta through container_of */
431-
u16 tid = *(u8 *)data;
432-
struct sta_info *sta = container_of((void *)data,
433-
struct sta_info, timer_to_tid[tid]);
432+
struct tid_ampdu_tx *tid_tx_timer =
433+
from_timer(tid_tx_timer, t, addba_resp_timer);
434+
struct sta_info *sta = tid_tx_timer->sta;
435+
u8 tid = tid_tx_timer->tid;
434436
struct tid_ampdu_tx *tid_tx;
435437

436438
/* check if the TID waits for addBA response */
@@ -525,21 +527,17 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
525527
* After accepting the AddBA Response we activated a timer,
526528
* resetting it after each frame that we send.
527529
*/
528-
static void sta_tx_agg_session_timer_expired(unsigned long data)
530+
static void sta_tx_agg_session_timer_expired(struct timer_list *t)
529531
{
530-
/* not an elegant detour, but there is no choice as the timer passes
531-
* only one argument, and various sta_info are needed here, so init
532-
* flow in sta_info_create gives the TID as data, while the timer_to_id
533-
* array gives the sta through container_of */
534-
u8 *ptid = (u8 *)data;
535-
u8 *timer_to_id = ptid - *ptid;
536-
struct sta_info *sta = container_of(timer_to_id, struct sta_info,
537-
timer_to_tid[0]);
532+
struct tid_ampdu_tx *tid_tx_timer =
533+
from_timer(tid_tx_timer, t, session_timer);
534+
struct sta_info *sta = tid_tx_timer->sta;
535+
u8 tid = tid_tx_timer->tid;
538536
struct tid_ampdu_tx *tid_tx;
539537
unsigned long timeout;
540538

541539
rcu_read_lock();
542-
tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[*ptid]);
540+
tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
543541
if (!tid_tx || test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
544542
rcu_read_unlock();
545543
return;
@@ -555,9 +553,9 @@ static void sta_tx_agg_session_timer_expired(unsigned long data)
555553
rcu_read_unlock();
556554

557555
ht_dbg(sta->sdata, "tx session timer expired on %pM tid %d\n",
558-
sta->sta.addr, (u16)*ptid);
556+
sta->sta.addr, tid);
559557

560-
ieee80211_stop_tx_ba_session(&sta->sta, *ptid);
558+
ieee80211_stop_tx_ba_session(&sta->sta, tid);
561559
}
562560

563561
int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
@@ -670,16 +668,15 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
670668
__set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
671669

672670
tid_tx->timeout = timeout;
671+
tid_tx->sta = sta;
672+
tid_tx->tid = tid;
673673

674674
/* response timer */
675-
setup_timer(&tid_tx->addba_resp_timer,
676-
sta_addba_resp_timer_expired,
677-
(unsigned long)&sta->timer_to_tid[tid]);
675+
timer_setup(&tid_tx->addba_resp_timer, sta_addba_resp_timer_expired, 0);
678676

679677
/* tx timer */
680-
setup_deferrable_timer(&tid_tx->session_timer,
681-
sta_tx_agg_session_timer_expired,
682-
(unsigned long)&sta->timer_to_tid[tid]);
678+
timer_setup(&tid_tx->session_timer,
679+
sta_tx_agg_session_timer_expired, TIMER_DEFERRABLE);
683680

684681
/* assign a dialog token */
685682
sta->ampdu_mlme.dialog_token_allocator++;

net/mac80211/ibss.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,10 +1711,10 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
17111711
sdata_unlock(sdata);
17121712
}
17131713

1714-
static void ieee80211_ibss_timer(unsigned long data)
1714+
static void ieee80211_ibss_timer(struct timer_list *t)
17151715
{
17161716
struct ieee80211_sub_if_data *sdata =
1717-
(struct ieee80211_sub_if_data *) data;
1717+
from_timer(sdata, t, u.ibss.timer);
17181718

17191719
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
17201720
}
@@ -1723,8 +1723,7 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
17231723
{
17241724
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
17251725

1726-
setup_timer(&ifibss->timer, ieee80211_ibss_timer,
1727-
(unsigned long) sdata);
1726+
timer_setup(&ifibss->timer, ieee80211_ibss_timer, 0);
17281727
INIT_LIST_HEAD(&ifibss->incomplete_stations);
17291728
spin_lock_init(&ifibss->incomplete_lock);
17301729
INIT_WORK(&ifibss->csa_connection_drop_work,

net/mac80211/ieee80211_i.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,7 @@ struct tpt_led_trigger {
10571057
const struct ieee80211_tpt_blink *blink_table;
10581058
unsigned int blink_table_len;
10591059
struct timer_list timer;
1060+
struct ieee80211_local *local;
10601061
unsigned long prev_traffic;
10611062
unsigned long tx_bytes, rx_bytes;
10621063
unsigned int active, want;
@@ -1932,7 +1933,7 @@ static inline int ieee80211_ac_from_tid(int tid)
19321933

19331934
void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
19341935
void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
1935-
void ieee80211_dynamic_ps_timer(unsigned long data);
1936+
void ieee80211_dynamic_ps_timer(struct timer_list *t);
19361937
void ieee80211_send_nullfunc(struct ieee80211_local *local,
19371938
struct ieee80211_sub_if_data *sdata,
19381939
bool powersave);

net/mac80211/led.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,10 @@ static unsigned long tpt_trig_traffic(struct ieee80211_local *local,
248248
return DIV_ROUND_UP(delta, 1024 / 8);
249249
}
250250

251-
static void tpt_trig_timer(unsigned long data)
251+
static void tpt_trig_timer(struct timer_list *t)
252252
{
253-
struct ieee80211_local *local = (void *)data;
254-
struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
253+
struct tpt_led_trigger *tpt_trig = from_timer(tpt_trig, t, timer);
254+
struct ieee80211_local *local = tpt_trig->local;
255255
struct led_classdev *led_cdev;
256256
unsigned long on, off, tpt;
257257
int i;
@@ -306,8 +306,9 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw,
306306
tpt_trig->blink_table = blink_table;
307307
tpt_trig->blink_table_len = blink_table_len;
308308
tpt_trig->want = flags;
309+
tpt_trig->local = local;
309310

310-
setup_timer(&tpt_trig->timer, tpt_trig_timer, (unsigned long)local);
311+
timer_setup(&tpt_trig->timer, tpt_trig_timer, 0);
311312

312313
local->tpt_led_trigger = tpt_trig;
313314

@@ -326,7 +327,7 @@ static void ieee80211_start_tpt_led_trig(struct ieee80211_local *local)
326327
tpt_trig_traffic(local, tpt_trig);
327328
tpt_trig->running = true;
328329

329-
tpt_trig_timer((unsigned long)local);
330+
tpt_trig_timer(&tpt_trig->timer);
330331
mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ));
331332
}
332333

net/mac80211/main.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
633633
ieee80211_dynamic_ps_enable_work);
634634
INIT_WORK(&local->dynamic_ps_disable_work,
635635
ieee80211_dynamic_ps_disable_work);
636-
setup_timer(&local->dynamic_ps_timer,
637-
ieee80211_dynamic_ps_timer, (unsigned long) local);
636+
timer_setup(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, 0);
638637

639638
INIT_WORK(&local->sched_scan_stopped_work,
640639
ieee80211_sched_scan_stopped_work);

net/mac80211/mesh.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ void ieee80211s_stop(void)
3737
kmem_cache_destroy(rm_cache);
3838
}
3939

40-
static void ieee80211_mesh_housekeeping_timer(unsigned long data)
40+
static void ieee80211_mesh_housekeeping_timer(struct timer_list *t)
4141
{
42-
struct ieee80211_sub_if_data *sdata = (void *) data;
42+
struct ieee80211_sub_if_data *sdata =
43+
from_timer(sdata, t, u.mesh.housekeeping_timer);
4344
struct ieee80211_local *local = sdata->local;
4445
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
4546

@@ -528,18 +529,18 @@ int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata,
528529
return 0;
529530
}
530531

531-
static void ieee80211_mesh_path_timer(unsigned long data)
532+
static void ieee80211_mesh_path_timer(struct timer_list *t)
532533
{
533534
struct ieee80211_sub_if_data *sdata =
534-
(struct ieee80211_sub_if_data *) data;
535+
from_timer(sdata, t, u.mesh.mesh_path_timer);
535536

536537
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
537538
}
538539

539-
static void ieee80211_mesh_path_root_timer(unsigned long data)
540+
static void ieee80211_mesh_path_root_timer(struct timer_list *t)
540541
{
541542
struct ieee80211_sub_if_data *sdata =
542-
(struct ieee80211_sub_if_data *) data;
543+
from_timer(sdata, t, u.mesh.mesh_path_root_timer);
543544
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
544545

545546
set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
@@ -1442,9 +1443,8 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
14421443
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
14431444
static u8 zero_addr[ETH_ALEN] = {};
14441445

1445-
setup_timer(&ifmsh->housekeeping_timer,
1446-
ieee80211_mesh_housekeeping_timer,
1447-
(unsigned long) sdata);
1446+
timer_setup(&ifmsh->housekeeping_timer,
1447+
ieee80211_mesh_housekeeping_timer, 0);
14481448

14491449
ifmsh->accepting_plinks = true;
14501450
atomic_set(&ifmsh->mpaths, 0);
@@ -1458,12 +1458,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
14581458

14591459
mesh_pathtbl_init(sdata);
14601460

1461-
setup_timer(&ifmsh->mesh_path_timer,
1462-
ieee80211_mesh_path_timer,
1463-
(unsigned long) sdata);
1464-
setup_timer(&ifmsh->mesh_path_root_timer,
1465-
ieee80211_mesh_path_root_timer,
1466-
(unsigned long) sdata);
1461+
timer_setup(&ifmsh->mesh_path_timer, ieee80211_mesh_path_timer, 0);
1462+
timer_setup(&ifmsh->mesh_path_root_timer,
1463+
ieee80211_mesh_path_root_timer, 0);
14671464
INIT_LIST_HEAD(&ifmsh->preq_queue.list);
14681465
skb_queue_head_init(&ifmsh->ps.bc_buf);
14691466
spin_lock_init(&ifmsh->mesh_preq_queue_lock);

net/mac80211/mesh.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ void mesh_path_tx_pending(struct mesh_path *mpath);
296296
int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata);
297297
void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata);
298298
int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr);
299-
void mesh_path_timer(unsigned long data);
299+
void mesh_path_timer(struct timer_list *t);
300300
void mesh_path_flush_by_nexthop(struct sta_info *sta);
301301
void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
302302
struct sk_buff *skb);

net/mac80211/mesh_hwmp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,9 +1194,9 @@ int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata,
11941194
return err;
11951195
}
11961196

1197-
void mesh_path_timer(unsigned long data)
1197+
void mesh_path_timer(struct timer_list *t)
11981198
{
1199-
struct mesh_path *mpath = (void *) data;
1199+
struct mesh_path *mpath = from_timer(mpath, t, timer);
12001200
struct ieee80211_sub_if_data *sdata = mpath->sdata;
12011201
int ret;
12021202

net/mac80211/mesh_pathtbl.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,7 @@ struct mesh_path *mesh_path_new(struct ieee80211_sub_if_data *sdata,
399399
skb_queue_head_init(&new_mpath->frame_queue);
400400
new_mpath->exp_time = jiffies;
401401
spin_lock_init(&new_mpath->state_lock);
402-
setup_timer(&new_mpath->timer, mesh_path_timer,
403-
(unsigned long) new_mpath);
402+
timer_setup(&new_mpath->timer, mesh_path_timer, 0);
404403

405404
return new_mpath;
406405
}

0 commit comments

Comments
 (0)