From: mike.looijmans@topic.nl (Mike Looijmans)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3] arm/mm/dma-mapping.c: Add arm_coherent_dma_mmap
Date: Wed, 3 Jun 2015 09:52:09 +0200 [thread overview]
Message-ID: <556EB229.1060409@topic.nl> (raw)
In-Reply-To: <1431003257-7794-1-git-send-email-mike.looijmans@topic.nl>
?Ping!
Just curious, any further feedback or comment after Arnd Bergmann's ack?
It fixes a bug that took quite some time to discover and analyze, we should
save other people going through that same trouble.
On 07-05-15 14:54, Mike Looijmans wrote:
> When dma-coherent transfers are enabled, the mmap call must
> not change the pg_prot flags in the vma struct.
>
> Split the arm_dma_mmap into a common and specific parts,
> and add a "arm_coherent_dma_mmap" implementation that does
> not alter the page protection flags.
>
> Tested on a topic-miami board (Zynq) using the ACP port
> to transfer data between FPGA and CPU using the Dyplo
> framework. Without this patch, byte-wise access to mmapped
> coherent DMA memory was about 20x slower because of the
> memory being marked as non-cacheable, and transfer speeds
> would not exceed 240MB/s.
>
> After this patch, the mapped memory is cacheable and the
> transfer speed is again 600MB/s (limited by the FPGA) when
> the data is in the L2 cache, while data integrity is being
> maintained.
>
> The patch has no effect on non-coherent DMA.
>
> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
> ---
> v2: Mistakenly sent the wrong patch which included a devicetree file, removed it from the patch.
> v3: Rebased on current linux master because the patch was made on 3.19 and did not apply cleanly.
>
> arch/arm/mm/dma-mapping.c | 32 +++++++++++++++++++++++++-------
> 1 file changed, 25 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 09c5fe3..d6f5256 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -148,11 +148,14 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
> static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> dma_addr_t handle, struct dma_attrs *attrs);
> +static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> + void *cpu_addr, dma_addr_t dma_addr, size_t size,
> + struct dma_attrs *attrs);
>
> struct dma_map_ops arm_coherent_dma_ops = {
> .alloc = arm_coherent_dma_alloc,
> .free = arm_coherent_dma_free,
> - .mmap = arm_dma_mmap,
> + .mmap = arm_coherent_dma_mmap,
> .get_sgtable = arm_dma_get_sgtable,
> .map_page = arm_coherent_dma_map_page,
> .map_sg = arm_dma_map_sg,
> @@ -690,10 +693,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> attrs, __builtin_return_address(0));
> }
>
> -/*
> - * Create userspace mapping for the DMA-coherent memory.
> - */
> -int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> +static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> void *cpu_addr, dma_addr_t dma_addr, size_t size,
> struct dma_attrs *attrs)
> {
> @@ -704,8 +704,6 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> unsigned long pfn = dma_to_pfn(dev, dma_addr);
> unsigned long off = vma->vm_pgoff;
>
> - vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
> -
> if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
> return ret;
>
> @@ -721,6 +719,26 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> }
>
> /*
> + * Create userspace mapping for the DMA-coherent memory.
> + */
> +static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> + void *cpu_addr, dma_addr_t dma_addr, size_t size,
> + struct dma_attrs *attrs)
> +{
> + return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
> +}
> +
> +int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> + void *cpu_addr, dma_addr_t dma_addr, size_t size,
> + struct dma_attrs *attrs)
> +{
> +#ifdef CONFIG_MMU
> + vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
> +#endif /* CONFIG_MMU */
> + return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
> +}
> +
> +/*
> * Free a buffer as defined by the above mapping.
> */
> static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>
Kind regards,
Mike Looijmans
System Expert
TOPIC Embedded Products
Eindhovenseweg 32-C, NL-5683 KH Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
Telefax: +31 (0) 499 33 69 70
E-mail: mike.looijmans at topicproducts.com
Website: www.topicproducts.com
Please consider the environment before printing this e-mail
WARNING: multiple messages have this Message-ID (diff)
From: Mike Looijmans <mike.looijmans@topic.nl>
To: <linux@arm.linux.org.uk>, <linux-arm-kernel@lists.infradead.org>
Cc: <arnd@arndb.de>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3] arm/mm/dma-mapping.c: Add arm_coherent_dma_mmap
Date: Wed, 3 Jun 2015 09:52:09 +0200 [thread overview]
Message-ID: <556EB229.1060409@topic.nl> (raw)
In-Reply-To: <1431003257-7794-1-git-send-email-mike.looijmans@topic.nl>
Ping!
Just curious, any further feedback or comment after Arnd Bergmann's ack?
It fixes a bug that took quite some time to discover and analyze, we should
save other people going through that same trouble.
On 07-05-15 14:54, Mike Looijmans wrote:
> When dma-coherent transfers are enabled, the mmap call must
> not change the pg_prot flags in the vma struct.
>
> Split the arm_dma_mmap into a common and specific parts,
> and add a "arm_coherent_dma_mmap" implementation that does
> not alter the page protection flags.
>
> Tested on a topic-miami board (Zynq) using the ACP port
> to transfer data between FPGA and CPU using the Dyplo
> framework. Without this patch, byte-wise access to mmapped
> coherent DMA memory was about 20x slower because of the
> memory being marked as non-cacheable, and transfer speeds
> would not exceed 240MB/s.
>
> After this patch, the mapped memory is cacheable and the
> transfer speed is again 600MB/s (limited by the FPGA) when
> the data is in the L2 cache, while data integrity is being
> maintained.
>
> The patch has no effect on non-coherent DMA.
>
> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
> ---
> v2: Mistakenly sent the wrong patch which included a devicetree file, removed it from the patch.
> v3: Rebased on current linux master because the patch was made on 3.19 and did not apply cleanly.
>
> arch/arm/mm/dma-mapping.c | 32 +++++++++++++++++++++++++-------
> 1 file changed, 25 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 09c5fe3..d6f5256 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -148,11 +148,14 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
> static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
> dma_addr_t handle, struct dma_attrs *attrs);
> +static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> + void *cpu_addr, dma_addr_t dma_addr, size_t size,
> + struct dma_attrs *attrs);
>
> struct dma_map_ops arm_coherent_dma_ops = {
> .alloc = arm_coherent_dma_alloc,
> .free = arm_coherent_dma_free,
> - .mmap = arm_dma_mmap,
> + .mmap = arm_coherent_dma_mmap,
> .get_sgtable = arm_dma_get_sgtable,
> .map_page = arm_coherent_dma_map_page,
> .map_sg = arm_dma_map_sg,
> @@ -690,10 +693,7 @@ static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
> attrs, __builtin_return_address(0));
> }
>
> -/*
> - * Create userspace mapping for the DMA-coherent memory.
> - */
> -int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> +static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> void *cpu_addr, dma_addr_t dma_addr, size_t size,
> struct dma_attrs *attrs)
> {
> @@ -704,8 +704,6 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> unsigned long pfn = dma_to_pfn(dev, dma_addr);
> unsigned long off = vma->vm_pgoff;
>
> - vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
> -
> if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
> return ret;
>
> @@ -721,6 +719,26 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> }
>
> /*
> + * Create userspace mapping for the DMA-coherent memory.
> + */
> +static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> + void *cpu_addr, dma_addr_t dma_addr, size_t size,
> + struct dma_attrs *attrs)
> +{
> + return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
> +}
> +
> +int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> + void *cpu_addr, dma_addr_t dma_addr, size_t size,
> + struct dma_attrs *attrs)
> +{
> +#ifdef CONFIG_MMU
> + vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
> +#endif /* CONFIG_MMU */
> + return __arm_dma_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
> +}
> +
> +/*
> * Free a buffer as defined by the above mapping.
> */
> static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
>
Kind regards,
Mike Looijmans
System Expert
TOPIC Embedded Products
Eindhovenseweg 32-C, NL-5683 KH Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
Telefax: +31 (0) 499 33 69 70
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com
Please consider the environment before printing this e-mail
next prev parent reply other threads:[~2015-06-03 7:52 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-07 12:54 [PATCH v3] arm/mm/dma-mapping.c: Add arm_coherent_dma_mmap Mike Looijmans
2015-05-07 12:54 ` Mike Looijmans
2015-05-07 15:18 ` Arnd Bergmann
2015-05-07 15:18 ` Arnd Bergmann
2015-06-03 7:52 ` Mike Looijmans [this message]
2015-06-03 7:52 ` Mike Looijmans
2015-06-03 9:01 ` Arnd Bergmann
2015-06-03 9:01 ` Arnd Bergmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=556EB229.1060409@topic.nl \
--to=mike.looijmans@topic.nl \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.