[source] ipq806x: do not allocate coherent memory in dma engine hotpath

LEDE Commits lede-commits at lists.infradead.org
Mon Mar 13 05:41:16 PDT 2017


nbd pushed a commit to source.git, branch master:
https://git.lede-project.org/6006227cb70bd96dcf13bbe473ca53f5af9b3f76

commit 6006227cb70bd96dcf13bbe473ca53f5af9b3f76
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Mon Mar 13 12:31:19 2017 +0100

    ipq806x: do not allocate coherent memory in dma engine hotpath
    
    The available amount of coherent DMA memory is very limited. On Linux
    4.4 this issue was worked around by increasing the pool size.
    
    It turns out that using coherent memory here is completely unnecessary.
    This change reworks the driver code to use kzalloc+dma_map_single
    instead.
    
    Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 .../0002-dmaengine-Add-ADM-driver.patch            | 44 ++++++++++++++--------
 1 file changed, 29 insertions(+), 15 deletions(-)

diff --git a/target/linux/ipq806x/patches-4.9/0002-dmaengine-Add-ADM-driver.patch b/target/linux/ipq806x/patches-4.9/0002-dmaengine-Add-ADM-driver.patch
index 212a902..4ad025c 100644
--- a/target/linux/ipq806x/patches-4.9/0002-dmaengine-Add-ADM-driver.patch
+++ b/target/linux/ipq806x/patches-4.9/0002-dmaengine-Add-ADM-driver.patch
@@ -49,7 +49,7 @@ Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
 +obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
 --- /dev/null
 +++ b/drivers/dma/qcom/qcom_adm.c
-@@ -0,0 +1,900 @@
+@@ -0,0 +1,914 @@
 +/*
 + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 + *
@@ -406,6 +406,7 @@ Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
 +	struct adm_device *adev = achan->adev;
 +	struct adm_async_desc *async_desc;
 +	struct scatterlist *sg;
++	dma_addr_t cple_addr;
 +	u32 i, burst;
 +	u32 single_count = 0, box_count = 0, crci = 0;
 +	void *desc;
@@ -454,7 +455,7 @@ Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
 +		}
 +	}
 +
-+	async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT);
++	async_desc = kzalloc(sizeof(*async_desc), GFP_ATOMIC);
 +	if (!async_desc)
 +		return ERR_PTR(-ENOMEM);
 +
@@ -467,13 +468,9 @@ Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
 +				box_count * sizeof(struct adm_desc_hw_box) +
 +				sizeof(*cple) + 2 * ADM_DESC_ALIGN;
 +
-+	async_desc->cpl = dma_alloc_writecombine(adev->dev, async_desc->dma_len,
-+				&async_desc->dma_addr, GFP_NOWAIT);
-+
-+	if (!async_desc->cpl) {
-+		kfree(async_desc);
-+		return ERR_PTR(-ENOMEM);
-+	}
++	async_desc->cpl = kzalloc(async_desc->dma_len, GFP_ATOMIC);
++	if (!async_desc->cpl)
++		goto free;
 +
 +	async_desc->adev = adev;
 +
@@ -481,10 +478,6 @@ Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
 +	cple = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN);
 +	desc = PTR_ALIGN(cple + 1, ADM_DESC_ALIGN);
 +
-+	/* init cmd list */
-+	*cple = ADM_CPLE_LP;
-+	*cple |= (desc - async_desc->cpl + async_desc->dma_addr) >> 3;
-+
 +	for_each_sg(sgl, sg, sg_len, i) {
 +		async_desc->length += sg_dma_len(sg);
 +
@@ -496,7 +489,27 @@ Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
 +							   direction);
 +	}
 +
++	async_desc->dma_addr = dma_map_single(adev->dev, async_desc->cpl,
++					      async_desc->dma_len,
++					      DMA_TO_DEVICE);
++	if (dma_mapping_error(adev->dev, async_desc->dma_addr))
++		goto free;
++
++	cple_addr = async_desc->dma_addr + ((void *)cple - async_desc->cpl);
++
++	/* init cmd list */
++	dma_sync_single_for_cpu(adev->dev, cple_addr, sizeof(*cple),
++				DMA_TO_DEVICE);
++	*cple = ADM_CPLE_LP;
++	*cple |= (async_desc->dma_addr + ADM_DESC_ALIGN) >> 3;
++	dma_sync_single_for_device(adev->dev, cple_addr, sizeof(*cple),
++				   DMA_TO_DEVICE);
++
 +	return vchan_tx_prep(&achan->vc, &async_desc->vd, flags);
++
++free:
++	kfree(async_desc);
++	return ERR_PTR(-ENOMEM);
 +}
 +
 +/**
@@ -721,8 +734,9 @@ Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
 +	struct adm_async_desc *async_desc = container_of(vd,
 +			struct adm_async_desc, vd);
 +
-+	dma_free_writecombine(async_desc->adev->dev, async_desc->dma_len,
-+		async_desc->cpl, async_desc->dma_addr);
++	dma_unmap_single(async_desc->adev->dev, async_desc->dma_addr,
++			 async_desc->dma_len, DMA_TO_DEVICE);
++	kfree(async_desc->cpl);
 +	kfree(async_desc);
 +}
 +



More information about the lede-commits mailing list