2014-04-09 10:07:41

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 0/4] ath10k: AP-related fixes

Hi,

This is a bunch of fixes I've found while
investigating tx credit issues.

I've only experienced problem fixed by 4/4
firsthand. Other patches are preemptive fixes :-)


Michal Kazior (4):
ath10k: make sure to not leak beacon dma mapping
ath10k: make sure to not use invalid beacon pointer
ath10k: prevent beacon memory leak
ath10k: fix firmware recovery with ap interface

drivers/net/wireless/ath/ath10k/mac.c | 16 ++++++++++++++++
drivers/net/wireless/ath/ath10k/wmi.c | 3 +++
2 files changed, 19 insertions(+)

--
1.8.5.3



2014-04-09 10:07:44

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 4/4] ath10k: fix firmware recovery with ap interface

Beacon data wasn't properly cleared during early
phase of recovery. This in turn caused firmware to
crash because the beacon data was submitted before
vdevs were fully re-configured. Ultimately the
device was considered wedged and nothing worked
until driver was reloaded.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 5a9da3a..143ea1c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2264,6 +2264,8 @@ static void ath10k_tx(struct ieee80211_hw *hw,
*/
void ath10k_halt(struct ath10k *ar)
{
+ struct ath10k_vif *arvif;
+
lockdep_assert_held(&ar->conf_mutex);

ath10k_stop_cac(ar);
@@ -2280,6 +2282,17 @@ void ath10k_halt(struct ath10k *ar)
ar->scan.in_progress = false;
ieee80211_scan_completed(ar->hw, true);
}
+
+ list_for_each_entry(arvif, &ar->arvifs, list) {
+ if (!arvif->beacon)
+ continue;
+
+ dma_unmap_single(arvif->ar->dev,
+ ATH10K_SKB_CB(arvif->beacon)->paddr,
+ arvif->beacon->len, DMA_TO_DEVICE);
+ dev_kfree_skb_any(arvif->beacon);
+ arvif->beacon = NULL;
+ }
spin_unlock_bh(&ar->data_lock);
}

--
1.8.5.3


2014-04-09 10:07:43

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 3/4] ath10k: prevent beacon memory leak

If DMA mapping of next beacon failed ath10k leaked
the beacon.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/wmi.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 35c7d52..ca51f17 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1450,6 +1450,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
ATH10K_SKB_CB(bcn)->paddr);
if (ret) {
ath10k_warn("failed to map beacon: %d\n", ret);
+ dev_kfree_skb_any(bcn);
goto skip;
}

--
1.8.5.3


2014-04-14 07:26:39

by Michal Kazior

[permalink] [raw]
Subject: [PATCHv2 3/4] ath10k: prevent beacon memory leak

If DMA mapping of next beacon failed ath10k leaked
the beacon.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/wmi.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 11176cc..72cc4f2 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1441,6 +1441,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
ATH10K_SKB_CB(bcn)->paddr);
if (ret) {
ath10k_warn("failed to map beacon: %d\n", ret);
+ dev_kfree_skb_any(bcn);
goto skip;
}

--
1.8.5.3


2014-04-14 07:26:40

by Michal Kazior

[permalink] [raw]
Subject: [PATCHv2 4/4] ath10k: fix firmware recovery with ap interface

Beacon data wasn't properly cleared during early
phase of recovery. This in turn caused firmware to
crash because the beacon data was submitted before
vdevs were fully re-configured. Ultimately the
device was considered wedged and nothing worked
until driver was reloaded.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 22e8239..e2c01dc 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2291,6 +2291,8 @@ static void ath10k_tx(struct ieee80211_hw *hw,
*/
void ath10k_halt(struct ath10k *ar)
{
+ struct ath10k_vif *arvif;
+
lockdep_assert_held(&ar->conf_mutex);

if (ath10k_monitor_is_enabled(ar)) {
@@ -2313,6 +2315,17 @@ void ath10k_halt(struct ath10k *ar)
ar->scan.in_progress = false;
ieee80211_scan_completed(ar->hw, true);
}
+
+ list_for_each_entry(arvif, &ar->arvifs, list) {
+ if (!arvif->beacon)
+ continue;
+
+ dma_unmap_single(arvif->ar->dev,
+ ATH10K_SKB_CB(arvif->beacon)->paddr,
+ arvif->beacon->len, DMA_TO_DEVICE);
+ dev_kfree_skb_any(arvif->beacon);
+ arvif->beacon = NULL;
+ }
spin_unlock_bh(&ar->data_lock);
}

--
1.8.5.3


2014-04-09 10:07:42

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 2/4] ath10k: make sure to not use invalid beacon pointer

If DMA mapping of next beacon failed it was
possible for next SWBA to access a pointer that
was already unmapped and freed. This could cause
memory corruption.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/wmi.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index d4b48ef..35c7d52 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1441,6 +1441,8 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
dev_kfree_skb_any(arvif->beacon);
}

+ arvif->beacon = NULL;
+
ATH10K_SKB_CB(bcn)->paddr = dma_map_single(arvif->ar->dev,
bcn->data, bcn->len,
DMA_TO_DEVICE);
--
1.8.5.3


