diff mbox

[v1,1/1] ath10k: convert kmemdup to dma_alloc_coherent

Message ID 1524238793-24481-1-git-send-email-jared.bents@rockwellcollins.com (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show

Commit Message

Jared Bents April 20, 2018, 3:39 p.m. UTC
Update to convert the use of kmemdup to dma_alloc_coherent as
dma_alloc_coherent will consider DMA region limits such as
those seen with CONFIG_FSL_PCI && CONFIG_ZONE_DMA32 whereas
kmemdup does not take those limitations into account.

Signed-off-by: Jared Bents <jared.bents@rockwellcollins.com>
---
 drivers/net/wireless/ath/ath10k/pci.c | 36 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 26 deletions(-)

Comments

Kalle Valo April 21, 2018, 7:10 a.m. UTC | #1
Jared Bents <jared.bents@rockwellcollins.com> writes:

> Update to convert the use of kmemdup to dma_alloc_coherent as
> dma_alloc_coherent will consider DMA region limits such as
> those seen with CONFIG_FSL_PCI && CONFIG_ZONE_DMA32 whereas
> kmemdup does not take those limitations into account.
>
> Signed-off-by: Jared Bents <jared.bents@rockwellcollins.com>

Does this fix a real bug or is it just a theoretical issue you noticed
while looking at the code? If this fixes a real bug please give a
description of it.

https://wireless.wiki.kernel.org/en/users/drivers/ath10k/submittingpatches#guidelines
Jared Bents April 23, 2018, 6:21 p.m. UTC | #2
Hi Kalle,

On Sat, Apr 21, 2018 at 2:10 AM, Kalle Valo <kvalo@codeaurora.org> wrote:
> Jared Bents <jared.bents@rockwellcollins.com> writes:
>
>> Update to convert the use of kmemdup to dma_alloc_coherent as
>> dma_alloc_coherent will consider DMA region limits such as
>> those seen with CONFIG_FSL_PCI && CONFIG_ZONE_DMA32 whereas
>> kmemdup does not take those limitations into account.
>>
>> Signed-off-by: Jared Bents <jared.bents@rockwellcollins.com>
>
> Does this fix a real bug or is it just a theoretical issue you noticed
> while looking at the code? If this fixes a real bug please give a
> description of it.

It fixes a real bug that I have experienced.  My processor is a qoriq
T1042 powerpc and I am running the fsl-sdk-v2.0-1703 kernel (mainline
v4.1.35-rt41).  In 32 bit, the ath10k and ath9k work without issue.
After migrating to 64 bit, we experienced dma mapping errors with both
devices.  This patch is the only one that applies to a driver, the
rest of the updates performed to fix the dma mapping issues deal with
the sk_buffs are handled in skbuff, mac80211, and netlink.  We worked
with NXP to resolve the issue and I believe they will be handling the
ones that don't apply to the ath10k driver through their process.  If
we don't see them after a while, we will be sending them to the kernel
as well.

Here is the output from the dma mapping problem:

ath10k_pci 0000:01:00.0: unable to get target info from device
ath10k_pci 0000:01:00.0: could not get target info (-5)
ath10k_pci 0000:01:00.0: could not probe fw (-5)
>
> https://wireless.wiki.kernel.org/en/users/drivers/ath10k/submittingpatches#guidelines
>
> --
> Kalle Valo

Jared Bents
Kalle Valo April 24, 2018, 7:32 a.m. UTC | #3
Jared Bents <jared.bents@rockwellcollins.com> writes:

> On Sat, Apr 21, 2018 at 2:10 AM, Kalle Valo <kvalo@codeaurora.org> wrote:
>> Jared Bents <jared.bents@rockwellcollins.com> writes:
>>
>>> Update to convert the use of kmemdup to dma_alloc_coherent as
>>> dma_alloc_coherent will consider DMA region limits such as
>>> those seen with CONFIG_FSL_PCI && CONFIG_ZONE_DMA32 whereas
>>> kmemdup does not take those limitations into account.
>>>
>>> Signed-off-by: Jared Bents <jared.bents@rockwellcollins.com>
>>
>> Does this fix a real bug or is it just a theoretical issue you noticed
>> while looking at the code? If this fixes a real bug please give a
>> description of it.
>
> It fixes a real bug that I have experienced.  My processor is a qoriq
> T1042 powerpc and I am running the fsl-sdk-v2.0-1703 kernel (mainline
> v4.1.35-rt41).  In 32 bit, the ath10k and ath9k work without issue.
> After migrating to 64 bit, we experienced dma mapping errors with both
> devices.  

Ok, please add this to the commit log.

> Here is the output from the dma mapping problem:
>
> ath10k_pci 0000:01:00.0: unable to get target info from device
> ath10k_pci 0000:01:00.0: could not get target info (-5)
> ath10k_pci 0000:01:00.0: could not probe fw (-5)

Please add this also.

And the patch doesn't seem to apply to at all, not sure why. But please
submit v2 and make sure that it applies to my ath.git master branch.

patching file drivers/net/wireless/ath/ath10k/pci.c
Hunk #1 FAILED at 1372.
Hunk #2 FAILED at 1422.
2 out of 2 hunks FAILED -- saving rejects to file drivers/net/wireless/ath/ath10k/pci.c.rej

More info:

https://wireless.wiki.kernel.org/en/users/drivers/ath10k/submittingpatches
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 3c4c800..8637bfe 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1372,28 +1372,16 @@  static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
 	if (resp && resp_len && *resp_len == 0)
 		return -EINVAL;
 
-	treq = kmemdup(req, req_len, GFP_KERNEL);
-	if (!treq)
-		return -ENOMEM;
-
-	req_paddr = dma_map_single(ar->dev, treq, req_len, DMA_TO_DEVICE);
-	ret = dma_mapping_error(ar->dev, req_paddr);
-	if (ret) {
+	treq = dma_alloc_coherent(ar->dev, req_len, &req_paddr, GFP_KERNEL);
+	if (!treq) {
 		ret = -EIO;
 		goto err_dma;
 	}
+	memcpy(treq, req, req_len);
 
 	if (resp && resp_len) {
-		tresp = kzalloc(*resp_len, GFP_KERNEL);
+		tresp = dma_alloc_coherent(ar->dev, *resp_len, &resp_paddr, GFP_KERNEL);
 		if (!tresp) {
-			ret = -ENOMEM;
-			goto err_req;
-		}
-
-		resp_paddr = dma_map_single(ar->dev, tresp, *resp_len,
-					    DMA_FROM_DEVICE);
-		ret = dma_mapping_error(ar->dev, resp_paddr);
-		if (ret) {
 			ret = EIO;
 			goto err_req;
 		}
@@ -1422,23 +1410,19 @@  static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
 	}
 
 err_resp:
+	if (ret == 0 && resp_len) {
+		*resp_len = min(*resp_len, xfer.resp_len);
+		memcpy(resp, tresp, xfer.resp_len);
+	}
 	if (resp) {
 		u32 unused_buffer;
 
 		ath10k_ce_revoke_recv_next(ce_rx, NULL, &unused_buffer);
-		dma_unmap_single(ar->dev, resp_paddr,
-				 *resp_len, DMA_FROM_DEVICE);
+		dma_free_coherent(ar->dev, *resp_len, tresp, resp_paddr);
 	}
 err_req:
-	dma_unmap_single(ar->dev, req_paddr, req_len, DMA_TO_DEVICE);
-
-	if (ret == 0 && resp_len) {
-		*resp_len = min(*resp_len, xfer.resp_len);
-		memcpy(resp, tresp, xfer.resp_len);
-	}
+	dma_free_coherent(ar->dev, req_len, treq, req_paddr);
 err_dma:
-	kfree(treq);
-	kfree(tresp);
 
 	return ret;
 }