mac80211: merge a bunch of pending fixes
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 48536
This commit is contained in:
parent
c0edf30bdc
commit
c1e6ef488f
5 changed files with 294 additions and 0 deletions
|
@ -0,0 +1,27 @@
|
|||
From: Michal Kazior <michal.kazior@tieto.com>
|
||||
Date: Thu, 21 Jan 2016 14:23:07 +0100
|
||||
Subject: [PATCH] mac80211: fix txq queue related crashes
|
||||
|
||||
The driver can access the queue simultanously
|
||||
while mac80211 tears down the interface. Without
|
||||
spinlock protection this could lead to corrupting
|
||||
sk_buff_head and subsequently to an invalid
|
||||
pointer dereference.
|
||||
|
||||
Fixes: ba8c3d6f16a1 ("mac80211: add an intermediate software queue implementation")
|
||||
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -977,7 +977,10 @@ static void ieee80211_do_stop(struct iee
|
||||
if (sdata->vif.txq) {
|
||||
struct txq_info *txqi = to_txq_info(sdata->vif.txq);
|
||||
|
||||
+ spin_lock_bh(&txqi->queue.lock);
|
||||
ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
|
||||
+ spin_unlock_bh(&txqi->queue.lock);
|
||||
+
|
||||
atomic_set(&sdata->txqs_len[txqi->txq.ac], 0);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
From: Michal Kazior <michal.kazior@tieto.com>
|
||||
Date: Mon, 25 Jan 2016 14:43:24 +0100
|
||||
Subject: [PATCH] mac80211: fix unnecessary frame drops in mesh fwding
|
||||
|
||||
The ieee80211_queue_stopped() expects hw queue
|
||||
number but it was given raw WMM AC number instead.
|
||||
|
||||
This could cause frame drops and problems with
|
||||
traffic in some cases - most notably if driver
|
||||
doesn't map AC numbers to queue numbers 1:1 and
|
||||
uses ieee80211_stop_queues() and
|
||||
ieee80211_wake_queue() only without ever calling
|
||||
ieee80211_wake_queues().
|
||||
|
||||
On ath10k it was possible to hit this problem in
|
||||
the following case:
|
||||
|
||||
1. wlan0 uses queue 0
|
||||
(ath10k maps queues per vif)
|
||||
2. offchannel uses queue 15
|
||||
3. queues 1-14 are unused
|
||||
4. ieee80211_stop_queues()
|
||||
5. ieee80211_wake_queue(q=0)
|
||||
6. ieee80211_wake_queue(q=15)
|
||||
(other queues are not woken up because both
|
||||
driver and mac80211 know other queues are
|
||||
unused)
|
||||
7. ieee80211_rx_h_mesh_fwding()
|
||||
8. ieee80211_select_queue_80211() returns 2
|
||||
9. ieee80211_queue_stopped(q=2) returns true
|
||||
10. frame is dropped (oops!)
|
||||
|
||||
Fixes: d3c1597b8d1b ("mac80211: fix forwarded mesh frame queue mapping")
|
||||
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2235,7 +2235,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
|
||||
struct ieee80211_local *local = rx->local;
|
||||
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
- u16 q, hdrlen;
|
||||
+ u16 ac, q, hdrlen;
|
||||
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
@@ -2304,7 +2304,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
|
||||
ether_addr_equal(sdata->vif.addr, hdr->addr3))
|
||||
return RX_CONTINUE;
|
||||
|
||||
- q = ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
+ ac = ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
+ q = sdata->vif.hw_queue[ac];
|
||||
if (ieee80211_queue_stopped(&local->hw, q)) {
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
|
||||
return RX_DROP_MONITOR;
|
|
@ -0,0 +1,103 @@
|
|||
From: Sachin Kulkarni <Sachin.Kulkarni@imgtec.com>
|
||||
Date: Tue, 12 Jan 2016 14:30:19 +0530
|
||||
Subject: [PATCH] mac80211: Requeue work after scan complete for all VIF
|
||||
types.
|
||||
|
||||
During a sw scan ieee80211_iface_work ignores work items for all vifs.
|
||||
However after the scan complete work is requeued only for STA, ADHOC
|
||||
and MESH iftypes.
|
||||
|
||||
This occasionally results in event processing getting delayed/not
|
||||
processed for iftype AP when it coexists with a STA. This can result
|
||||
in data halt and eventually disconnection on the AP interface.
|
||||
|
||||
Signed-off-by: Sachin Kulkarni <Sachin.Kulkarni@imgtec.com>
|
||||
Cc: linux-wireless@vger.kernel.org
|
||||
Cc: johannes@sipsolutions.net
|
||||
---
|
||||
|
||||
--- a/net/mac80211/ibss.c
|
||||
+++ b/net/mac80211/ibss.c
|
||||
@@ -1731,7 +1731,6 @@ void ieee80211_ibss_notify_scan_complete
|
||||
if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
|
||||
continue;
|
||||
sdata->u.ibss.last_scan_completed = jiffies;
|
||||
- ieee80211_queue_work(&local->hw, &sdata->work);
|
||||
}
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
}
|
||||
--- a/net/mac80211/mesh.c
|
||||
+++ b/net/mac80211/mesh.c
|
||||
@@ -1369,17 +1369,6 @@ out:
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
-void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
|
||||
-{
|
||||
- struct ieee80211_sub_if_data *sdata;
|
||||
-
|
||||
- rcu_read_lock();
|
||||
- list_for_each_entry_rcu(sdata, &local->interfaces, list)
|
||||
- if (ieee80211_vif_is_mesh(&sdata->vif) &&
|
||||
- ieee80211_sdata_running(sdata))
|
||||
- ieee80211_queue_work(&local->hw, &sdata->work);
|
||||
- rcu_read_unlock();
|
||||
-}
|
||||
|
||||
void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
--- a/net/mac80211/mesh.h
|
||||
+++ b/net/mac80211/mesh.h
|
||||
@@ -362,14 +362,10 @@ static inline bool mesh_path_sel_is_hwmp
|
||||
return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
|
||||
}
|
||||
|
||||
-void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
|
||||
-
|
||||
void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
|
||||
void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211s_stop(void);
|
||||
#else
|
||||
-static inline void
|
||||
-ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
|
||||
static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
|
||||
{ return false; }
|
||||
static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -3978,8 +3978,6 @@ static void ieee80211_restart_sta_timer(
|
||||
if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
|
||||
ieee80211_queue_work(&sdata->local->hw,
|
||||
&sdata->u.mgd.monitor_work);
|
||||
- /* and do all the other regular work too */
|
||||
- ieee80211_queue_work(&sdata->local->hw, &sdata->work);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net/mac80211/scan.c
|
||||
+++ b/net/mac80211/scan.c
|
||||
@@ -314,6 +314,7 @@ static void __ieee80211_scan_completed(s
|
||||
bool was_scanning = local->scanning;
|
||||
struct cfg80211_scan_request *scan_req;
|
||||
struct ieee80211_sub_if_data *scan_sdata;
|
||||
+ struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
lockdep_assert_held(&local->mtx);
|
||||
|
||||
@@ -373,7 +374,15 @@ static void __ieee80211_scan_completed(s
|
||||
|
||||
ieee80211_mlme_notify_scan_completed(local);
|
||||
ieee80211_ibss_notify_scan_completed(local);
|
||||
- ieee80211_mesh_notify_scan_completed(local);
|
||||
+
|
||||
+ /* Requeue all the work that might have been ignored while
|
||||
+ * the scan was in progress
|
||||
+ */
|
||||
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
+ if (ieee80211_sdata_running(sdata))
|
||||
+ ieee80211_queue_work(&sdata->local->hw, &sdata->work);
|
||||
+ }
|
||||
+
|
||||
if (was_scanning)
|
||||
ieee80211_start_next_roc(local);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
From: Sara Sharon <sara.sharon@intel.com>
|
||||
Date: Mon, 25 Jan 2016 15:46:35 +0200
|
||||
Subject: [PATCH] mac80211: fix ibss scan parameters
|
||||
|
||||
When joining IBSS a full scan should be initiated in order to search
|
||||
for existing cell, unless the fixed_channel parameter was set.
|
||||
A default channel to create the IBSS on if no cell was found is
|
||||
provided as well.
|
||||
However - a scan is initiated only on the default channel provided
|
||||
regardless of whether ifibss->fixed_channel is set or not, with the
|
||||
obvious result of the cell not joining existing IBSS cell that is
|
||||
on another channel.
|
||||
|
||||
Fixes: 76bed0f43b27 ("mac80211: IBSS fix scan request")
|
||||
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
|
||||
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/ibss.c
|
||||
+++ b/net/mac80211/ibss.c
|
||||
@@ -7,6 +7,7 @@
|
||||
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
+ * Copyright(c) 2016 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -1483,14 +1484,21 @@ static void ieee80211_sta_find_ibss(stru
|
||||
|
||||
sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
|
||||
|
||||
- num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
|
||||
- &ifibss->chandef,
|
||||
- channels,
|
||||
- ARRAY_SIZE(channels));
|
||||
scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
|
||||
- ieee80211_request_ibss_scan(sdata, ifibss->ssid,
|
||||
- ifibss->ssid_len, channels, num,
|
||||
- scan_width);
|
||||
+
|
||||
+ if (ifibss->fixed_channel) {
|
||||
+ num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
|
||||
+ &ifibss->chandef,
|
||||
+ channels,
|
||||
+ ARRAY_SIZE(channels));
|
||||
+ ieee80211_request_ibss_scan(sdata, ifibss->ssid,
|
||||
+ ifibss->ssid_len, channels,
|
||||
+ num, scan_width);
|
||||
+ } else {
|
||||
+ ieee80211_request_ibss_scan(sdata, ifibss->ssid,
|
||||
+ ifibss->ssid_len, NULL,
|
||||
+ 0, scan_width);
|
||||
+ }
|
||||
} else {
|
||||
int interval = IEEE80211_SCAN_INTERVAL;
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
From: Chris Bainbridge <chris.bainbridge@gmail.com>
|
||||
Date: Wed, 27 Jan 2016 15:46:18 +0000
|
||||
Subject: [PATCH] net/mac80211/agg-rx.c: fix use of uninitialised values
|
||||
|
||||
Use kzalloc instead of kmalloc for struct tid_ampdu_rx. Fixes:
|
||||
|
||||
[ 7.976605] UBSAN: Undefined behaviour in net/mac80211/rx.c:932:29
|
||||
[ 7.976608] load of value 2 is not a valid value for type '_Bool'
|
||||
[ 7.976611] CPU: 3 PID: 1134 Comm: kworker/u16:7 Not tainted 4.5.0-rc1+ #265
|
||||
[ 7.976613] Hardware name: Apple Inc. MacBookPro10,2/Mac-AFD8A9D944EA4843, BIOS MBP102.88Z.0106.B0A.1509130955 09/13/2015
|
||||
[ 7.976616] Workqueue: phy0 rt2x00usb_work_rxdone
|
||||
[ 7.976619] 0000000000000004 ffff880254a7ba50 ffffffff8181d866 0000000000000007
|
||||
[ 7.976622] ffff880254a7ba78 ffff880254a7ba68 ffffffff8188422d ffffffff8379b500
|
||||
[ 7.976626] ffff880254a7bab8 ffffffff81884747 0000000000000202 0000000348620032
|
||||
[ 7.976629] Call Trace:
|
||||
[ 7.976633] [<ffffffff8181d866>] dump_stack+0x45/0x5f
|
||||
[ 7.976637] [<ffffffff8188422d>] ubsan_epilogue+0xd/0x40
|
||||
[ 7.976642] [<ffffffff81884747>] __ubsan_handle_load_invalid_value+0x67/0x70
|
||||
[ 7.976646] [<ffffffff82227b4d>] ieee80211_sta_reorder_release.isra.16+0x5ed/0x730
|
||||
[ 7.976650] [<ffffffff8222ca14>] ieee80211_prepare_and_rx_handle+0xd04/0x1c00
|
||||
[ 7.976654] [<ffffffff81cb27ce>] ? usb_hcd_map_urb_for_dma+0x65e/0x960
|
||||
[ 7.976659] [<ffffffff8222db03>] __ieee80211_rx_handle_packet+0x1f3/0x750
|
||||
[ 7.976663] [<ffffffff8222e4a7>] ieee80211_rx_napi+0x447/0x990
|
||||
[ 7.976667] [<ffffffff81c5fb85>] rt2x00lib_rxdone+0x305/0xbd0
|
||||
[ 7.976670] [<ffffffff811ac23f>] ? dequeue_task_fair+0x64f/0x1de0
|
||||
[ 7.976674] [<ffffffff811a1516>] ? sched_clock_cpu+0xe6/0x150
|
||||
[ 7.976678] [<ffffffff81c6c45c>] rt2x00usb_work_rxdone+0x7c/0x140
|
||||
[ 7.976682] [<ffffffff8117aef6>] process_one_work+0x226/0x860
|
||||
[ 7.976686] [<ffffffff8117b58c>] worker_thread+0x5c/0x680
|
||||
[ 7.976690] [<ffffffff8117b530>] ? process_one_work+0x860/0x860
|
||||
[ 7.976693] [<ffffffff81184f86>] kthread+0xf6/0x150
|
||||
[ 7.976697] [<ffffffff81184e90>] ? kthread_worker_fn+0x310/0x310
|
||||
[ 7.976700] [<ffffffff822a94df>] ret_from_fork+0x3f/0x70
|
||||
[ 7.976703] [<ffffffff81184e90>] ? kthread_worker_fn+0x310/0x310
|
||||
|
||||
Link: https://lkml.org/lkml/2016/1/26/230
|
||||
Signed-off-by: Chris Bainbridge <chris.bainbridge@gmail.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/agg-rx.c
|
||||
+++ b/net/mac80211/agg-rx.c
|
||||
@@ -327,7 +327,7 @@ void __ieee80211_start_rx_ba_session(str
|
||||
}
|
||||
|
||||
/* prepare A-MPDU MLME for Rx aggregation */
|
||||
- tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
|
||||
+ tid_agg_rx = kzalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
|
||||
if (!tid_agg_rx)
|
||||
goto end;
|
||||
|
Loading…
Reference in a new issue