From: arnd@arndb.de (Arnd Bergmann)
To: linux-arm-kernel@lists.infradead.org
Subject: dma_alloc_coherent versus streaming DMA, neither works satisfactory
Date: Wed, 29 Apr 2015 11:01:35 +0200 [thread overview]
Message-ID: <4351847.Ycu9R2FQB8@wuerfel> (raw)
In-Reply-To: <55409A89.5070008@topic.nl>
On Wednesday 29 April 2015 10:47:05 Mike Looijmans wrote:
> On 23-04-15 14:32, Arnd Bergmann wrote:
> > On Thursday 23 April 2015 13:52:34 Mike Looijmans wrote:
> >> Can anyone here offer some advise on this?
> >>
> >
> > The problem you are experiencing is a direct result of using hardware
> > without cache-coherency from user space. There is no software workaround
> > for this: If you want data to be cacheable *and* avoid doing manual cache
> > flushes each time data is passed between user space and hardware, you have
> > to use hardware that is cache-coherent.
> >
> > You mentioned that you are using 'Zynq', which supports cache-coherent
> > DMA using the 'accelerator coherency port'. If you are able to connect
> > your device to that port, it should work, otherwise you should consider
> > using a different platform.
>
> I tried as you suggested, and used the ACP instead of the HP to connect the
> logic to the CPU.
>
> Without any further changes, this passes all tests with the exact same
> performance numbers. The reason for that is that the driver/DMA framework is
> unaware of the "coherency" hardware and still uses the manual cache
> flush/invalidate routines, so I figured out that adding a "dma-coherent"
> property to the devicetree node changes that.
Correct.
> However, with "dma-coherent" set for my driver, the system locks up at random
> points in the tests. Simple memory transfer tests fail with data mismatches
> (probably stale cache results). Running DMA tests usually results in the
> system completely locking up at some point.
> Normal register read/write access is done through the AXI bus directly, not
> using the ACP at all.
>
> Is the ACP hardware broken, is there some extra things my driver needs to be
> aware of, or is there something else I need to do here?
You still need to synchronize MMIO register accesses with write buffers,
as the readl() and writel() functions do in the kernel.
In particular, after you have written a buffer to memory from the CPU,
you will need to do an outer_sync() before the MMIO write that triggers
the DMA. This is still much cheaper than doing the cache flush though.
On the inbound side, you normally need an MMIO read followed by a dsb
instruction to ensure that data is visible in the cache after you have
received an interrupt from the device. Again that is what readl()
does, but it won't be implied if you do the MMIO from user space.
Another possible problem would be if the driver mmaps the buffer in
uncached mode to user space. This is something your kernel driver has
to get right, it won't be handled automatically by setting the
"dma-coherent" property in DT.
There could of course be some other problem either in your FPGA code,
in your driver, or in your user space. I would not assume that the zynq
ACP itself is broken though.
Arnd
next prev parent reply other threads:[~2015-04-29 9:01 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-23 11:52 dma_alloc_coherent versus streaming DMA, neither works satisfactory Mike Looijmans
2015-04-23 12:32 ` Arnd Bergmann
2015-04-23 13:05 ` Mike Looijmans
2015-04-29 8:47 ` Mike Looijmans
2015-04-29 9:01 ` Arnd Bergmann [this message]
2015-04-29 9:17 ` Russell King - ARM Linux
2015-04-29 9:47 ` Mike Looijmans
2015-04-29 10:07 ` Arnd Bergmann
2015-04-29 10:33 ` Mike Looijmans
2015-04-29 10:41 ` Arnd Bergmann
2015-04-29 12:49 ` Mike Looijmans
2015-04-29 13:13 ` Arnd Bergmann
2015-04-30 13:50 ` Mike Looijmans
2015-04-30 13:54 ` Arnd Bergmann
2015-05-01 6:08 ` Mike Looijmans
2015-05-01 7:01 ` Mike Looijmans
2015-05-07 11:18 ` Mike Looijmans
2015-05-07 11:56 ` Arnd Bergmann
2015-05-07 13:21 ` Daniel Drake
2015-05-07 13:31 ` Mike Looijmans
2015-05-07 14:08 ` Mike Looijmans
2015-05-07 14:30 ` Russell King - ARM Linux
2015-05-08 5:55 ` Mike Looijmans
2015-05-08 7:54 ` Arnd Bergmann
2015-05-08 8:31 ` Mike Looijmans
2015-05-08 13:19 ` Arnd Bergmann
2015-05-08 14:18 ` Mike Looijmans
2015-05-08 14:27 ` Arnd Bergmann
2015-05-08 11:10 ` Russell King - ARM Linux
2015-05-08 12:17 ` Mike Looijmans
2015-04-29 11:09 ` Mike Looijmans
2015-04-29 12:35 ` Arnd Bergmann
2015-04-29 12:52 ` Mike Looijmans
2015-04-29 12:54 ` 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=4351847.Ycu9R2FQB8@wuerfel \
--to=arnd@arndb.de \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox