linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: catalin.marinas@arm.com (Catalin Marinas)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCHv4 5/5] arm64: Add atomic pool for non-coherent and CMA allocations.
Date: Tue, 22 Jul 2014 22:03:52 +0100	[thread overview]
Message-ID: <20140722210352.GA10604@arm.com> (raw)
In-Reply-To: <201407222006.44666.arnd@arndb.de>

On Tue, Jul 22, 2014 at 07:06:44PM +0100, Arnd Bergmann wrote:
> On Wednesday 02 July 2014, Laura Abbott wrote:
> > +       pgprot_t prot = __pgprot(PROT_NORMAL_NC);
> > +       unsigned long nr_pages = atomic_pool_size >> PAGE_SHIFT;
> > +       struct page *page;
> > +       void *addr;
> > +
> > +
> > +       if (dev_get_cma_area(NULL))
> > +               page = dma_alloc_from_contiguous(NULL, nr_pages,
> > +                                       get_order(atomic_pool_size));
> > +       else
> > +               page = alloc_pages(GFP_KERNEL, get_order(atomic_pool_size));
> > +
> > +
> > +       if (page) {
> > +               int ret;
> > +
> > +               atomic_pool = gen_pool_create(PAGE_SHIFT, -1);
> > +               if (!atomic_pool)
> > +                       goto free_page;
> > +
> > +               addr = dma_common_contiguous_remap(page, atomic_pool_size,
> > +                                       VM_USERMAP, prot, atomic_pool_init);
> > +
> 
> I just stumbled over this thread and noticed the code here: When you do
> alloc_pages() above, you actually get pages that are already mapped into
> the linear kernel mapping as cacheable pages. Your new
> dma_common_contiguous_remap tries to map them as noncacheable. This
> seems broken because it allows the CPU to treat both mappings as
> cacheable, and that won't be coherent with device DMA.

It does *not* allow the CPU to treat both as cacheable. It treats the
non-cacheable mapping as non-cacheable (and the cacheable one as
cacheable). The only requirements the ARM ARM makes in this situation
(B2.9 point 5 in the ARMv8 ARM):

- Before writing to a location not using the Write-Back attribute,
  software must invalidate, or clean, a location from the caches if any
  agent might have written to the location with the Write-Back
  attribute. This avoids the possibility of overwriting the location
  with stale data.
- After writing to a location with the Write-Back attribute, software
  must clean the location from the caches, to make the write visible to
  external memory.
- Before reading the location with a cacheable attribute, software must
  invalidate the location from the caches, to ensure that any value held
  in the caches reflects the last value made visible in external memory.

So we as long as the CPU accesses such memory only via the non-cacheable
mapping, the only requirement is to flush the cache so that there are no
dirty lines that could be evicted.

(if the mismatched attributes were for example Normal vs Device, the
Device guarantees would be lost but in the cacheable vs non-cacheable
it's not too bad; same for ARMv7).

> > +               if (!addr)
> > +                       goto destroy_genpool;
> > +
> > +               memset(addr, 0, atomic_pool_size);
> > +               __dma_flush_range(addr, addr + atomic_pool_size);
> 
> It also seems weird to flush the cache on a virtual address of
> an uncacheable mapping. Is that well-defined?

Yes. According to D5.8.1 (Data and unified caches), "if cache
maintenance is performed on a memory location, the effect of that cache
maintenance is visible to all aliases of that physical memory location.
These properties are consistent with implementing all caches that can
handle data accesses as Physically-indexed, physically-tagged (PIPT)
caches".

> In the CMA case, the
> original mapping should already be uncached here, so you don't need
> to flush it.

I don't think it is non-cacheable already, at least not for arm64 (CMA
can be used on coherent architectures as well).

> In the alloc_pages() case, I think you need to unmap
> the pages from the linear mapping instead.

Even if unmapped, it would not remove dirty cache lines (which are
associated with physical addresses anyway). But we don't need to worry
about unmapping anyway, see above (that's unless we find some
architecture implementation where having such cacheable/non-cacheable
aliases is not efficient enough, the efficiency is not guaranteed by the
ARM ARM, just the correct behaviour).

-- 
Catalin

  reply	other threads:[~2014-07-22 21:03 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-02 18:03 [PATCHv4 0/5] DMA Atomic pool for arm64 Laura Abbott
2014-07-02 18:03 ` [PATCHv4 1/5] lib/genalloc.c: Add power aligned algorithm Laura Abbott
2014-07-03 18:10   ` Will Deacon
2014-07-09 22:35     ` Olof Johansson
2014-07-02 18:03 ` [PATCHv4 2/5] lib/genalloc.c: Add genpool range check function Laura Abbott
2014-07-03 18:14   ` Will Deacon
2014-07-09 22:33   ` Olof Johansson
2014-07-21 19:51     ` Laura Abbott
2014-07-22 15:50       ` Catalin Marinas
2014-07-02 18:03 ` [PATCHv4 3/5] common: dma-mapping: Introduce common remapping functions Laura Abbott
2014-07-09 22:46   ` Olof Johansson
2014-07-18 14:13     ` Catalin Marinas
2014-07-18 13:53   ` Catalin Marinas
2014-07-21 19:33     ` Laura Abbott
2014-07-22 16:04       ` Catalin Marinas
2014-07-02 18:03 ` [PATCHv4 4/5] arm: use genalloc for the atomic pool Laura Abbott
2014-07-04 13:42   ` Thierry Reding
2014-07-21 21:22     ` Laura Abbott
2014-07-02 18:03 ` [PATCHv4 5/5] arm64: Add atomic pool for non-coherent and CMA allocations Laura Abbott
2014-07-04 13:35   ` Thierry Reding
2014-07-21 22:00     ` Laura Abbott
2014-07-18 13:43   ` Catalin Marinas
2014-07-21 22:36     ` Laura Abbott
2014-07-22 15:56       ` Catalin Marinas
2014-07-22 18:06   ` Arnd Bergmann
2014-07-22 21:03     ` Catalin Marinas [this message]
2014-07-22 23:51       ` Laura Abbott
2014-07-23 11:12       ` Arnd Bergmann
  -- strict thread matches above, loose matches on Subject: below --
2014-07-23  1:35 [PATCHv4 0/5] Atomic pool for arm64 Laura Abbott
2014-07-23  1:35 ` [PATCHv4 5/5] arm64: Add atomic pool for non-coherent and CMA allocations Laura Abbott

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=20140722210352.GA10604@arm.com \
    --to=catalin.marinas@arm.com \
    --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;
as well as URLs for NNTP newsgroup(s).