2014-04-09 10:07:41

by Michal Kazior

[permalink] [raw]
Subject: [PATCH 1/4] ath10k: make sure to not leak beacon dma mapping

If for some reason mac80211 wouldn't stop
beaconing gracefully and just removed interface of
a running AP/IBSS interface it was possible to
leak pending beacon DMA mapping. It's very
unlikely but better safe than sorry.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 58ec5a7..5a9da3a 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2738,6 +2738,9 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,

spin_lock_bh(&ar->data_lock);
if (arvif->beacon) {
+ dma_unmap_single(arvif->ar->dev,
+ ATH10K_SKB_CB(arvif->beacon)->paddr,
+ arvif->beacon->len, DMA_TO_DEVICE);
dev_kfree_skb_any(arvif->beacon);
arvif->beacon = NULL;
}
--
1.8.5.3


2014-04-14 07:26:36

by Michal Kazior

[permalink] [raw]
Subject: [PATCHv2 1/4] ath10k: make sure to not leak beacon dma mapping

If for some reason mac80211 wouldn't stop
beaconing gracefully and just removed interface of
a running AP/IBSS interface it was possible to
leak pending beacon DMA mapping. It's very
unlikely but better safe than sorry.

Signed-off-by: Michal Kazior <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 8385a7a..22e8239 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2771,6 +2771,9 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,

spin_lock_bh(&ar->data_lock);
if (arvif->beacon) {
+ dma_unmap_single(arvif->ar->dev,
+ ATH10K_SKB_CB(arvif->beacon)->paddr,
+ arvif->beacon->len, DMA_TO_DEVICE);
dev_kfree_skb_any(arvif->beacon);
arvif->beacon = NULL;
}
--
1.8.5.3


2014-04-14 07:26:38

by Michal Kazior

[permalink] [raw]
Subject: [PATCHv2 2/4] ath10k: make sure to not use invalid beacon pointer

If DMA mapping of next beacon failed it was
possible for next SWBA to access a pointer that
was already unmapped and freed. This could cause
memory corruption.

Signed-off-by: Michal Kazior <[email protected]>
---
v2:
* move arvif->beacon=NULL after dev_kfree_skb() [Kalle]

drivers/net/wireless/ath/ath10k/wmi.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index fe4d5f1..11176cc 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1431,6 +1431,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
ATH10K_SKB_CB(arvif->beacon)->paddr,
arvif->beacon->len, DMA_TO_DEVICE);
dev_kfree_skb_any(arvif->beacon);
+ arvif->beacon = NULL;
}

ATH10K_SKB_CB(bcn)->paddr = dma_map_single(arvif->ar->dev,
--
1.8.5.3


2014-04-14 07:26:35

by Michal Kazior

[permalink] [raw]
Subject: [PATCHv2 0/4] ath10k: AP-related fixes

Hi,

This is a bunch of fixes I've found while
investigating tx credit issues.

I've only experienced problem fixed by 4/4
firsthand. Other patches are preemptive fixes :-)

v2:
* minor tweaks

Michal Kazior (4):
ath10k: make sure to not leak beacon dma mapping
ath10k: make sure to not use invalid beacon pointer
ath10k: prevent beacon memory leak
ath10k: fix firmware recovery with ap interface

drivers/net/wireless/ath/ath10k/mac.c | 16 ++++++++++++++++
drivers/net/wireless/ath/ath10k/wmi.c | 2 ++
2 files changed, 18 insertions(+)

--
1.8.5.3


2014-04-10 05:57:19

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 2/4] ath10k: make sure to not use invalid beacon pointer

Michal Kazior <[email protected]> writes:

> If DMA mapping of next beacon failed it was
> possible for next SWBA to access a pointer that
> was already unmapped and freed. This could cause
> memory corruption.
>
> Signed-off-by: Michal Kazior <[email protected]>
> ---
> drivers/net/wireless/ath/ath10k/wmi.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
> index d4b48ef..35c7d52 100644
> --- a/drivers/net/wireless/ath/ath10k/wmi.c
> +++ b/drivers/net/wireless/ath/ath10k/wmi.c
> @@ -1441,6 +1441,8 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
> dev_kfree_skb_any(arvif->beacon);
> }
>
> + arvif->beacon = NULL;

Why have this outside the "if (arvif->beacon)" check? If it's already
NULL, there's no need to set it to NULL again. And besides, at least for
me, it's more intuitive to reset the variable immeadiately after
dev_kfree_skb_any().

--
Kalle Valo

2014-04-24 06:23:42

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCHv2 0/4] ath10k: AP-related fixes

Michal Kazior <[email protected]> writes:

> Hi,
>
> This is a bunch of fixes I've found while
> investigating tx credit issues.
>
> I've only experienced problem fixed by 4/4
> firsthand. Other patches are preemptive fixes :-)
>
> v2:
> * minor tweaks
>
> Michal Kazior (4):
> ath10k: make sure to not leak beacon dma mapping
> ath10k: make sure to not use invalid beacon pointer
> ath10k: prevent beacon memory leak
> ath10k: fix firmware recovery with ap interface

Thanks, all patches applied.

--
Kalle Valo