Hello,
This is a snapshot of my work-in-progress on DMA-mapping framework
redesign. All these works are a preparation for adding support for IOMMU
controllers.
DMA-mapping patches have been rebased onto Linux v3.1-rc4 kernel, what
required resolving a bunch of confilcts in the code. The patches have
been heavily tested and all bugs found in the initial version have been
fixed.
Here is the link to the initial version of the DMA-mapping redesign patches:
http://www.spinics.net/lists/linux-mm/msg21241.html
TODO:
- merge the patches with CMA patches and respective changes in
DMA-mapping framework
- start the discussion about chaning alloc_coherent into alloc_attrs in
dma_map_ops structure.
The proof-of-concept IOMMU mapper for DMA-mapping will follow. In next 2
weeks I will be on holidays, so I decided not to delay these patch
anymore longer.
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
Patch summary:
Marek Szyprowski (7):
ARM: dma-mapping: remove offset parameter to prepare for generic
dma_ops
ARM: dma-mapping: use asm-generic/dma-mapping-common.h
ARM: dma-mapping: implement dma sg methods on top of any generic dma
ops
ARM: dma-mapping: move all dma bounce code to separate dma ops
structure
ARM: dma-mapping: remove redundant code and cleanup
common: dma-mapping: change alloc/free_coherent method to more
generic alloc/free_attrs
ARM: dma-mapping: use alloc, mmap, free from dma_ops
arch/arm/Kconfig | 1 +
arch/arm/common/dmabounce.c | 78 ++++++--
arch/arm/include/asm/device.h | 1 +
arch/arm/include/asm/dma-mapping.h | 401 ++++++++++--------------------------
arch/arm/mm/dma-mapping.c | 269 +++++++++++++-----------
include/linux/dma-attrs.h | 1 +
include/linux/dma-mapping.h | 13 +-
7 files changed, 325 insertions(+), 439 deletions(-)
--
1.7.1.569.g6f426
Hello again,
This is yet another round of Contiguous Memory Allocator patches. Now I
implemented all the ideas that has been discussed during Linaro Sprint
meeting.
This version provides a solution for complete integration of CMA to DMA
mapping subsystem on ARM architecture. The issue caused by double dma
pages mapping and possible aliasing in coherent memory mapping has been
finally resolved, both for GFP_ATOMIC case (allocations comes from
coherent memory pool) and non-GFP_ATOMIC case (allocations comes from
CMA managed areas).
For coherent, nommu, ARMv4 and ARMv5 systems the current DMA-mapping
implementation has been kept.
For ARMv6+ systems, CMA has been enabled and a special pool of coherent
memory for atomic allocations has been created. The size of this pool
defaults to CONSISTEN_DMA_SIZE/8, but can be changed with coherent_pool
kernel parameter (if really required).
All atomic allocations are served from this pool. I've did a little
simplification here, because there is no separate pool for writecombine
memory - such requests are also served from coherent pool. I don't think
that such simplification is a problem here - I found no driver that use
dma_alloc_writecombine with GFP_ATOMIC flags.
All non-atomic allocation are served from CMA area. Kernel mapping is
updated to reflect required memory attributes changes. This is possible
because during early boot, all CMA area are remapped with 4KiB pages in
kernel low-memory.
This version have been tested on Samsung S5PC110 based Goni machine and
Exynos4 UniversalC210 board with various V4L2 multimedia drivers.
Coherent atomic allocations has been tested by manually enabling the dma
bounce for the s3c-sdhci device.
All patches are prepared for Linux Kernel v3.1-rc2.
A few words for these who see CMA for the first time:
The Contiguous Memory Allocator (CMA) makes it possible for device
drivers to allocate big contiguous chunks of memory after the system
has booted.
The main difference from the similar frameworks is the fact that CMA
allows to transparently reuse memory region reserved for the big
chunk allocation as a system memory, so no memory is wasted when no
big chunk is allocated. Once the alloc request is issued, the
framework will migrate system pages to create a required big chunk of
physically contiguous memory.
For more information you can refer to nice LWN articles:
http://lwn.net/Articles/447405/ and http://lwn.net/Articles/450286/
as well as links to previous versions of the CMA framework.
The CMA framework has been initially developed by Michal Nazarewicz
at Samsung Poland R&D Center. Since version 9, I've taken over the
development, because Michal has left the company.
TODO (optional):
- implement support for contiguous memory areas placed in HIGHMEM zone
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
Links to previous versions of the patchset:
v14: <http://www.spinics.net/lists/linux-media/msg36536.html>
v13: (internal, intentionally not released)
v12: <http://www.spinics.net/lists/linux-media/msg35674.html>
v11: <http://www.spinics.net/lists/linux-mm/msg21868.html>
v10: <http://www.spinics.net/lists/linux-mm/msg20761.html>
v9: <http://article.gmane.org/gmane.linux.kernel.mm/60787>
v8: <http://article.gmane.org/gmane.linux.kernel.mm/56855>
v7: <http://article.gmane.org/gmane.linux.kernel.mm/55626>
v6: <http://article.gmane.org/gmane.linux.kernel.mm/55626>
v5: (intentionally left out as CMA v5 was identical to CMA v4)
v4: <http://article.gmane.org/gmane.linux.kernel.mm/52010>
v3: <http://article.gmane.org/gmane.linux.kernel.mm/51573>
v2: <http://article.gmane.org/gmane.linux.kernel.mm/50986>
v1: <http://article.gmane.org/gmane.linux.kernel.mm/50669>
Changelog:
v15:
1. fixed calculation of the total memory after activating CMA area (was
broken from v12)
2. more code cleanup in drivers/base/dma-contiguous.c
3. added address limit for default CMA area
4. rewrote ARM DMA integration:
- removed "ARM: DMA: steal memory for DMA coherent mappings" patch
- kept current DMA mapping implementation for coherent, nommu and
ARMv4/ARMv5 systems
- enabled CMA for all ARMv6+ systems
- added separate, small pool for coherent atomic allocations, defaults
to CONSISTENT_DMA_SIZE/8, but can be changed with kernel parameter
coherent_pool=[size]
v14:
1. Merged with "ARM: DMA: steal memory for DMA coherent mappings"
patch, added support for GFP_ATOMIC allocations.
2. Added checks for NULL device pointer
v13: (internal, intentionally not released)
v12:
1. Fixed 2 nasty bugs in dma-contiguous allocator:
- alignment argument was not passed correctly
- range for dma_release_from_contiguous was not checked correctly
2. Added support for architecture specfic dma_contiguous_early_fixup()
function
3. CMA and DMA-mapping integration for ARM architechture has been
rewritten to take care of the memory aliasing issue that might
happen for newer ARM CPUs (mapping of the same pages with different
cache attributes is forbidden). TODO: add support for GFP_ATOMIC
allocations basing on the "ARM: DMA: steal memory for DMA coherent
mappings" patch and implement support for contiguous memory areas
that are placed in HIGHMEM zone
v11:
1. Removed genalloc usage and replaced it with direct calls to
bitmap_* functions, dropped patches that are not needed
anymore (genalloc extensions)
2. Moved all contiguous area management code from mm/cma.c
to drivers/base/dma-contiguous.c
3. Renamed cm_alloc/free to dma_alloc/release_from_contiguous
4. Introduced global, system wide (default) contiguous area
configured with kernel config and kernel cmdline parameters
5. Simplified initialization to just one function:
dma_declare_contiguous()
6. Added example of device private memory contiguous area
v10:
1. Rebased onto 3.0-rc2 and resolved all conflicts
2. Simplified CMA to be just a pure memory allocator, for use
with platfrom/bus specific subsystems, like dma-mapping.
Removed all device specific functions are calls.
3. Integrated with ARM DMA-mapping subsystem.
4. Code cleanup here and there.
5. Removed private context support.
v9: 1. Rebased onto 2.6.39-rc1 and resolved all conflicts
2. Fixed a bunch of nasty bugs that happened when the allocation
failed (mainly kernel oops due to NULL ptr dereference).
3. Introduced testing code: cma-regions compatibility layer and
videobuf2-cma memory allocator module.
v8: 1. The alloc_contig_range() function has now been separated from
CMA and put in page_allocator.c. This function tries to
migrate all LRU pages in specified range and then allocate the
range using alloc_contig_freed_pages().
2. Support for MIGRATE_CMA has been separated from the CMA code.
I have not tested if CMA works with ZONE_MOVABLE but I see no
reasons why it shouldn't.
3. I have added a @private argument when creating CMA contexts so
that one can reserve memory and not share it with the rest of
the system. This way, CMA acts only as allocation algorithm.
v7: 1. A lot of functionality that handled driver->allocator_context
mapping has been removed from the patchset. This is not to say
that this code is not needed, it's just not worth posting
everything in one patchset.
Currently, CMA is "just" an allocator. It uses it's own
migratetype (MIGRATE_CMA) for defining ranges of pageblokcs
which behave just like ZONE_MOVABLE but dispite the latter can
be put in arbitrary places.
2. The migration code that was introduced in the previous version
actually started working.
v6: 1. Most importantly, v6 introduces support for memory migration.
The implementation is not yet complete though.
Migration support means that when CMA is not using memory
reserved for it, page allocator can allocate pages from it.
When CMA wants to use the memory, the pages have to be moved
and/or evicted as to make room for CMA.
To make it possible it must be guaranteed that only movable and
reclaimable pages are allocated in CMA controlled regions.
This is done by introducing a MIGRATE_CMA migrate type that
guarantees exactly that.
Some of the migration code is "borrowed" from Kamezawa
Hiroyuki's alloc_contig_pages() implementation. The main
difference is that thanks to MIGRATE_CMA migrate type CMA
assumes that memory controlled by CMA are is always movable or
reclaimable so that it makes allocation decisions regardless of
the whether some pages are actually allocated and migrates them
if needed.
The most interesting patches from the patchset that implement
the functionality are:
09/13: mm: alloc_contig_free_pages() added
10/13: mm: MIGRATE_CMA migration type added
11/13: mm: MIGRATE_CMA isolation functions added
12/13: mm: cma: Migration support added [wip]
Currently, kernel panics in some situations which I am trying
to investigate.
2. cma_pin() and cma_unpin() functions has been added (after
a conversation with Johan Mossberg). The idea is that whenever
hardware does not use the memory (no transaction is on) the
chunk can be moved around. This would allow defragmentation to
be implemented if desired. No defragmentation algorithm is
provided at this time.
3. Sysfs support has been replaced with debugfs. I always felt
unsure about the sysfs interface and when Greg KH pointed it
out I finally got to rewrite it to debugfs.
v5: (intentionally left out as CMA v5 was identical to CMA v4)
v4: 1. The "asterisk" flag has been removed in favour of requiring
that platform will provide a "*=<regions>" rule in the map
attribute.
2. The terminology has been changed slightly renaming "kind" to
"type" of memory. In the previous revisions, the documentation
indicated that device drivers define memory kinds and now,
v3: 1. The command line parameters have been removed (and moved to
a separate patch, the fourth one). As a consequence, the
cma_set_defaults() function has been changed -- it no longer
accepts a string with list of regions but an array of regions.
2. The "asterisk" attribute has been removed. Now, each region
has an "asterisk" flag which lets one specify whether this
region should by considered "asterisk" region.
3. SysFS support has been moved to a separate patch (the third one
in the series) and now also includes list of regions.
v2: 1. The "cma_map" command line have been removed. In exchange,
a SysFS entry has been created under kernel/mm/contiguous.
The intended way of specifying the attributes is
a cma_set_defaults() function called by platform initialisation
code. "regions" attribute (the string specified by "cma"
command line parameter) can be overwritten with command line
parameter; the other attributes can be changed during run-time
using the SysFS entries.
2. The behaviour of the "map" attribute has been modified
slightly. Currently, if no rule matches given device it is
assigned regions specified by the "asterisk" attribute. It is
by default built from the region names given in "regions"
attribute.
3. Devices can register private regions as well as regions that
can be shared but are not reserved using standard CMA
mechanisms. A private region has no name and can be accessed
only by devices that have the pointer to it.
4. The way allocators are registered has changed. Currently,
a cma_allocator_register() function is used for that purpose.
Moreover, allocators are attached to regions the first time
memory is registered from the region or when allocator is
registered which means that allocators can be dynamic modules
that are loaded after the kernel booted (of course, it won't be
possible to allocate a chunk of memory from a region if
allocator is not loaded).
5. Index of new functions:
+static inline dma_addr_t __must_check
+cma_alloc_from(const char *regions, size_t size,
+ dma_addr_t alignment)
+static inline int
+cma_info_about(struct cma_info *info, const const char *regions)
+int __must_check cma_region_register(struct cma_region *reg);
+dma_addr_t __must_check
+cma_alloc_from_region(struct cma_region *reg,
+ size_t size, dma_addr_t alignment);
+static inline dma_addr_t __must_check
+cma_alloc_from(const char *regions,
+ size_t size, dma_addr_t alignment);
+int cma_allocator_register(struct cma_allocator *alloc);
Patches in this patchset:
mm: move some functions from memory_hotplug.c to page_isolation.c
mm: alloc_contig_freed_pages() added
Code "stolen" from Kamezawa. The first patch just moves code
around and the second provide function for "allocates" already
freed memory.
mm: alloc_contig_range() added
This is what Kamezawa asked: a function that tries to migrate all
pages from given range and then use alloc_contig_freed_pages()
(defined by the previous commit) to allocate those pages.
mm: MIGRATE_CMA migration type added
mm: MIGRATE_CMA isolation functions added
Introduction of the new migratetype and support for it in CMA.
MIGRATE_CMA works similar to ZONE_MOVABLE expect almost any
memory range can be marked as one.
mm: cma: Contiguous Memory Allocator added
The code CMA code. Manages CMA contexts and performs memory
allocations.
ARM: integrate CMA with dma-mapping subsystem
Main client of CMA frame work. CMA serves as a alloc_pages()
replacement.
ARM: S5PV210: example of CMA private area for FIMC device on Goni board
Example of platform/board specific code that creates cma
context and assigns it to particular device.
Patch summary:
KAMEZAWA Hiroyuki (2):
mm: move some functions from memory_hotplug.c to page_isolation.c
mm: alloc_contig_freed_pages() added
Marek Szyprowski (3):
drivers: add Contiguous Memory Allocator
ARM: integrate CMA with DMA-mapping subsystem
ARM: S5PV210: example of CMA private area for FIMC device on Goni
board
Michal Nazarewicz (3):
mm: alloc_contig_range() added
mm: MIGRATE_CMA migration type added
mm: MIGRATE_CMA isolation functions added
arch/Kconfig | 3 +
arch/arm/Kconfig | 2 +
arch/arm/include/asm/device.h | 3 +
arch/arm/include/asm/dma-contiguous.h | 33 +++
arch/arm/include/asm/mach/map.h | 1 +
arch/arm/mach-s5pv210/mach-goni.c | 4 +
arch/arm/mm/dma-mapping.c | 362 +++++++++++++++++++++++++------
arch/arm/mm/init.c | 8 +
arch/arm/mm/mm.h | 3 +
arch/arm/mm/mmu.c | 29 ++-
drivers/base/Kconfig | 79 +++++++
drivers/base/Makefile | 1 +
drivers/base/dma-contiguous.c | 386 +++++++++++++++++++++++++++++++++
include/linux/dma-contiguous.h | 102 +++++++++
include/linux/mmzone.h | 41 +++-
include/linux/page-isolation.h | 51 ++++-
mm/Kconfig | 8 +-
mm/compaction.c | 10 +
mm/memory_hotplug.c | 111 ----------
mm/page_alloc.c | 287 ++++++++++++++++++++++--
mm/page_isolation.c | 129 +++++++++++-
21 files changed, 1417 insertions(+), 236 deletions(-)
create mode 100644 arch/arm/include/asm/dma-contiguous.h
create mode 100644 drivers/base/dma-contiguous.c
create mode 100644 include/linux/dma-contiguous.h
--
1.7.1.569.g6f426
On Wed, Sep 14, 2011 at 2:57 AM, Thomas Hellstrom <thomas(a)shipmail.org> wrote:
>>>>>>>>>
>>>>>>>>> +static struct drm_ioctl_desc samsung_ioctls[] = {
>>>>>>>>> + DRM_IOCTL_DEF_DRV(SAMSUNG_GEM_CREATE,
>>>>>>>>> samsung_drm_gem_create_ioctl,
>>>>>>>>> + DRM_UNLOCKED | DRM_AUTH),
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>> Hi!
>>>>>>>>
>>>>>>>> With reference my previous security comment.
>>>>>>>>
>>>>>>>> Let's say you have a compromised video player running as a DRM
>>>>>>>> client, that
>>>>>>>> tries to repeatedly allocate huge GEM buffers...
>>>>>>>>
>>>>>>>> What will happen when all DMA memory is exhausted? Will this cause
>>>>>>>> other
>>>>>>>> device drivers to see an OOM, or only DRM?
>>>>>>>>
>>>>>>>> The old DRI model basically allowed any authorized DRI client to
>>>>>>>> exhaust
>>>>>>>> video ram or AGP memory, but never system memory. Newer DRI drivers
>>>>>>>> typically only allow DRI masters to do that.
>>>>>>>> as
>>>>>>>>
>>>>>>>> I don't think an authorized DRI client should be able to easily
>>>>>>>>
>>>>>
>>>>> exhaust
>>>>>
>>>>>>>>
>>>>>>>> resources (DMA memory) used by other device drivers causing them to
>>>>>>>> fail.
>>>>>>>>
>>>>>>>
>>>>>>> I'm not entirely sure what else can be done, other than have a
>>>>>>> threshold on max MB allocatable of buffer memory..
>>>>>>>
>>>>>>
>>>>>> Yes, I think that's what needs to be done, and that threshold should
>>>>>> be low enough to keep other device drivers running in the worst
>>>>>> allocation case.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> In the samsung driver case, he is only allocating scanout memory
>>>>>>>
>>>
>>> from
>>>
>>>>>>>
>>>>>>> CMA, so the limit will be the CMA region size.. beyond that you
>>>>>>>
>>>
>>> can't
>>>
>>>>>>>
>>>>>>> get physically contiguous memory. So I think this driver is safe.
>>>>>>>
>>>>>>
>>>>>> It's not really what well-behaved user-space drivers do that should
>>>>>>
>>>
>>> be
>>>
>>>>>>
>>>>>> a concern, but what compromized application *might* do that is a
>>>>>>
>>>>
>>>> concern.
>>>>
>>>>>
>>>>> Hmm. I might have missed your point here. If the buffer allocation
>>>>>
>>>
>>> ioctl
>>>
>>>>>
>>>>> only allows allocating CMA memory, then I agree the driver fits the old
>>>>> DRI security model, as long as no other devices on the platform will
>>>>> ever use CMA.
>>>>>
>>>>> But in that case, there really should be a way for the driver to say
>>>>> "Hey, all CMA memory on this system is mine", in the same way
>>>>> traditional video drivers can claim the VRAM PCI resource.
>>>>>
>>>>>
>>>>
>>>> CMA could reserve memory region for a specific driver so DRM Client
>>>>
>>>
>>> could
>>>
>>>>
>>>> request memory allocation from only the region.
>>>>
>>>>
>>>>>
>>>>> This is to avoid the possibility that future drivers that need CMA will
>>>>> be vulnerable to DOS-attacks from ill-behaved DRI clients.
>>>>>
>>>>>
>>>>
>>>> Thomas, if any application has root authority for ill-purpose then isn't
>>>>
>>>
>>> it
>>>
>>>>
>>>> possible to be vulnerable to DOS-attacks? I think DRM_AUTH means root
>>>> authority. I know DRM Framework gives any root application DRM_AUTH
>>>> authority for compatibility.
>>>>
>>>
>>> DRM_AUTH just means that the client has authenticated w/ X11 (meaning
>>> that it has permission to connect to x server)..
>>>
>>>
>>
>> Yes, I understood so. but see drm_open_helper() of drm_fops.c file please.
>> in this function, you can see a line below.
>> /* for compatibility root is always authenticated */
>> priv->authenticated = capable(CAP_SYS_ADMIN)
>>
>> I think the code above says that any application with root permission is
>> authenticated.
>>
>>
>
> Yes, that is true. A root client may be assumed to have AUTH permissions,
> but the inverse does not hold, meaning that an AUTH client may *not* be
> assumed to have root permissions. I think there is a ROOT_ONLY ioctl flag
> for that.
>
> The problem I'm seeing compared to other drivers is the following:
>
> Imagine for example that you have a disc driver that allocates temporary
> memory out of the same DMA pool as the DRM driver.
>
> Now you have a video player that is a DRM client. It contains a security
> flaw and is compromized by somebody trying to play a specially crafted video
> stream. The video player starts to allocate gem buffers until it receives an
> -ENOMEM. Then it stops allocating and does nothing.
>
> Now the system tries an important disc access (paging for example). This
> fails, because the video player has exhausted all DMA memory and the disc
> driver fails to allocate.
>
> The system is dead.
>
> The point is:
>
> If there is a chance that other drivers will use the same DMA/CMA pool as
> the DRM driver, DRM must leave enough DMA/CMA memory for those drivers to
> work.
ah, ok, I get your point
> The difference compared to other drm drivers:
>
> There are other drm drivers that work the same way, with a static allocator.
> For example "via" and "sis". But those drivers completely claim the
> resources they are using. Nobody else is expected to use VRAM / AGP.
>
> In the Samsung case, it's not clear to me whether the DMA/CMA pool *can* be
> shared with other devices.
> If it is, IMHO you must implement an allocation limit in DRM, if not, the
> driver should probably be safe.
It is possible to create a device private CMA pool.. although OTOH it
might be desirable to let some other drivers (like v4l2) use buffers
from the same pool..
I'm not entirely sure what will happen w/ dma_alloc_coherent, etc, if
the global CMA pool is exhausted.
Marek? I guess you know what would happen?
BR,
-R
> Thanks,
> Thomas
Hi,
The following change fixes a bug, which causes releasing incorrect iova space, in this patch. It fixes compilation error either.
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 82d5134..8c16ed7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -900,10 +900,8 @@ static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t si
unsigned int count = size >> PAGE_SHIFT;
int i;
- for (i=0; i<count; i++) {
- iommu_unmap(mapping->domain, iova, 0);
- iova += PAGE_SIZE;
- }
+ for (i=0; i<count; i++)
+ iommu_unmap(mapping->domain, iova + i * PAGE_SIZE, 0);
__free_iova(mapping, iova, size);
return 0;
}
@@ -1073,7 +1071,7 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
size += sg->length;
}
__map_sg_chunk(dev, start, size, &dma->dma_address, dir);
- d->dma_address += offset;
+ dma->dma_address += offset;
return count;
-KR
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information. Any unauthorized review, use, disclosure or distribution
is prohibited. If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
This RFC is aimed at introducing the buffer sharing framework for review.
Since almost all the discussion about buffer sharing objects happened on
linaro-mm-sig list, I am sending it first for review within the list, and
will share it with other lists after first-set of review comments from here.
--
This is the first step in defining a buffer sharing framework.
A new buffer object is added, with hooks to allow for easy sharing of
this buffer object across devices.
The idea was first mooted at the Linaro memory management mini-summit in
Budapest in May 2011, as part of multiple things needed for a 'unified memory
management framework'. It took a more concrete shape at Linaro memory-management
mini-summit in Cambridge, Aug 2011.
The framework allows:
- a new buffer-object to be created, which associates a file pointer with each
user-buffer and associated allocator-defined operations on that buffer.
This operation is called the 'export' operation.
- this exported buffer-object to be shared with the other entity by asking for
its 'file-descriptor (fd)', and sharing the fd across.
- a received fd to get the buffer object back, where it can be accessed using
the associated allocator-defined operations.
- the exporter and importer to share the scatterlist using get_ and put_
operations.
Some file operations are provided as wrappers over the allocator-defined
operations, which allows usage of fops(eg mmap) on the associated 'fd'.
This is based on design suggestions from many people at both the mini-summits,
most notably from Arnd Bergmann <arnd(a)arndb.de>, and Rob Clark <rob(a)ti.com>.
The implementation is inspired from proof-of-concept patch-set from
Tomasz Stanislawski <t.stanislaws(a)samsung.com>, who demonstrated buffer sharing
between two v4l2 devices.
Signed-off-by: Sumit Semwal <sumit.semwal(a)ti.com>
---
drivers/base/Kconfig | 10 +++
drivers/base/Makefile | 1 +
drivers/base/dma-buf.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/dma-buf.h | 105 +++++++++++++++++++++++++
4 files changed, 312 insertions(+), 0 deletions(-)
create mode 100644 drivers/base/dma-buf.c
create mode 100644 include/linux/dma-buf.h
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index d57e8d0..5398ce8 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -168,4 +168,14 @@ config SYS_HYPERVISOR
bool
default n
+config DMA_SHARED_BUFFER
+ bool "Buffer framework to be shared between drivers"
+ default n
+ depends on ANON_INODES
+ help
+ This option enables the framework for buffer-sharing between
+ multiple drivers. A buffer is associated with a file using driver
+ APIs extension; the file's descriptor can then be passed on to other
+ driver.
+
endmenu
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 4c5701c..bd95732 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
+obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
new file mode 100644
index 0000000..e35b385
--- /dev/null
+++ b/drivers/base/dma-buf.c
@@ -0,0 +1,196 @@
+/*
+ * Framework for buffer objects that can be shared across devices/subsystems.
+ *
+ * Copyright(C) 2011 Texas Instruments Inc. All rights reserved.
+ * Author: Sumit Semwal <sumit.semwal(a)ti.com>
+ *
+ * Many thanks to linaro-mm-sig list, and specially
+ * Arnd Bergmann <arnd(a)arndb.de> and Rob Clark <rob(a)ti.com>
+ * for their support in creation and refining of this idea.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/dma-buf.h>
+#include <linux/anon_inodes.h>
+
+static int is_dma_buf_file(struct file *);
+
+/* file operation wrappers for dma buf ops */
+static ssize_t dma_buf_read(struct file *file, char __user *buf, size_t size,
+ loff_t *offset)
+{
+ struct dma_buf *dmabuf;
+
+ if (!is_dma_buf_file(file))
+ return -EINVAL;
+
+ dmabuf = file->private_data;
+ return dmabuf->ops->read(dmabuf, buf, size);
+}
+
+static ssize_t dma_buf_write(struct file *file, char __user *buf, size_t size,
+ loff_t *offset)
+{
+ struct dma_buf *dmabuf;
+
+ if (!is_dma_buf_file(file))
+ return -EINVAL;
+
+ dmabuf = file->private_data;
+ return dmabuf->ops->write(dmabuf, buf, size);
+}
+
+static int dma_buf_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct dma_buf *dmabuf;
+
+ if (!is_dma_buf_file(file))
+ return -EINVAL;
+
+ dmabuf = file->private_data;
+ return dmabuf->ops->mmap(dmabuf, vma);
+}
+
+static int dma_buf_release(struct inode *inode, struct file *file)
+{
+ struct dma_buf *dmabuf;
+
+ if (!is_dma_buf_file(file))
+ return -EINVAL;
+
+ dmabuf = file->private_data;
+
+ dmabuf->ops->release(dmabuf);
+ kfree(dmabuf);
+ return 0;
+}
+
+static const struct file_operations dma_buf_fops = {
+ .mmap = dma_buf_mmap,
+ .read = dma_buf_read,
+ .write = dma_buf_write,
+ .release = dma_buf_release,
+};
+
+/*
+ * is_dma_buf_file - Check if struct file* is associated with dma_buf
+ */
+static inline int is_dma_buf_file(struct file *file)
+{
+ return file->f_op == &dma_buf_fops;
+}
+
+/**
+ * dma_buf_export - Creates a new dma_buf, and associates an anon file
+ * with this buffer,so it can be exported.
+ * Also 'attach' the allocator specific data and ops to the buffer.
+ *
+ * @priv: Attach private data of allocator to this buffer
+ * @ops: Attach allocator-defined dma buf ops to the new buffer.
+ *
+ * Returns, on success, a newly created dma_buf object, which wraps the
+ * supplied private data and operations for dma_buf_ops. On failure to
+ * allocate the dma_buf object, it can return NULL.
+ *
+ */
+struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops)
+{
+ struct dma_buf *dmabuf;
+ struct file *file;
+
+ BUG_ON(!priv || !ops);
+
+ dmabuf = kzalloc(sizeof(struct dma_buf), GFP_KERNEL);
+ if (dmabuf == NULL)
+ return dmabuf;
+
+ dmabuf->priv = priv;
+ dmabuf->ops = ops;
+
+ file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, 0);
+
+ dmabuf->file = file;
+ file->private_data = dmabuf;
+
+ return dmabuf;
+}
+EXPORT_SYMBOL(dma_buf_export);
+
+/**
+ * dma_buf_fd - returns a file descriptor for the given dma_buf
+ * @dmabuf: [in] pointer to dma_buf for which fd is required.
+ *
+ * On success, returns an associated 'fd'. Else, returns error.
+ */
+int dma_buf_fd(struct dma_buf *dmabuf)
+{
+ int error, fd;
+
+ if (!dmabuf->file)
+ return -EINVAL;
+
+ error = get_unused_fd_flags(0);
+ if (error < 0)
+ return error;
+ fd = error;
+
+ fd_install(fd, dmabuf->file);
+
+ return fd;
+}
+EXPORT_SYMBOL(dma_buf_fd);
+
+/**
+ * dma_buf_get - returns the dma_buf structure related to an fd
+ * @fd: [in] fd associated with the dma_buf to be returned
+ *
+ * On success, returns the dma_buf structure associated with an fd; uses
+ * file's refcounting done by fget to increase refcount. returns ERR_PTR
+ * otherwise.
+ */
+struct dma_buf *dma_buf_get(int fd)
+{
+ struct file *file;
+
+ file = fget(fd);
+
+ if (!file)
+ return ERR_PTR(-EBADF);
+
+ if (!is_dma_buf_file(file)) {
+ fput(file);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return file->private_data;
+}
+EXPORT_SYMBOL(dma_buf_get);
+
+/**
+ * dma_buf_put - decreases refcount of the buffer
+ * @dmabuf: [in] buffer to reduce refcount of
+ *
+ * Uses file's refcounting done implicitly by fput()
+ */
+void dma_buf_put(struct dma_buf *dmabuf)
+{
+ BUG_ON(!dmabuf->file);
+
+ fput(dmabuf->file);
+
+ return;
+}
+EXPORT_SYMBOL(dma_buf_put);
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
new file mode 100644
index 0000000..c22896a
--- /dev/null
+++ b/include/linux/dma-buf.h
@@ -0,0 +1,105 @@
+/*
+ * Header file for dma buffer sharing framework.
+ *
+ * Copyright(C) 2011 Texas Instruments Inc. All rights reserved.
+ * Author: Sumit Semwal <sumit.semwal(a)ti.com>
+ *
+ * Many thanks to linaro-mm-sig list, and specially
+ * Arnd Bergmann <arnd(a)arndb.de> and Rob Clark <rob(a)ti.com>
+ * for their support in creation and refining of this idea.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __DMA_BUF_H__
+#define __DMA_BUF_H__
+
+#include <linux/file.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/scatterlist.h>
+
+struct dma_buf;
+
+/**
+ * struct dma_buf_ops - operations possible on struct dmabuf
+ * @get_scatterlist: returns list of scatter pages allocated, increases
+ * usecount of the buffer
+ * @put_scatterlist: decreases usecount of buffer, might deallocate scatter
+ * pages
+ * @mmap: map this buffer
+ * @read: read from this buffer
+ * @write: write to this buffer
+ * @release: release this buffer; to be called after the last dma_buf_put
+ * @sync_sg_for_cpu: sync the sg list for cpu
+ * @sync_sg_for_device: synch the sg list for device
+ */
+struct dma_buf_ops {
+ /* allow buffer to not be pinned when DMA is not happening */
+ struct scatterlist * (*get_scatterlist)(struct dma_buf *);
+ void (*put_scatterlist)(struct dma_buf *, struct scatterlist *);
+
+ /* allow allocator to mmap/read/write to take care of cache attrib */
+ int (*mmap)(struct dma_buf *, struct vm_area_struct *);
+ ssize_t (*read)(struct dma_buf *, void *, size_t);
+ ssize_t (*write)(struct dma_buf *, void *, size_t);
+ /* after final dma_buf_put() */
+ void (*release)(struct dma_buf *);
+
+ /* allow allocator to take care of cache ops */
+ void (*sync_sg_for_cpu) (struct dma_buf *, struct device *);
+ void (*sync_sg_for_device)(struct dma_buf *, struct device *);
+};
+
+/**
+ * struct dma_buf - shared buffer object
+ * @file: file pointer used for sharing buffers across, and for refcounting.
+ * @ops: dma_buf_ops associated with this buffer object
+ * @priv: user specific private data
+ */
+struct dma_buf {
+ struct file *file;
+ struct dma_buf_ops *ops;
+ void *priv;
+};
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+
+struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops);
+int dma_buf_fd(struct dma_buf *dmabuf);
+struct dma_buf *dma_buf_get(int fd);
+void dma_buf_put(struct dma_buf *dmabuf);
+
+#else
+static inline struct dma_buf *dma_buf_export(void *priv,
+ struct dma_buf_ops *ops)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline int dma_buf_fd(struct dma_buf *dmabuf)
+{
+ return -ENODEV;
+}
+
+static inline struct dma_buf *dma_buf_get(int fd)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline void dma_buf_put(struct dma_buf *dmabuf)
+{
+ return;
+}
+#endif /* CONFIG_DMA_SHARED_BUFFER */
+
+#endif /* __DMA_BUF_H__ */
--
1.7.4.1
Hello again,
Like I promissed on Linaro Sprint meeting, yet another round of
Contiguous Memory Allocator patches are now available. I hope that this
version finally solves all pending issues and can be widely tested in
ARM platform as well as finally be merged to -next kernel tree for even
more testing.
This version provides a solution for complete integration of CMA to DMA
mapping subsystem on ARM architecture. The issue caused by double dma
pages mapping and possible aliasing in coherent memory mapping has been
finally resolved, both for GFP_ATOMIC case (allocations comes from
reserved DMA memory pool) and non-GFP_ATOMIC case (allocations comes
from CMA managed areas).
All patches are prepared for Linux Kernel v3.1-rc1.
A few words for these who see CMA for the first time:
The Contiguous Memory Allocator (CMA) makes it possible for device
drivers to allocate big contiguous chunks of memory after the system
has booted.
The main difference from the similar frameworks is the fact that CMA
allows to transparently reuse memory region reserved for the big
chunk allocation as a system memory, so no memory is wasted when no
big chunk is allocated. Once the alloc request is issued, the
framework will migrate system pages to create a required big chunk of
physically contiguous memory.
For more information you can refer to nice LWN articles:
http://lwn.net/Articles/447405/ and http://lwn.net/Articles/450286/
as well as links to previous versions of the CMA framework.
The CMA framework has been initially developed by Michal Nazarewicz
at Samsung Poland R&D Center. Since version 9, I've taken over the
development, because Michal has left the company.
The current version of CMA is a set of helper functions for DMA mapping
framework that handles allocation of contiguous memory blocks. The
difference between this patchset and Kamezawa's alloc_contig_pages()
are:
1. alloc_contig_pages() requires MAX_ORDER alignment of allocations
which may be unsuitable for embeded systems where a few MiBs are
required.
Lack of the requirement on the alignment means that several threads
might try to access the same pageblock/page. To prevent this from
happening CMA uses a mutex so that only one allocating/releasing
function may run at one point.
2. CMA may use its own migratetype (MIGRATE_CMA) which behaves
similarly to ZONE_MOVABLE but can be put in arbitrary places.
This is required for us since we need to define two disjoint memory
ranges inside system RAM. (ie. in two memory banks (do not confuse
with nodes)).
3. alloc_contig_pages() scans memory in search for range that could be
migrated. CMA on the other hand maintains its own allocator to
decide where to allocate memory for device drivers and then tries
to migrate pages from that part if needed. This is not strictly
required but I somehow feel it might be faster.
The integration with ARM DMA-mapping subsystem is done on 2 levels.
During early boot memory reserved for contiguous areas are remapped with
2-level page tables. This enables us to change cache attributes of the
individual pages from such area on request. Then, DMA mapping subsystem
is updated to use dma_alloc_from_contiguous() call instead of
alloc_pages() and perform page attributes remapping.
Current version have been tested on Samsung S5PC110 based Goni machine
and s5p-fimc V4L2 driver. The driver itself uses videobuf2 dma-contig
memory allocator, which in turn relies on dma_alloc_coherent() from
DMA-mapping subsystem. By integrating CMA with DMA-mapping we managed to
get this driver working with CMA without any single change required in
the driver or videobuf2-dma-contig allocator.
TODO (optional):
- implement support for contiguous memory areas placed in HIGHMEM zone
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
Links to previous versions of the patchset:
v13: (internal, intentionally not released)
v12: <http://www.spinics.net/lists/linux-media/msg35674.html>
v11: <http://www.spinics.net/lists/linux-mm/msg21868.html>
v10: <http://www.spinics.net/lists/linux-mm/msg20761.html>
v9: <http://article.gmane.org/gmane.linux.kernel.mm/60787>
v8: <http://article.gmane.org/gmane.linux.kernel.mm/56855>
v7: <http://article.gmane.org/gmane.linux.kernel.mm/55626>
v6: <http://article.gmane.org/gmane.linux.kernel.mm/55626>
v5: (intentionally left out as CMA v5 was identical to CMA v4)
v4: <http://article.gmane.org/gmane.linux.kernel.mm/52010>
v3: <http://article.gmane.org/gmane.linux.kernel.mm/51573>
v2: <http://article.gmane.org/gmane.linux.kernel.mm/50986>
v1: <http://article.gmane.org/gmane.linux.kernel.mm/50669>
Changelog:
v14:
1. Merged with "ARM: DMA: steal memory for DMA coherent mappings"
patch, added support for GFP_ATOMIC allocations.
2. Added checks for NULL device pointer
v13: (internal, intentionally not released)
v12:
1. Fixed 2 nasty bugs in dma-contiguous allocator:
- alignment argument was not passed correctly
- range for dma_release_from_contiguous was not checked correctly
2. Added support for architecture specfic dma_contiguous_early_fixup()
function
3. CMA and DMA-mapping integration for ARM architechture has been
rewritten to take care of the memory aliasing issue that might
happen for newer ARM CPUs (mapping of the same pages with different
cache attributes is forbidden). TODO: add support for GFP_ATOMIC
allocations basing on the "ARM: DMA: steal memory for DMA coherent
mappings" patch and implement support for contiguous memory areas
that are placed in HIGHMEM zone
v11:
1. Removed genalloc usage and replaced it with direct calls to
bitmap_* functions, dropped patches that are not needed
anymore (genalloc extensions)
2. Moved all contiguous area management code from mm/cma.c
to drivers/base/dma-contiguous.c
3. Renamed cm_alloc/free to dma_alloc/release_from_contiguous
4. Introduced global, system wide (default) contiguous area
configured with kernel config and kernel cmdline parameters
5. Simplified initialization to just one function:
dma_declare_contiguous()
6. Added example of device private memory contiguous area
v10:
1. Rebased onto 3.0-rc2 and resolved all conflicts
2. Simplified CMA to be just a pure memory allocator, for use
with platfrom/bus specific subsystems, like dma-mapping.
Removed all device specific functions are calls.
3. Integrated with ARM DMA-mapping subsystem.
4. Code cleanup here and there.
5. Removed private context support.
v9: 1. Rebased onto 2.6.39-rc1 and resolved all conflicts
2. Fixed a bunch of nasty bugs that happened when the allocation
failed (mainly kernel oops due to NULL ptr dereference).
3. Introduced testing code: cma-regions compatibility layer and
videobuf2-cma memory allocator module.
v8: 1. The alloc_contig_range() function has now been separated from
CMA and put in page_allocator.c. This function tries to
migrate all LRU pages in specified range and then allocate the
range using alloc_contig_freed_pages().
2. Support for MIGRATE_CMA has been separated from the CMA code.
I have not tested if CMA works with ZONE_MOVABLE but I see no
reasons why it shouldn't.
3. I have added a @private argument when creating CMA contexts so
that one can reserve memory and not share it with the rest of
the system. This way, CMA acts only as allocation algorithm.
v7: 1. A lot of functionality that handled driver->allocator_context
mapping has been removed from the patchset. This is not to say
that this code is not needed, it's just not worth posting
everything in one patchset.
Currently, CMA is "just" an allocator. It uses it's own
migratetype (MIGRATE_CMA) for defining ranges of pageblokcs
which behave just like ZONE_MOVABLE but dispite the latter can
be put in arbitrary places.
2. The migration code that was introduced in the previous version
actually started working.
v6: 1. Most importantly, v6 introduces support for memory migration.
The implementation is not yet complete though.
Migration support means that when CMA is not using memory
reserved for it, page allocator can allocate pages from it.
When CMA wants to use the memory, the pages have to be moved
and/or evicted as to make room for CMA.
To make it possible it must be guaranteed that only movable and
reclaimable pages are allocated in CMA controlled regions.
This is done by introducing a MIGRATE_CMA migrate type that
guarantees exactly that.
Some of the migration code is "borrowed" from Kamezawa
Hiroyuki's alloc_contig_pages() implementation. The main
difference is that thanks to MIGRATE_CMA migrate type CMA
assumes that memory controlled by CMA are is always movable or
reclaimable so that it makes allocation decisions regardless of
the whether some pages are actually allocated and migrates them
if needed.
The most interesting patches from the patchset that implement
the functionality are:
09/13: mm: alloc_contig_free_pages() added
10/13: mm: MIGRATE_CMA migration type added
11/13: mm: MIGRATE_CMA isolation functions added
12/13: mm: cma: Migration support added [wip]
Currently, kernel panics in some situations which I am trying
to investigate.
2. cma_pin() and cma_unpin() functions has been added (after
a conversation with Johan Mossberg). The idea is that whenever
hardware does not use the memory (no transaction is on) the
chunk can be moved around. This would allow defragmentation to
be implemented if desired. No defragmentation algorithm is
provided at this time.
3. Sysfs support has been replaced with debugfs. I always felt
unsure about the sysfs interface and when Greg KH pointed it
out I finally got to rewrite it to debugfs.
v5: (intentionally left out as CMA v5 was identical to CMA v4)
v4: 1. The "asterisk" flag has been removed in favour of requiring
that platform will provide a "*=<regions>" rule in the map
attribute.
2. The terminology has been changed slightly renaming "kind" to
"type" of memory. In the previous revisions, the documentation
indicated that device drivers define memory kinds and now,
v3: 1. The command line parameters have been removed (and moved to
a separate patch, the fourth one). As a consequence, the
cma_set_defaults() function has been changed -- it no longer
accepts a string with list of regions but an array of regions.
2. The "asterisk" attribute has been removed. Now, each region
has an "asterisk" flag which lets one specify whether this
region should by considered "asterisk" region.
3. SysFS support has been moved to a separate patch (the third one
in the series) and now also includes list of regions.
v2: 1. The "cma_map" command line have been removed. In exchange,
a SysFS entry has been created under kernel/mm/contiguous.
The intended way of specifying the attributes is
a cma_set_defaults() function called by platform initialisation
code. "regions" attribute (the string specified by "cma"
command line parameter) can be overwritten with command line
parameter; the other attributes can be changed during run-time
using the SysFS entries.
2. The behaviour of the "map" attribute has been modified
slightly. Currently, if no rule matches given device it is
assigned regions specified by the "asterisk" attribute. It is
by default built from the region names given in "regions"
attribute.
3. Devices can register private regions as well as regions that
can be shared but are not reserved using standard CMA
mechanisms. A private region has no name and can be accessed
only by devices that have the pointer to it.
4. The way allocators are registered has changed. Currently,
a cma_allocator_register() function is used for that purpose.
Moreover, allocators are attached to regions the first time
memory is registered from the region or when allocator is
registered which means that allocators can be dynamic modules
that are loaded after the kernel booted (of course, it won't be
possible to allocate a chunk of memory from a region if
allocator is not loaded).
5. Index of new functions:
+static inline dma_addr_t __must_check
+cma_alloc_from(const char *regions, size_t size,
+ dma_addr_t alignment)
+static inline int
+cma_info_about(struct cma_info *info, const const char *regions)
+int __must_check cma_region_register(struct cma_region *reg);
+dma_addr_t __must_check
+cma_alloc_from_region(struct cma_region *reg,
+ size_t size, dma_addr_t alignment);
+static inline dma_addr_t __must_check
+cma_alloc_from(const char *regions,
+ size_t size, dma_addr_t alignment);
+int cma_allocator_register(struct cma_allocator *alloc);
Patches in this patchset:
mm: move some functions from memory_hotplug.c to page_isolation.c
mm: alloc_contig_freed_pages() added
Code "stolen" from Kamezawa. The first patch just moves code
around and the second provide function for "allocates" already
freed memory.
mm: alloc_contig_range() added
This is what Kamezawa asked: a function that tries to migrate all
pages from given range and then use alloc_contig_freed_pages()
(defined by the previous commit) to allocate those pages.
mm: MIGRATE_CMA migration type added
mm: MIGRATE_CMA isolation functions added
Introduction of the new migratetype and support for it in CMA.
MIGRATE_CMA works similar to ZONE_MOVABLE expect almost any
memory range can be marked as one.
mm: cma: Contiguous Memory Allocator added
The code CMA code. Manages CMA contexts and performs memory
allocations.
ARM: DMA: steal memory for DMA coherent mappings
Ancillary patch with significant DMA-mapping subsystem redesing,
resolves double mapping issue by creating DMA exclusive memory
area.
ARM: integrate CMA with dma-mapping subsystem
Main client of CMA frame work. CMA serves as a alloc_pages()
replacement.
ARM: S5PV210: example of CMA private area for FIMC device on Goni board
Example of platform/board specific code that creates cma
context and assigns it to particular device.
Patch summary:
KAMEZAWA Hiroyuki (2):
mm: move some functions from memory_hotplug.c to page_isolation.c
mm: alloc_contig_freed_pages() added
Marek Szyprowski (3):
drivers: add Contiguous Memory Allocator
ARM: integrate CMA with DMA-mapping subsystem
ARM: S5PV210: example of CMA private area for FIMC device on Goni
board
Michal Nazarewicz (3):
mm: alloc_contig_range() added
mm: MIGRATE_CMA migration type added
mm: MIGRATE_CMA isolation functions added
Russell King (1):
ARM: DMA: steal memory for DMA coherent mappings
arch/Kconfig | 3 +
arch/arm/Kconfig | 1 +
arch/arm/include/asm/device.h | 3 +
arch/arm/include/asm/dma-contiguous.h | 33 +++
arch/arm/include/asm/dma-mapping.h | 3 +-
arch/arm/include/asm/mach/map.h | 3 +
arch/arm/include/asm/memory.h | 7 +
arch/arm/mach-s5pv210/Kconfig | 1 +
arch/arm/mach-s5pv210/mach-goni.c | 4 +
arch/arm/mm/dma-mapping.c | 462 ++++++++++++++++++++-------------
arch/arm/mm/init.c | 4 +
arch/arm/mm/mm.h | 5 +
arch/arm/mm/mmu.c | 53 +++-
drivers/base/Kconfig | 77 ++++++
drivers/base/Makefile | 1 +
drivers/base/dma-contiguous.c | 396 ++++++++++++++++++++++++++++
include/linux/dma-contiguous.h | 106 ++++++++
include/linux/mmzone.h | 41 +++-
include/linux/page-isolation.h | 51 +++-
mm/Kconfig | 8 +-
mm/compaction.c | 10 +
mm/memory_hotplug.c | 111 --------
mm/page_alloc.c | 287 +++++++++++++++++++--
mm/page_isolation.c | 129 +++++++++-
24 files changed, 1449 insertions(+), 350 deletions(-)
create mode 100644 arch/arm/include/asm/dma-contiguous.h
create mode 100644 drivers/base/dma-contiguous.c
create mode 100644 include/linux/dma-contiguous.h
--
1.7.1.569.g6f426
Hi,
I know it is very early but here it is a tryout of the dma_map_sg and
dma_unmap_sg with iommu, I made it to roughly understand what is needed to
remove drivers/omap-iovmm.c (which is a virtual memory manager
implementation on top of omap iommu driver).
This patch is placed on top of Marek Szyprowsk initial work:
ARM: DMA-mapping & IOMMU integration
http://thread.gmane.org/gmane.linux.kernel.mm/63727/
It was tested on an OMAP zoom3 platform and tidspbridge driver. The patch
is used to map user space buffers to dsp's iommu, get_user_pages is used to
form the sg list that will be passed to dma_map_sg.
While at it, I bumped into some issues that I would like to get some
feedback or know if they are being considered:
1. There is no way to keep track of what virtual address are being mapped
in the scatterlist, which we need to propagate to the dsp, in order that it
knows where does the buffers start and end on its virtual address space.
I ended up adding an iov_address to scatterlist which if accepted should be
toggled/affected by the selection of CONFIG_IOMMU_API.
2. tidspbridge driver sometimes needs to map a physical address into a
fixed virtual address (i.e. the start of a firmware section is expected to
be at dsp va 0x20000000), there is no straight forward way to do this with
the dma api given that it only expects to receive a cpu_addr, a sg or a
page, by adding iov_address I could pass phys and iov addresses in a sg
and overcome this limitation, but, these addresses belong to:
2a. Shared memory between ARM and DSP: this memory is allocated through
memblock API which takes it out of kernel control to be later
ioremap'd and iommu map'd to the dsp (this because a non-cacheable
requirement), so, these physical addresses doesn't have a linear
virtual address translation, which is what dma api expects.
2b. Bus addresses: of dsp peripherals which are also ioremap'd and
affected by the same thing.
So: kmemcheck_mark_initialized(sg_virt(s), s->length);
sg_virt might be returning a wrong virtual address, which is different to
what ioremap returns.
I leave the code below and appreciate any comments or feedback
Regards,
Omar
---
arch/arm/mm/dma-mapping.c | 68 +++++++++++++++++++++++++++++++++++++
drivers/iommu/omap-iommu.c | 9 ++++-
include/asm-generic/scatterlist.h | 3 ++
3 files changed, 79 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index b6397c1..2cc4853 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1318,10 +1318,78 @@ void arm_iommu_free_attrs(struct device *dev,
size_t size, void *cpu_addr,
mutex_unlock(&mapping->lock);
}
+int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ struct scatterlist *s;
+ dma_addr_t iova;
+ size_t size = 0;
+ int i, j;
+
+ BUG_ON(!valid_dma_direction(dir));
+
+ /* XXX do not assume al ents of PAGE_SIZE */
+ size = nents * PAGE_SIZE;
+ iova = gen_pool_alloc(mapping->pool, size);
+ if (iova == 0)
+ return 0;
+
+ for_each_sg(sg, s, nents, i) {
+ int ret;
+ unsigned int phys = page_to_phys(sg_page(s));
+
+ /* XXX Add arch flags */
+ ret = iommu_map(mapping->domain, iova, phys, 0, 0);
+ if (ret < 0)
+ goto bad_mapping;
+
+ s->iov_address = iova;
+ iova += PAGE_SIZE;
+
+ /* XXX do something on error to clean iommu map*/
+ s->dma_address = __dma_map_page(dev, sg_page(s), s->offset,
+ s->length, dir);
+ if (dma_mapping_error(dev, s->dma_address))
+ goto bad_mapping;
+ }
+ debug_dma_map_sg(dev, sg, nents, nents, dir);
+ return nents;
+
+ bad_mapping:
+ for_each_sg(sg, s, i, j)
+ __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ return 0;
+
+}
+
+void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t iova = sg_iov_address(sg);
+ struct scatterlist *s;
+ size_t size = 0;
+ int i;
+
+ debug_dma_unmap_sg(dev, sg, nents, dir);
+
+ for_each_sg(sg, s, nents, i) {
+ __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ iommu_unmap(mapping->domain, sg_iov_address(s), 0);
+ }
+
+ size = nents * PAGE_SIZE;
+ gen_pool_free(mapping->pool, iova, size);
+}
+
+
struct arm_dma_map_ops iommu_ops = {
.alloc_attrs = arm_iommu_alloc_attrs,
.free_attrs = arm_iommu_free_attrs,
.mmap_attrs = arm_iommu_mmap_attrs,
+ .map_sg = arm_iommu_map_sg,
+ .unmap_sg = arm_iommu_unmap_sg,
};
EXPORT_SYMBOL_GPL(iommu_ops);
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 9b21b80..6b2a3e1 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -22,6 +22,7 @@
#include <linux/mutex.h>
#include <asm/cacheflush.h>
+#include <asm/dma-iommu.h>
#include <plat/iommu.h>
#include <plat/iopgtable.h>
@@ -879,9 +880,15 @@ EXPORT_SYMBOL_GPL(iommu_set_da_range);
*/
struct device *omap_find_iommu_device(const char *name)
{
- return driver_find_device(&omap_iommu_driver.driver, NULL,
+ struct device *dev;
+
+ dev = driver_find_device(&omap_iommu_driver.driver, NULL,
(void *)name,
device_match_by_alias);
+
+ arm_iommu_assign_device(dev, 0x204f0000, 0x304f0000);
+
+ return dev;
}
EXPORT_SYMBOL_GPL(omap_find_iommu_device);
diff --git a/include/asm-generic/scatterlist.h
b/include/asm-generic/scatterlist.h
index 5de0735..831d626 100644
--- a/include/asm-generic/scatterlist.h
+++ b/include/asm-generic/scatterlist.h
@@ -11,6 +11,7 @@ struct scatterlist {
unsigned int offset;
unsigned int length;
dma_addr_t dma_address;
+ dma_addr_t iov_address;
#ifdef CONFIG_NEED_SG_DMA_LENGTH
unsigned int dma_length;
#endif
@@ -25,6 +26,8 @@ struct scatterlist {
*/
#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_iov_address(sg) ((sg)->iov_address)
+
#ifdef CONFIG_NEED_SG_DMA_LENGTH
#define sg_dma_len(sg) ((sg)->dma_length)
#else
--
1.7.0.4
Hello Everyone,
This patchset introduces the proof-of-concept infrastructure for buffer
sharing between multiple devices using file descriptors. The
infrastructure has been integrated with V4L2 framework, more
specifically videobuf2 and two S5P drivers FIMC (capture interface) and
TV drivers, but it can be easily used by other kernel subsystems, like DRI.
In this patch the buffer object has been simplified to absolute minimum
- it contains only the buffer physical address (only physically
contiguous buffers are supported), but this can be easily extended to
complete scatter list in the future.
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
Hi all,
For those that tried to participate remotely yesterday, I have a
couple of updates:
1) We've added an extra microphone in the middle of the room in the
hopes of picking up the sound better.
2) We've gotten the room signed on to the correct IRC channel (#linaro-corpus).
cheers,
Jesse
Hi all,
Sorry for the late notice, but it turns out we have remote access for
the memory management sessions at the Linaro Connect in Cambourne this
week,, starting right now today, same time tomorrow and Wednesday.
Dial-in details are available at
http://connect.linaro.org/events/event/linux-on-arm/, the room is
Corpus Christi, and the channel for the room is #connect-corpus.
cheers,
Jesse
Hello,
This patch series is a continuation of my works on implementing generic
IOMMU support in DMA mapping framework for ARM architecture. Now I
focused on the DMA mapping framework itself. It turned out that adding
support for common dma_map_ops structure was not that hard as I initally
thought. After some modification most of the code fits really well to
the generic dma_map_ops methods.
The only change required to dma_map_ops is a new alloc function. During
the discussion on Linaro Memory Management meeting in Budapest we got
the idea that we can have only one alloc/free/mmap function with
additional attributes argument. This way all different kinds of
architecture specific buffer mappings can be hidden behind the
attributes without the need of creating several versions of dma_alloc_
function. I also noticed that the dma_alloc_noncoherent() function can
be also implemented this way with DMA_ATTRIB_NON_COHERENT attribute.
Systems that just defines dma_alloc_noncoherent as dma_alloc_coherent
will just ignore such attribute.
Another good use case for alloc methods with attributes is the
possibility to allocate buffer without a valid kernel mapping. There are
a number of drivers (mainly V4L2 and ALSA) that only exports the DMA
buffers to user space. Such drivers don't touch the buffer data at all.
For such buffers we can avoid the creation of a mapping in kernel
virtual address space, saving precious vmalloc area. Such buffers might
be allocated once a new attribute DMA_ATTRIB_NO_KERNEL_MAPPING.
All the changes introduced in this patch series are intended to prepare
a good ground for upcoming generic IOMMU integration to DMA mapping
framework on ARM architecture.
For more information about proof-of-concept IOMMU implementation in DMA
mapping framework, please refer to my previous set of patches:
http://www.spinics.net/lists/linux-mm/msg19856.html
I've tried to split the redesign into a set of single-step changes for
easier review and understanding. If there is anything that needs further
clarification, please don't hesitate to ask.
The patches are prepared on top of Linux Kernel v3.0-rc3.
The proposed changes have been tested on Samsung Exynos4 platform. I've
also tested dmabounce code (by manually registering support for DMA
bounce for some of the devices available on my board), although my
hardware have no such strict requirements. Would be great if one could
test my patches on different ARM architectures to check if I didn't
break anything.
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
Patch summary:
Marek Szyprowski (8):
ARM: dma-mapping: remove offset parameter to prepare for generic
dma_ops
ARM: dma-mapping: implement dma_map_single on top of dma_map_page
ARM: dma-mapping: use asm-generic/dma-mapping-common.h
ARM: dma-mapping: implement dma sg methods on top of generic dma ops
ARM: dma-mapping: move all dma bounce code to separate dma ops
structure
ARM: dma-mapping: remove redundant code and cleanup
common: dma-mapping: change alloc/free_coherent method to more
generic alloc/free_attrs
ARM: dma-mapping: use alloc, mmap, free from dma_ops
arch/arm/Kconfig | 1 +
arch/arm/common/dmabounce.c | 112 +++--
arch/arm/include/asm/device.h | 1 +
arch/arm/include/asm/dma-mapping.h | 835 +++++++++++++-----------------------
arch/arm/mm/dma-mapping.c | 278 +++++++------
include/linux/dma-attrs.h | 1 +
include/linux/dma-mapping.h | 13 +-
7 files changed, 539 insertions(+), 702 deletions(-)
rewrite arch/arm/include/asm/dma-mapping.h (66%)
--
1.7.1.569.g6f426
Hello everyone,
This is yet another round of Contiguous Memory Allocator patches. Now I
focused mainly on the integration of CMA to DMA mapping subsystem on ARM
architecture. In this version I've tried to solve the issue of the
aliasing in coherent memory mapping that was present in earlier versions
of DMA mapping framework.
The proposed solution should be considered as a proof-of-concept. Right
now it doesn't support GFP_ATOMIC allocations. Support for them is on my
TODO list and will be implemented on top of the "ARM: DMA: steal memory
for DMA coherent mappings" patch by Russell King.
A few words for these who see CMA for the first time:
The Contiguous Memory Allocator (CMA) makes it possible for device
drivers to allocate big contiguous chunks of memory after the system
has booted.
The main difference from the similar frameworks is the fact that CMA
allows to transparently reuse memory region reserved for the big
chunk allocation as a system memory, so no memory is wasted when no
big chunk is allocated. Once the alloc request is issued, the
framework will migrate system pages to create a required big chunk of
physically contiguous memory.
For more information you can refer to nice LWN articles:
http://lwn.net/Articles/447405/ and http://lwn.net/Articles/450286/
as well as links to previous versions of the CMA framework.
The CMA framework has been initially developed by Michal Nazarewicz
at Samsung Poland R&D Center. Since version 9, I've taken over the
development, because Michal has left the company.
The current version of CMA is a set of helper functions for DMA mapping
framework that handles allocation of contiguous memory blocks. The
difference between this patchset and Kamezawa's alloc_contig_pages()
are:
1. alloc_contig_pages() requires MAX_ORDER alignment of allocations
which may be unsuitable for embeded systems where a few MiBs are
required.
Lack of the requirement on the alignment means that several threads
might try to access the same pageblock/page. To prevent this from
happening CMA uses a mutex so that only one allocating/releasing
function may run at one point.
2. CMA may use its own migratetype (MIGRATE_CMA) which behaves
similarly to ZONE_MOVABLE but can be put in arbitrary places.
This is required for us since we need to define two disjoint memory
ranges inside system RAM. (ie. in two memory banks (do not confuse
with nodes)).
3. alloc_contig_pages() scans memory in search for range that could be
migrated. CMA on the other hand maintains its own allocator to
decide where to allocate memory for device drivers and then tries
to migrate pages from that part if needed. This is not strictly
required but I somehow feel it might be faster.
The integration with ARM DMA-mapping subsystem is done on 2 levels.
During early boot memory reserved for contiguous areas are remapped with
2-level page tables. This enables us to change cache attributes of the
individual pages from such area on request. Then, DMA mapping subsystem
is updated to use dma_alloc_from_contiguous() call instead of
alloc_pages() and perform page attributes remapping.
Current version have been tested on Samsung S5PC110 based Goni machine
and s5p-fimc V4L2 driver. The driver itself uses videobuf2 dma-contig
memory allocator, which in turn relies on dma_alloc_coherent() from
DMA-mapping subsystem. By integrating CMA with DMA-mapping we managed to
get this driver working with CMA without any single change required in
the driver or videobuf2-dma-contig allocator.
TODO:
- implement GPF_ATOMIC allocations
- implement support for contiguous memory areas placed in HIGHMEM zone
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
Links to previous versions of the patchset:
v11: <http://www.spinics.net/lists/linux-mm/msg21868.html>
v10: <http://www.spinics.net/lists/linux-mm/msg20761.html>
v9: <http://article.gmane.org/gmane.linux.kernel.mm/60787>
v8: <http://article.gmane.org/gmane.linux.kernel.mm/56855>
v7: <http://article.gmane.org/gmane.linux.kernel.mm/55626>
v6: <http://article.gmane.org/gmane.linux.kernel.mm/55626>
v5: (intentionally left out as CMA v5 was identical to CMA v4)
v4: <http://article.gmane.org/gmane.linux.kernel.mm/52010>
v3: <http://article.gmane.org/gmane.linux.kernel.mm/51573>
v2: <http://article.gmane.org/gmane.linux.kernel.mm/50986>
v1: <http://article.gmane.org/gmane.linux.kernel.mm/50669>
Changelog:
v12:
1. Fixed 2 nasty bugs in dma-contiguous allocator:
- alignment argument was not passed correctly
- range for dma_release_from_contiguous was not checked correctly
2. Added support for architecture specfic dma_contiguous_early_fixup()
function
3. CMA and DMA-mapping integration for ARM architechture has been
rewritten to take care of the memory aliasing issue that might
happen for newer ARM CPUs (mapping of the same pages with different
cache attributes is forbidden). TODO: add support for GFP_ATOMIC
allocations basing on the "ARM: DMA: steal memory for DMA coherent
mappings" patch and implement support for contiguous memory areas
that are placed in HIGHMEM zone
v11:
1. Removed genalloc usage and replaced it with direct calls to
bitmap_* functions, dropped patches that are not needed
anymore (genalloc extensions)
2. Moved all contiguous area management code from mm/cma.c
to drivers/base/dma-contiguous.c
3. Renamed cm_alloc/free to dma_alloc/release_from_contiguous
4. Introduced global, system wide (default) contiguous area
configured with kernel config and kernel cmdline parameters
5. Simplified initialization to just one function:
dma_declare_contiguous()
6. Added example of device private memory contiguous area
v10:
1. Rebased onto 3.0-rc2 and resolved all conflicts
2. Simplified CMA to be just a pure memory allocator, for use
with platfrom/bus specific subsystems, like dma-mapping.
Removed all device specific functions are calls.
3. Integrated with ARM DMA-mapping subsystem.
4. Code cleanup here and there.
5. Removed private context support.
v9: 1. Rebased onto 2.6.39-rc1 and resolved all conflicts
2. Fixed a bunch of nasty bugs that happened when the allocation
failed (mainly kernel oops due to NULL ptr dereference).
3. Introduced testing code: cma-regions compatibility layer and
videobuf2-cma memory allocator module.
v8: 1. The alloc_contig_range() function has now been separated from
CMA and put in page_allocator.c. This function tries to
migrate all LRU pages in specified range and then allocate the
range using alloc_contig_freed_pages().
2. Support for MIGRATE_CMA has been separated from the CMA code.
I have not tested if CMA works with ZONE_MOVABLE but I see no
reasons why it shouldn't.
3. I have added a @private argument when creating CMA contexts so
that one can reserve memory and not share it with the rest of
the system. This way, CMA acts only as allocation algorithm.
v7: 1. A lot of functionality that handled driver->allocator_context
mapping has been removed from the patchset. This is not to say
that this code is not needed, it's just not worth posting
everything in one patchset.
Currently, CMA is "just" an allocator. It uses it's own
migratetype (MIGRATE_CMA) for defining ranges of pageblokcs
which behave just like ZONE_MOVABLE but dispite the latter can
be put in arbitrary places.
2. The migration code that was introduced in the previous version
actually started working.
v6: 1. Most importantly, v6 introduces support for memory migration.
The implementation is not yet complete though.
Migration support means that when CMA is not using memory
reserved for it, page allocator can allocate pages from it.
When CMA wants to use the memory, the pages have to be moved
and/or evicted as to make room for CMA.
To make it possible it must be guaranteed that only movable and
reclaimable pages are allocated in CMA controlled regions.
This is done by introducing a MIGRATE_CMA migrate type that
guarantees exactly that.
Some of the migration code is "borrowed" from Kamezawa
Hiroyuki's alloc_contig_pages() implementation. The main
difference is that thanks to MIGRATE_CMA migrate type CMA
assumes that memory controlled by CMA are is always movable or
reclaimable so that it makes allocation decisions regardless of
the whether some pages are actually allocated and migrates them
if needed.
The most interesting patches from the patchset that implement
the functionality are:
09/13: mm: alloc_contig_free_pages() added
10/13: mm: MIGRATE_CMA migration type added
11/13: mm: MIGRATE_CMA isolation functions added
12/13: mm: cma: Migration support added [wip]
Currently, kernel panics in some situations which I am trying
to investigate.
2. cma_pin() and cma_unpin() functions has been added (after
a conversation with Johan Mossberg). The idea is that whenever
hardware does not use the memory (no transaction is on) the
chunk can be moved around. This would allow defragmentation to
be implemented if desired. No defragmentation algorithm is
provided at this time.
3. Sysfs support has been replaced with debugfs. I always felt
unsure about the sysfs interface and when Greg KH pointed it
out I finally got to rewrite it to debugfs.
v5: (intentionally left out as CMA v5 was identical to CMA v4)
v4: 1. The "asterisk" flag has been removed in favour of requiring
that platform will provide a "*=<regions>" rule in the map
attribute.
2. The terminology has been changed slightly renaming "kind" to
"type" of memory. In the previous revisions, the documentation
indicated that device drivers define memory kinds and now,
v3: 1. The command line parameters have been removed (and moved to
a separate patch, the fourth one). As a consequence, the
cma_set_defaults() function has been changed -- it no longer
accepts a string with list of regions but an array of regions.
2. The "asterisk" attribute has been removed. Now, each region
has an "asterisk" flag which lets one specify whether this
region should by considered "asterisk" region.
3. SysFS support has been moved to a separate patch (the third one
in the series) and now also includes list of regions.
v2: 1. The "cma_map" command line have been removed. In exchange,
a SysFS entry has been created under kernel/mm/contiguous.
The intended way of specifying the attributes is
a cma_set_defaults() function called by platform initialisation
code. "regions" attribute (the string specified by "cma"
command line parameter) can be overwritten with command line
parameter; the other attributes can be changed during run-time
using the SysFS entries.
2. The behaviour of the "map" attribute has been modified
slightly. Currently, if no rule matches given device it is
assigned regions specified by the "asterisk" attribute. It is
by default built from the region names given in "regions"
attribute.
3. Devices can register private regions as well as regions that
can be shared but are not reserved using standard CMA
mechanisms. A private region has no name and can be accessed
only by devices that have the pointer to it.
4. The way allocators are registered has changed. Currently,
a cma_allocator_register() function is used for that purpose.
Moreover, allocators are attached to regions the first time
memory is registered from the region or when allocator is
registered which means that allocators can be dynamic modules
that are loaded after the kernel booted (of course, it won't be
possible to allocate a chunk of memory from a region if
allocator is not loaded).
5. Index of new functions:
+static inline dma_addr_t __must_check
+cma_alloc_from(const char *regions, size_t size,
+ dma_addr_t alignment)
+static inline int
+cma_info_about(struct cma_info *info, const const char *regions)
+int __must_check cma_region_register(struct cma_region *reg);
+dma_addr_t __must_check
+cma_alloc_from_region(struct cma_region *reg,
+ size_t size, dma_addr_t alignment);
+static inline dma_addr_t __must_check
+cma_alloc_from(const char *regions,
+ size_t size, dma_addr_t alignment);
+int cma_allocator_register(struct cma_allocator *alloc);
Patches in this patchset:
mm: move some functions from memory_hotplug.c to page_isolation.c
mm: alloc_contig_freed_pages() added
Code "stolen" from Kamezawa. The first patch just moves code
around and the second provide function for "allocates" already
freed memory.
mm: alloc_contig_range() added
This is what Kamezawa asked: a function that tries to migrate all
pages from given range and then use alloc_contig_freed_pages()
(defined by the previous commit) to allocate those pages.
mm: MIGRATE_CMA migration type added
mm: MIGRATE_CMA isolation functions added
Introduction of the new migratetype and support for it in CMA.
MIGRATE_CMA works similar to ZONE_MOVABLE expect almost any
memory range can be marked as one.
mm: cma: Contiguous Memory Allocator added
The code CMA code. Manages CMA contexts and performs memory
allocations.
ARM: integrate CMA with dma-mapping subsystem
Main client of CMA frame work. CMA serves as a alloc_pages()
replacement.
ARM: S5PV210: example of CMA private area for FIMC device on Goni board
Example of platform/board specific code that creates cma
context and assigns it to particular device.
Patch summary:
KAMEZAWA Hiroyuki (2):
mm: move some functions from memory_hotplug.c to page_isolation.c
mm: alloc_contig_freed_pages() added
Marek Szyprowski (3):
drivers: add Contiguous Memory Allocator
ARM: integrate CMA with dma-mapping subsystem
ARM: S5PV210: example of CMA private area for FIMC device on Goni
board
Michal Nazarewicz (3):
mm: alloc_contig_range() added
mm: MIGRATE_CMA migration type added
mm: MIGRATE_CMA isolation functions added
arch/Kconfig | 3 +
arch/arm/Kconfig | 1 +
arch/arm/include/asm/device.h | 3 +
arch/arm/include/asm/dma-contiguous.h | 33 +++
arch/arm/include/asm/mach/map.h | 1 +
arch/arm/mach-s5pv210/Kconfig | 1 +
arch/arm/mach-s5pv210/mach-goni.c | 8 +
arch/arm/mm/dma-mapping.c | 244 +++-----------------
arch/arm/mm/init.c | 3 +
arch/arm/mm/mmu.c | 56 +++++-
drivers/base/Kconfig | 77 +++++++
drivers/base/Makefile | 1 +
drivers/base/dma-contiguous.c | 396 +++++++++++++++++++++++++++++++++
include/linux/dma-contiguous.h | 102 +++++++++
include/linux/mmzone.h | 41 +++-
include/linux/page-isolation.h | 51 ++++-
mm/Kconfig | 8 +-
mm/compaction.c | 10 +
mm/memory_hotplug.c | 111 ---------
mm/page_alloc.c | 287 ++++++++++++++++++++++--
mm/page_isolation.c | 129 ++++++++++-
21 files changed, 1197 insertions(+), 369 deletions(-)
create mode 100644 arch/arm/include/asm/dma-contiguous.h
create mode 100644 drivers/base/dma-contiguous.c
create mode 100644 include/linux/dma-contiguous.h
--
1.7.1.569.g6f426
Hi Marek,
> Add initial proof of concept implementation of DMA-mapping API for
> devices that have IOMMU support. Right now only dma_alloc_coherent,
> dma_free_coherent and dma_mmap_coherent functions are supported.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski(a)samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park(a)samsung.com>
> ---
...
> diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
> new file mode 100644
> index 0000000..c246ff3
> --- /dev/null
> +++ b/arch/arm/include/asm/dma-iommu.h
...
> +int __init arm_iommu_assign_device(struct device *dev, dma_addr_t base, dma_addr_t size);
__init causes a panic if the iommu is assigned after boot.
In OMAP3 the iommu driver controls isp and dsp address spaces, it is
loaded until any of those 2 drivers is needed.
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index f8c6972..b6397c1 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
...
> +static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> + dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +{
> + struct dma_iommu_mapping *mapping = dev->archdata.mapping;
> + struct page **pages;
> + void *addr = NULL;
> + pgprot_t prot;
> +
> + if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
> + prot = pgprot_writecombine(pgprot_kernel);
> + else
> + prot = pgprot_dmacoherent(pgprot_kernel);
> +
> + arm_iommu_init(dev);
I found useful to call arm_iommu_init inside arm_iommu_assign_device
instead. So, then gen_pool is created only once without the
mapping->pool check, instead of relying on the call to ...alloc_attrs,
which in my case I never use because I'm implementing
iommu_map|unmap_sg functions to see how it goes with the dma mapping.
Regards,
Omar
Hi All,
In response to the discussion about power savings with memory regions
features following measurements are done.
Title:
On a system with 2GB memory , 1GB is static and the other 1GB in
various power states.
Brief environment description:
Samsung smdk-exynos board is used for this work and full board level
power consumption is measured that comprises of cpu and other
components. It has 2 DMC's(Dynamic memory controller) with each
supporting 1 GB DDR3 memory. Power characteristics of DMC0 controlled
memory remain same but memory controlled by DMC1 is changed to 4
different power states. The following numbers describe the maximum
power savings measured after executing the software from DMC0
controlled memory which changes the power states of DMC1 controlled
memory. Here the actual numbers are not mentioned but the percentage
power savings is shown in reference to the change in overall power
consumption. The memory region patches are expected to facilitate
transition of memory into into one of the following low power states.
1) Percentage power savings when DMC1(1GB) moved to self refresh mode
from idle/unaccess mode= 2.69%
2) Percentage power savings when DMC1(1GB) moved to precharge mode
from idle/unaccess mode= 3.23%
3) Percentage power savings when DMC1(1GB) clock is gated = 6.32%
The above power savings is indicative of the benefits that memory
regions could provide in this platform.
Thanks & Regards,
Amit Daniel Kachhap
Samsung India s/w operations, Bangalore
On Sat, May 28, 2011 at 1:26 PM, Andrew Morton
<akpm(a)linux-foundation.org> wrote:
> On Fri, 27 May 2011 18:01:28 +0530 Ankita Garg <ankita(a)in.ibm.com> wrote:
>
>> This patchset proposes a generic memory regions infrastructure that can be
>> used to tag boundaries of memory blocks which belongs to a specific memory
>> power management domain and further enable exploitation of platform memory
>> power management capabilities.
>
> A couple of quick thoughts...
>
> I'm seeing no estimate of how much energy we might save when this work
> is completed. But saving energy is the entire point of the entire
> patchset! So please spend some time thinking about that and update and
> maintain the [patch 0/n] description so others can get some idea of the
> benefit we might get from all of this. That estimate should include an
> estimate of what proportion of machines are likely to have hardware
> which can use this feature and in what timeframe.
>
> IOW, if it saves one microwatt on 0.001% of machines, not interested ;)
>
>
> Also, all this code appears to be enabled on all machines? So machines
> which don't have the requisite hardware still carry any additional
> overhead which is added here. I can see that ifdeffing a feature like
> this would be ghastly but please also have a think about the
> implications of this and add that discussion also.
>
> If possible, it would be good to think up some microbenchmarks which
> probe the worst-case performance impact and describe those and present
> the results. So others can gain an understanding of the runtime costs.
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel(a)lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
Hello everyone,
Like I've promised during the Memory Management summit at Linaro Meeting
in Budapest I continued the development of the CMA. The goal is to
integrate it as tight as possible with other kernel subsystems (like
memory management and dma-mapping) and finally merge to mainline.
This version introduces integration with DMA-mapping subsystem for ARM
architecture, but I believe that similar integration can be done for
other archs too. I've also rebased all the code onto latest v3.0-rc2
kernel.
A few words for these who see CMA for the first time:
The Contiguous Memory Allocator (CMA) makes it possible for device
drivers to allocate big contiguous chunks of memory after the system
has booted.
The main difference from the similar frameworks is the fact that CMA
allows to transparently reuse memory region reserved for the big
chunk allocation as a system memory, so no memory is wasted when no
big chunk is allocated. Once the alloc request is issued, the
framework will migrate system pages to create a required big chunk of
physically contiguous memory.
For more information see the changelog and links to previous versions
of CMA framework.
The current version of CMA is just an allocator that handles allocation
of contiguous memory blocks. The difference between this patchset and
Kamezawa's alloc_contig_pages() are:
1. alloc_contig_pages() requires MAX_ORDER alignment of allocations
which may be unsuitable for embeded systems where a few MiBs are
required.
Lack of the requirement on the alignment means that several threads
might try to access the same pageblock/page. To prevent this from
happening CMA uses a mutex so that only one cm_alloc()/cm_free()
function may run at one point.
2. CMA may use its own migratetype (MIGRATE_CMA) which behaves
similarly to ZONE_MOVABLE but can be put in arbitrary places.
This is required for us since we need to define two disjoint memory
ranges inside system RAM. (ie. in two memory banks (do not confuse
with nodes)).
3. alloc_contig_pages() scans memory in search for range that could be
migrated. CMA on the other hand maintains its own allocator to
decide where to allocate memory for device drivers and then tries
to migrate pages from that part if needed. This is not strictly
required but I somehow feel it might be faster.
The integration with ARM DMA-mapping subsystem is quite straightforward.
Once cma context is available alloc_pages() can be replaced by
cm_alloc() call.
Current version have been tested on Samsung S5PC110 based Aquila machine
and s5p-fimc V4L2 driver. The driver itself uses videobuf2 dma-contig
memory allocator, which in turn relies on dma_alloc_coherent() from
DMA-mapping subsystem. By integrating CMA with DMA-mapping we manage to
get this driver working with CMA without any single change required in
the driver or videobuf2-dma-contig allocator.
TODO:
1. use struct page * or pfn internally instead of physicall address
2. use some simple bitmap based allocator instead of genaloc
3. provide a function similar to dma_declare_coherent_memory(), which
will created and register cma area for particular device
4. code cleanup and simplification
5. discussion
6. double-mapping issues with ARMv6+ and coherent memory
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
Links to previous versions of the patchset:
v9: <http://article.gmane.org/gmane.linux.kernel.mm/60787>
v8: <http://article.gmane.org/gmane.linux.kernel.mm/56855>
v7: <http://article.gmane.org/gmane.linux.kernel.mm/55626>
v6: <http://article.gmane.org/gmane.linux.kernel.mm/55626>
v5: (intentionally left out as CMA v5 was identical to CMA v4)
lv4: <http://article.gmane.org/gmane.linux.kernel.mm/52010>
v3: <http://article.gmane.org/gmane.linux.kernel.mm/51573>
v2: <http://article.gmane.org/gmane.linux.kernel.mm/50986>
v1: <http://article.gmane.org/gmane.linux.kernel.mm/50669>
Changelog:
v10:
1. Rebased onto 3.0-rc2 and resolved all conflicts
2. Simplified CMA to be just a pure memory allocator, for use
with platfrom/bus specific subsystems, like dma-mapping.
Removed all device specific functions are calls.
3. Integrated with ARM DMA-mapping subsystem.
4. Code cleanup here and there.
5. Removed private context support.
v9: 1. Rebased onto 2.6.39-rc1 and resolved all conflicts
2. Fixed a bunch of nasty bugs that happened when the allocation
failed (mainly kernel oops due to NULL ptr dereference).
3. Introduced testing code: cma-regions compatibility layer and
videobuf2-cma memory allocator module.
v8: 1. The alloc_contig_range() function has now been separated from
CMA and put in page_allocator.c. This function tries to
migrate all LRU pages in specified range and then allocate the
range using alloc_contig_freed_pages().
2. Support for MIGRATE_CMA has been separated from the CMA code.
I have not tested if CMA works with ZONE_MOVABLE but I see no
reasons why it shouldn't.
3. I have added a @private argument when creating CMA contexts so
that one can reserve memory and not share it with the rest of
the system. This way, CMA acts only as allocation algorithm.
v7: 1. A lot of functionality that handled driver->allocator_context
mapping has been removed from the patchset. This is not to say
that this code is not needed, it's just not worth posting
everything in one patchset.
Currently, CMA is "just" an allocator. It uses it's own
migratetype (MIGRATE_CMA) for defining ranges of pageblokcs
which behave just like ZONE_MOVABLE but dispite the latter can
be put in arbitrary places.
2. The migration code that was introduced in the previous version
actually started working.
v6: 1. Most importantly, v6 introduces support for memory migration.
The implementation is not yet complete though.
Migration support means that when CMA is not using memory
reserved for it, page allocator can allocate pages from it.
When CMA wants to use the memory, the pages have to be moved
and/or evicted as to make room for CMA.
To make it possible it must be guaranteed that only movable and
reclaimable pages are allocated in CMA controlled regions.
This is done by introducing a MIGRATE_CMA migrate type that
guarantees exactly that.
Some of the migration code is "borrowed" from Kamezawa
Hiroyuki's alloc_contig_pages() implementation. The main
difference is that thanks to MIGRATE_CMA migrate type CMA
assumes that memory controlled by CMA are is always movable or
reclaimable so that it makes allocation decisions regardless of
the whether some pages are actually allocated and migrates them
if needed.
The most interesting patches from the patchset that implement
the functionality are:
09/13: mm: alloc_contig_free_pages() added
10/13: mm: MIGRATE_CMA migration type added
11/13: mm: MIGRATE_CMA isolation functions added
12/13: mm: cma: Migration support added [wip]
Currently, kernel panics in some situations which I am trying
to investigate.
2. cma_pin() and cma_unpin() functions has been added (after
a conversation with Johan Mossberg). The idea is that whenever
hardware does not use the memory (no transaction is on) the
chunk can be moved around. This would allow defragmentation to
be implemented if desired. No defragmentation algorithm is
provided at this time.
3. Sysfs support has been replaced with debugfs. I always felt
unsure about the sysfs interface and when Greg KH pointed it
out I finally got to rewrite it to debugfs.
v5: (intentionally left out as CMA v5 was identical to CMA v4)
v4: 1. The "asterisk" flag has been removed in favour of requiring
that platform will provide a "*=<regions>" rule in the map
attribute.
2. The terminology has been changed slightly renaming "kind" to
"type" of memory. In the previous revisions, the documentation
indicated that device drivers define memory kinds and now,
v3: 1. The command line parameters have been removed (and moved to
a separate patch, the fourth one). As a consequence, the
cma_set_defaults() function has been changed -- it no longer
accepts a string with list of regions but an array of regions.
2. The "asterisk" attribute has been removed. Now, each region
has an "asterisk" flag which lets one specify whether this
region should by considered "asterisk" region.
3. SysFS support has been moved to a separate patch (the third one
in the series) and now also includes list of regions.
v2: 1. The "cma_map" command line have been removed. In exchange,
a SysFS entry has been created under kernel/mm/contiguous.
The intended way of specifying the attributes is
a cma_set_defaults() function called by platform initialisation
code. "regions" attribute (the string specified by "cma"
command line parameter) can be overwritten with command line
parameter; the other attributes can be changed during run-time
using the SysFS entries.
2. The behaviour of the "map" attribute has been modified
slightly. Currently, if no rule matches given device it is
assigned regions specified by the "asterisk" attribute. It is
by default built from the region names given in "regions"
attribute.
3. Devices can register private regions as well as regions that
can be shared but are not reserved using standard CMA
mechanisms. A private region has no name and can be accessed
only by devices that have the pointer to it.
4. The way allocators are registered has changed. Currently,
a cma_allocator_register() function is used for that purpose.
Moreover, allocators are attached to regions the first time
memory is registered from the region or when allocator is
registered which means that allocators can be dynamic modules
that are loaded after the kernel booted (of course, it won't be
possible to allocate a chunk of memory from a region if
allocator is not loaded).
5. Index of new functions:
+static inline dma_addr_t __must_check
+cma_alloc_from(const char *regions, size_t size,
+ dma_addr_t alignment)
+static inline int
+cma_info_about(struct cma_info *info, const const char *regions)
+int __must_check cma_region_register(struct cma_region *reg);
+dma_addr_t __must_check
+cma_alloc_from_region(struct cma_region *reg,
+ size_t size, dma_addr_t alignment);
+static inline dma_addr_t __must_check
+cma_alloc_from(const char *regions,
+ size_t size, dma_addr_t alignment);
+int cma_allocator_register(struct cma_allocator *alloc);
Patches in this patchset:
lib: bitmap: Added alignment offset for bitmap_find_next_zero_area()
lib: genalloc: Generic allocator improvements
Some improvements to genalloc API (most importantly possibility to
allocate memory with alignment requirement).
mm: move some functions from memory_hotplug.c to page_isolation.c
mm: alloc_contig_freed_pages() added
Code "stolen" from Kamezawa. The first patch just moves code
around and the second provide function for "allocates" already
freed memory.
mm: alloc_contig_range() added
This is what Kamezawa asked: a function that tries to migrate all
pages from given range and then use alloc_contig_freed_pages()
(defined by the previous commit) to allocate those pages.
mm: MIGRATE_CMA migration type added
mm: MIGRATE_CMA isolation functions added
Introduction of the new migratetype and support for it in CMA.
MIGRATE_CMA works similar to ZONE_MOVABLE expect almost any
memory range can be marked as one.
mm: cma: Contiguous Memory Allocator added
The code CMA code. Manages CMA contexts and performs memory
allocations.
ARM: integrate CMA with dma-mapping subsystem
Main client of CMA frame work. CMA serves as a alloc_pages()
replacement if device has the cma context assigned.
ARM: S5PV210: add CMA support for FIMC devices on Aquila board
Example of platform/board specific code that creates cma
context and assigns it to particular devices.
Patch summary:
KAMEZAWA Hiroyuki (2):
mm: move some functions from memory_hotplug.c to page_isolation.c
mm: alloc_contig_freed_pages() added
Marek Szyprowski (3):
mm: cma: Contiguous Memory Allocator added
ARM: integrate CMA with dma-mapping subsystem
ARM: S5PV210: add CMA support for FIMC devices on Aquila board
Michal Nazarewicz (5):
lib: bitmap: Added alignment offset for bitmap_find_next_zero_area()
lib: genalloc: Generic allocator improvements
mm: alloc_contig_range() added
mm: MIGRATE_CMA migration type added
mm: MIGRATE_CMA isolation functions added
arch/arm/include/asm/device.h | 3 +
arch/arm/include/asm/dma-mapping.h | 19 ++
arch/arm/mach-s5pv210/Kconfig | 1 +
arch/arm/mach-s5pv210/mach-aquila.c | 26 +++
arch/arm/mm/dma-mapping.c | 60 +++++--
include/linux/bitmap.h | 24 ++-
include/linux/cma.h | 189 ++++++++++++++++++
include/linux/genalloc.h | 50 +++---
include/linux/mmzone.h | 43 ++++-
include/linux/page-isolation.h | 50 ++++--
lib/bitmap.c | 22 ++-
lib/genalloc.c | 190 +++++++++++--------
mm/Kconfig | 29 +++-
mm/Makefile | 1 +
mm/cma.c | 358 +++++++++++++++++++++++++++++++++++
mm/compaction.c | 10 +
mm/internal.h | 3 +
mm/memory_hotplug.c | 111 -----------
mm/page_alloc.c | 292 ++++++++++++++++++++++++++---
mm/page_isolation.c | 130 ++++++++++++-
20 files changed, 1319 insertions(+), 292 deletions(-)
create mode 100644 include/linux/cma.h
create mode 100644 mm/cma.c
--
1.7.1.569.g6f426
Hi all,
Just a reminder (as previously discussed in Budapest and in the recent
IRC meeting), the next face to face mini-summit will be at the Linaro
Connect event from August 1-5 in Cambourne, UK (just outside
Cambridge). The actual mini-summit will be, as with Budapest,
afternoons on Monday through Wednesday. We will also be co-locating
the next V4L2 brainstorming meeting at the Connect as well (right,
Laurent?). Details for registering, booking the conference hotel,
etc. can be found here:
https://wiki.linaro.org/Events/LinaroConnectQ3.11
Please let me know if you have questions, concerns, etc.
cheers,
Jesse
Hello,
Folloing the discussion about the driver for IOMMU controller for
Samsung Exynos4 platform and Arnd's suggestions I've decided to start
working on redesign of dma-mapping implementation for ARM architecture.
The goal is to add support for IOMMU in the way preffered by the
community :)
Some of the ideas about merging dma-mapping api and iommu api comes from
the following threads:
http://www.spinics.net/lists/linux-media/msg31453.htmlhttp://www.spinics.net/lists/arm-kernel/msg122552.htmlhttp://www.spinics.net/lists/arm-kernel/msg124416.html
They were also discussed on Linaro memory management meeting at UDS
(Budapest 9-12 May).
I've finaly managed to clean up a bit my works and present the initial,
very proof-of-concept version of patches that were ready just before
Linaro meeting.
What have been implemented:
1. Introduced arm_dma_ops
dma_map_ops from include/linux/dma-mapping.h suffers from the following
limitations:
- lack of start address for sync operations
- lack of write-combine methods
- lack of mmap to user-space methods
- lack of map_single method
For the initial version I've decided to use custom arm_dma_ops.
Extending common interface will take time, until that I wanted to have
something already working.
dma_{alloc,free,mmap}_{coherent,writecombine} have been consolidated
into dma_{alloc,free,mmap}_attrib what have been suggested on Linaro
meeting. New attribute for WRITE_COMBINE memory have been introduced.
2. moved all inline ARM dma-mapping related operations to
arch/arm/mm/dma-mapping.c and put them as methods in generic arm_dma_ops
structure. The dma-mapping.c code deinitely needs cleanup, but this is
just a first step.
3. Added very initial IOMMU support. Right now it is limited only to
dma_alloc_attrib, dma_free_attrib and dma_mmap_attrib. It have been
tested with s5p-fimc driver on Samsung Exynos4 platform.
4. Adapted Samsung Exynos4 IOMUU driver to make use of the introduced
iommu_dma proposal.
This patch series contains only patches for common dma-mapping part.
There is also a patch that adds driver for Samsung IOMMU controller on
Exynos4 platform. All required patches are available on:
git://git.infradead.org/users/kmpark/linux-2.6-samsung dma-mapping branch
Git web interface:
http://git.infradead.org/users/kmpark/linux-2.6-samsung/shortlog/refs/heads…
Future:
1. Add all missing operations for IOMMU mappings (map_single/page/sg,
sync_*)
2. Move sync_* operations into separate function for better code sharing
between iommu and non-iommu dma-mapping code
3. Splitting out dma bounce code from non-bounce into separate set of
dma methods. Right now dma-bounce code is compiled conditionally and
spread over arch/arm/mm/dma-mapping.c and arch/arm/common/dmabounce.c.
4. Merging dma_map_single with dma_map_page. I haven't investigated
deeply why they have separate implementation on ARM. If this is a
requirement then dma_map_ops need to be extended with another method.
5. Fix dma_alloc to unmap from linear mapping.
6. Convert IO address space management code from gen-alloc to some
simpler bitmap based solution.
7. resolve issues that might araise during discussion & comments
Please note that this is very early version of patches, definitely NOT
intended for merging. I just wanted to make sure that the direction is
right and share the code with others that might want to cooperate on
dma-mapping improvements.
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
Patch summary:
Marek Szyprowski (2):
ARM: Move dma related inlines into arm_dma_ops methods
ARM: initial proof-of-concept IOMMU mapper for DMA-mapping
arch/arm/Kconfig | 1 +
arch/arm/include/asm/device.h | 3 +
arch/arm/include/asm/dma-iommu.h | 30 ++
arch/arm/include/asm/dma-mapping.h | 653 +++++++++++------------------
arch/arm/mm/dma-mapping.c | 817 +++++++++++++++++++++++++++++++++---
arch/arm/mm/vmregion.h | 2 +-
include/linux/dma-attrs.h | 1 +
7 files changed, 1033 insertions(+), 474 deletions(-)
create mode 100644 arch/arm/include/asm/dma-iommu.h
--
1.7.1.569.g6f426
Hi all,
As Linaro refines its release cycles and related processes, we would
very much like to ensure that work stays on track and that we're able
to make progress. To that end, we'd like to have a sync-up meeting on
IRC (#linaro-mm-sig on irc.linaro.org or irc.freenode.net) to cover
status and next steps on the topics we've discussed in the summit, on
this list, and others. To address the timezone issue (there are a lot
of them between us), I'd like to offer to usurp the normal meeting
slot for the graphics working group, which, if nothing else, should
ensure that at least the working group members that are assigned to
memory management topics will be there; specifically, 1200UTC on
Wednesday, June 22. The meeting details are here:
https://wiki.linaro.org/OfficeofCTO/MemoryManagement/Notes/2011-06-22
I've put in a preliminary agenda, and the minutes and actions will be
culled from the channel log after the meeting. Please let me know if
you can't make it or if you want to see other items on the agenda but
can't edit the wiki for some reason (I'm not clear on the write access
to that page, but I'm happy to make proxy edits).
cheers,
Jesse
Hi,
I have a below use case for the UMM.
Samsung EXYNOS4 SoC has hardware IP for JPEG encoding/decoding. The
Android gallery application uses the JPEG decoder to draw the
images/thumbnail. As of now, skia library which handles this, uses a
software JPEG decoder for the same.
Buffer will be allocated by the Skia library for the JPEG image file to
be decoded. Now if we want to use hardware IP for decoding, we need to
a) Change the buffer allocation mechanism in Skia to get the buffers
from JPEG driver (mmapped)
b) Pass the user allocated buffer into the JPEG driver, and then to the
IP through the proposed DMA-IOMMU framework.
We feel (b) is nicer way to handle, with minimal changes into the
Android framework. But the issue lies if the UMM is going to address
this scenario.
Please mail me back if you need any clarifications on the requirement.
Regards,
Subash