From: Michal Kazior <hidden> Date: 2016-01-21 13:22:00
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 <redacted>
---
net/mac80211/iface.c | 3 +++
1 file changed, 3 insertions(+)
From: Michal Kazior <hidden> Date: 2016-01-21 13:22:01
This will allow drivers to make more educated
decisions whether to defer transmission or not.
Relying on wake_tx_queue() call count implicitly
was not possible because it could be called
without queued frame count actually changing on
software tx aggregation start/stop code paths.
It was also not possible to know how long
byte-wise queue was without dequeueing.
Signed-off-by: Michal Kazior <redacted>
---
include/net/mac80211.h | 4 ++++
net/mac80211/iface.c | 2 ++
net/mac80211/sta_info.c | 2 ++
net/mac80211/tx.c | 11 ++++++++++-
4 files changed, 18 insertions(+), 1 deletion(-)
From: Felix Fietkau <hidden> Date: 2016-01-26 10:45:54
On 2016-01-21 14:23, Michal Kazior wrote:
This will allow drivers to make more educated
decisions whether to defer transmission or not.
Relying on wake_tx_queue() call count implicitly
was not possible because it could be called
without queued frame count actually changing on
software tx aggregation start/stop code paths.
It was also not possible to know how long
byte-wise queue was without dequeueing.
Signed-off-by: Michal Kazior <redacted>
Instead of exposing these in the struct to the driver directly, please
make a function to get them. Since the number of frames is already
tracked in txqi->queue, you can avoid counter duplication that way.
Also, that way you can fix a race condition between accessing the number
of frames counter and the bytes counter.
- Felix
From: Michal Kazior <hidden> Date: 2016-01-26 11:56:33
On 26 January 2016 at 11:45, Felix Fietkau [off-list ref] wrote:
On 2016-01-21 14:23, Michal Kazior wrote:
quoted
This will allow drivers to make more educated
decisions whether to defer transmission or not.
Relying on wake_tx_queue() call count implicitly
was not possible because it could be called
without queued frame count actually changing on
software tx aggregation start/stop code paths.
It was also not possible to know how long
byte-wise queue was without dequeueing.
Signed-off-by: Michal Kazior <redacted>
Instead of exposing these in the struct to the driver directly, please
make a function to get them. Since the number of frames is already
tracked in txqi->queue, you can avoid counter duplication that way.
Hmm, so you suggest to have something like:
void
ieee80211_get_txq_depth(struct ieee80211_txq *txq,
unsigned int *frame_cnt,
unsigned int *byte_count) {
struct txq_info *txqi = txq_to_info(txq);
if (frame_cnt)
*frame_cnt = txqi->queue.qlen;
if (byte_count)
*byte_cnt = txqi->byte_cnt;
}
Correct?
Sounds reasonable.
Also, that way you can fix a race condition between accessing the number
of frames counter and the bytes counter.
I don't see a point in maintaining coherency between the two counters
with regard to each other alone. Do you have a use-case that would
actually make use of that property?
I'd like to avoid any unnecessary spinlocks.
Michał
From: Felix Fietkau <hidden> Date: 2016-01-26 12:04:39
On 2016-01-26 12:56, Michal Kazior wrote:
On 26 January 2016 at 11:45, Felix Fietkau [off-list ref] wrote:
quoted
On 2016-01-21 14:23, Michal Kazior wrote:
quoted
This will allow drivers to make more educated
decisions whether to defer transmission or not.
Relying on wake_tx_queue() call count implicitly
was not possible because it could be called
without queued frame count actually changing on
software tx aggregation start/stop code paths.
It was also not possible to know how long
byte-wise queue was without dequeueing.
Signed-off-by: Michal Kazior <redacted>
Instead of exposing these in the struct to the driver directly, please
make a function to get them. Since the number of frames is already
tracked in txqi->queue, you can avoid counter duplication that way.
Hmm, so you suggest to have something like:
void
ieee80211_get_txq_depth(struct ieee80211_txq *txq,
unsigned int *frame_cnt,
unsigned int *byte_count) {
struct txq_info *txqi = txq_to_info(txq);
if (frame_cnt)
*frame_cnt = txqi->queue.qlen;
if (byte_count)
*byte_cnt = txqi->byte_cnt;
}
Correct?
Sounds reasonable.
Right.
quoted
Also, that way you can fix a race condition between accessing the number
of frames counter and the bytes counter.
I don't see a point in maintaining coherency between the two counters
with regard to each other alone. Do you have a use-case that would
actually make use of that property?
I'd like to avoid any unnecessary spinlocks.
OK. I guess we can leave them out for now. How frequently are you going
to call this function?
- Felix
From: Michal Kazior <hidden> Date: 2016-01-26 12:45:57
On 26 January 2016 at 13:04, Felix Fietkau [off-list ref] wrote:
On 2016-01-26 12:56, Michal Kazior wrote:
quoted
On 26 January 2016 at 11:45, Felix Fietkau [off-list ref] wrote:
quoted
On 2016-01-21 14:23, Michal Kazior wrote:
quoted
This will allow drivers to make more educated
decisions whether to defer transmission or not.
Relying on wake_tx_queue() call count implicitly
was not possible because it could be called
without queued frame count actually changing on
software tx aggregation start/stop code paths.
It was also not possible to know how long
byte-wise queue was without dequeueing.
Signed-off-by: Michal Kazior <redacted>
Instead of exposing these in the struct to the driver directly, please
make a function to get them. Since the number of frames is already
tracked in txqi->queue, you can avoid counter duplication that way.
Hmm, so you suggest to have something like:
[...]
quoted
quoted
Also, that way you can fix a race condition between accessing the number
of frames counter and the bytes counter.
I don't see a point in maintaining coherency between the two counters
with regard to each other alone. Do you have a use-case that would
actually make use of that property?
I'd like to avoid any unnecessary spinlocks.
OK. I guess we can leave them out for now. How frequently are you going
to call this function?
From: Johannes Berg <johannes@sipsolutions.net> Date: 2016-01-26 12:56:22
I don't see a point in maintaining coherency between the two counters
with regard to each other alone. Do you have a use-case that would
actually make use of that property?
I'd like to avoid any unnecessary spinlocks.
Make sure you document the lack of consistency between the two values
then, please.
johannes
From: Ben Greear <hidden> Date: 2016-01-25 17:59:53
On 01/21/2016 05:23 AM, Michal Kazior wrote:
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.
Hard to know for certain, but this *appears* to fix the unexpectedly large
amount of CE/AXI ath10k firmware crashes that we saw in the 4.2 kernel (4.0 previously
ran much better han 4.2 for us).
We'll continue testing, in case we are just getting lucky so far.
Thanks,
Ben
From: Michal Kazior <hidden> Date: 2016-01-26 06:35:47
On 25 January 2016 at 18:59, Ben Greear [off-list ref] wrote:
On 01/21/2016 05:23 AM, Michal Kazior wrote:
quoted
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.
Hard to know for certain, but this *appears* to fix the unexpectedly large
amount of CE/AXI ath10k firmware crashes that we saw in the 4.2 kernel (4.0
previously
ran much better han 4.2 for us).
That's impossible.
Without wake_tx_queue() txqs aren't even allocated (sdata->vif.txq is NULL).
Michał
From: Ben Greear <hidden> Date: 2016-01-26 15:29:31
On 01/25/2016 10:35 PM, Michal Kazior wrote:
On 25 January 2016 at 18:59, Ben Greear [off-list ref] wrote:
quoted
On 01/21/2016 05:23 AM, Michal Kazior wrote:
quoted
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.
Hard to know for certain, but this *appears* to fix the unexpectedly large
amount of CE/AXI ath10k firmware crashes that we saw in the 4.2 kernel (4.0
previously
ran much better han 4.2 for us).
That's impossible.
Without wake_tx_queue() txqs aren't even allocated (sdata->vif.txq is NULL).
You are right. But while testing, one of my guys did find a way to reproduce the
crash very quickly in 4.2. Happens fastest when I use the HTT-MGT variant
of my firmware, but same firmware works good-ish in 4.0. Seems I have something
to bisect now if I can get a minimal patch to apply each time to enable my
htt-mgt firmware feature...
The latest test case is to just to change the channel of the AP while station
is connected. Station sends some null-funcs, firmware resets it's low-level
stuff a bunch because it doesn't get AKCs, then CE/AXI crashes. Could be
my firmware or kernel modifications of course, though similar crash scenarios have been seen forever
in all sorts of firmwares and kernels.
Thanks,
Ben
--
Ben Greear [off-list ref]
Candela Technologies Inc http://www.candelatech.com
From: Johannes Berg <johannes@sipsolutions.net> Date: 2016-01-26 13:11:34
On Thu, 2016-01-21 at 14:23 +0100, Michal Kazior wrote:
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.
From: Michal Kazior <hidden> Date: 2016-01-27 14:25:10
This will allow drivers to make more educated
decisions whether to defer transmission or not.
Relying on wake_tx_queue() call count implicitly
was not possible because it could be called
without queued frame count actually changing on
software tx aggregation start/stop code paths.
It was also not possible to know how long
byte-wise queue was without dequeueing.
Signed-off-by: Michal Kazior <redacted>
---
Notes:
v2:
* export a dedicated API call to get both
frame/byte counts to reduce redundancy and
offer possible synchronized reads in the future [Felix]
include/net/mac80211.h | 15 +++++++++++++++
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/iface.c | 1 +
net/mac80211/sta_info.c | 1 +
net/mac80211/tx.c | 8 +++++++-
net/mac80211/util.c | 14 ++++++++++++++
6 files changed, 39 insertions(+), 1 deletion(-)
This *looks* a bit worrying - you have an atomic dec for the # of
packets and a non-atomic one for the bytes.
You probably thought about it and I guess it's fine, but can you
explain it?
johannes
This *looks* a bit worrying - you have an atomic dec for the # of
packets and a non-atomic one for the bytes.
You probably thought about it and I guess it's fine, but can you
explain it?
The atomic was used because it accesses per-vif counters. You can't
use txqi->queue.lock for that.
On the other hand byte_cnt is per txqi and it was very easy to make
use of the txqi->queue.lock (which was already acquired in both drv_tx
and tx_dequeue functions). Using atomic* for byte_cnt would be
wasteful a bit.
Michał
This *looks* a bit worrying - you have an atomic dec for the # of
packets and a non-atomic one for the bytes.
You probably thought about it and I guess it's fine, but can you
explain it?
The atomic was used because it accesses per-vif counters. You can't
use txqi->queue.lock for that.
Ah. I completely missed that distinction, thanks.
johannes
From: Johannes Berg <johannes@sipsolutions.net> Date: 2016-02-02 15:07:04
On Wed, 2016-01-27 at 15:26 +0100, Michal Kazior wrote:
This will allow drivers to make more educated
decisions whether to defer transmission or not.
Relying on wake_tx_queue() call count implicitly
was not possible because it could be called
without queued frame count actually changing on
software tx aggregation start/stop code paths.
It was also not possible to know how long
byte-wise queue was without dequeueing.