Re: [RFC/PATCHv2 v2 2/4] dma-mapping: Add dma_remap() APIs

From: Laura Abbott
Date: Wed Apr 27 2016 - 14:16:43 EST


On 04/27/2016 08:25 AM, Catalin Marinas wrote:
On Fri, Apr 22, 2016 at 05:35:16PM -0700, Stephen Boyd wrote:
Quoting Catalin Marinas (2016-04-21 03:35:12)
On Tue, Apr 19, 2016 at 06:04:27PM -0700, Stephen Boyd wrote:
From: Laura Abbott <lauraa@xxxxxxxxxxxxxx>

Some systems are memory constrained but they need to load very
large firmwares. The firmware subsystem allows drivers to request
this firmware be loaded from the filesystem, but this requires
that the entire firmware be loaded into kernel memory first
before it's provided to the driver. This can lead to a situation
where we map the firmware twice, once to load the firmware into
kernel memory and once to copy the firmware into the final
resting place.

This design creates needless memory pressure and delays loading
because we have to copy from kernel memory to somewhere else.
Let's add a couple DMA APIs that allow us to map DMA buffers into
the CPU's address space in arbitrary sizes. With this API, we can
allocate a DMA buffer with DMA_ATTR_NO_KERNEL_MAPPING and move a
small mapping window across our large DMA buffer to load the
firmware directly into buffer.

The first two patches in this series don't make sense to me. I don't
understand what the memory pressure is: physical or virtual? Because
they don't seem to address the former (the DMA buffer is allocated in
full) while the latter doesn't need any addressing at all on arm64, we
have plenty of VA space.

Why do you even need the coherent DMA API? Can you use the streaming API
(map_sg etc.) with a separately allocated buffer?

Hmm I guess I need to add in the patches that show how this is used on
top of "no-map" DT reserved memory regions. There are some more patches
that allow us to assigned reserved memory regions with the "no-map"
attribute to devices and then allocate from those regions using the
coherent DMA APIs. In the downstream kernel it's called a removed dma
pool[1].

So the plan is to wire that all up so that the device can have a
reserved chunk of memory for the firmware that doesn't exist in the
kernel's linear memory mappings. Once we have allocated the region, we
can map it into the kernel's view of memory for a short time so that we
can load the firmware into it (dma_remap part). Once that's over, we
want to destroy the mapping so that we 1) don't use any of the kernel's
virtual memory space (dma_unremap part) to back the buffer and 2) so
that the secure world can protect the memory from the non-secure world.

Does the firmware already know about such memory? If yes, I presume the
kernel would have to be told about it and won't try to map it in the
linear mapping.

At this point, wouldn't a combination of:

dma_declare_coherent_memory()
dma_alloc_from_coherent()
dma_release_from_coherent()
dma_release_declared_memory()

work? The removed_alloc() implementation in the link you posted doesn't
seem far from dma_alloc_from_coherent(). The releasing of the declared
memory above would unmap the memory, so there are no VA mappings left.


The removed alloc was specifically written as a fork of the coherent
pool. This was a choice for ease of out of tree maintenance. The better
choice here would be to fold those features back into dma-coherent.c
if needed.

Thanks,
Laura