Skip to content

Commit

Permalink
drivers: add Contiguous Memory Allocator
Browse files Browse the repository at this point in the history
The Contiguous Memory Allocator is a set of helper functions for DMA
mapping framework that improves allocations of contiguous memory chunks.

CMA grabs memory on system boot, marks it with MIGRATE_CMA migrate type
and gives back to the system. Kernel is allowed to allocate only movable
pages within CMA's managed memory so that it can be used for example for
page cache when DMA mapping do not use it. On
dma_alloc_from_contiguous() request such pages are migrated out of CMA
area to free required contiguous block and fulfill the request. This
allows to allocate large contiguous chunks of memory at any time
assuming that there is enough free memory available in the system.

This code is heavily based on earlier works by Michal Nazarewicz.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Rob Clark <rob.clark@linaro.org>
Tested-by: Ohad Ben-Cohen <ohad@wizery.com>
Tested-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Tested-by: Robert Nelson <robertcnelson@gmail.com>
Tested-by: Barry Song <Baohua.Song@csr.com>
  • Loading branch information
mszyprow committed May 21, 2012
1 parent 49f223a commit c64be2b
Show file tree
Hide file tree
Showing 8 changed files with 641 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Also note the kernel might malfunction if you disable
some critical bits.

cma=nn[MG] [ARM,KNL]
Sets the size of kernel global memory area for contiguous
memory allocations. For more information, see
include/linux/dma-contiguous.h

cmo_free_hint= [PPC] Format: { yes | no }
Specify whether pages are marked as being inactive
when they are freed. This is used in CMO environments
Expand Down
3 changes: 3 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ config HAVE_ARCH_TRACEHOOK
config HAVE_DMA_ATTRS
bool

config HAVE_DMA_CONTIGUOUS
bool

config USE_GENERIC_SMP_HELPERS
bool

Expand Down
89 changes: 89 additions & 0 deletions drivers/base/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,93 @@ config DMA_SHARED_BUFFER
APIs extension; the file's descriptor can then be passed on to other
driver.

config CMA
bool "Contiguous Memory Allocator (EXPERIMENTAL)"
depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK && EXPERIMENTAL
select MIGRATION
help
This enables the Contiguous Memory Allocator which allows drivers
to allocate big physically-contiguous blocks of memory for use with
hardware components that do not support I/O map nor scatter-gather.

For more information see <include/linux/dma-contiguous.h>.
If unsure, say "n".

if CMA

config CMA_DEBUG
bool "CMA debug messages (DEVELOPMENT)"
depends on DEBUG_KERNEL
help
Turns on debug messages in CMA. This produces KERN_DEBUG
messages for every CMA call as well as various messages while
processing calls such as dma_alloc_from_contiguous().
This option does not affect warning and error messages.

comment "Default contiguous memory area size:"

config CMA_SIZE_MBYTES
int "Size in Mega Bytes"
depends on !CMA_SIZE_SEL_PERCENTAGE
default 16
help
Defines the size (in MiB) of the default memory area for Contiguous
Memory Allocator.

config CMA_SIZE_PERCENTAGE
int "Percentage of total memory"
depends on !CMA_SIZE_SEL_MBYTES
default 10
help
Defines the size of the default memory area for Contiguous Memory
Allocator as a percentage of the total memory in the system.

choice
prompt "Selected region size"
default CMA_SIZE_SEL_ABSOLUTE

config CMA_SIZE_SEL_MBYTES
bool "Use mega bytes value only"

config CMA_SIZE_SEL_PERCENTAGE
bool "Use percentage value only"

config CMA_SIZE_SEL_MIN
bool "Use lower value (minimum)"

config CMA_SIZE_SEL_MAX
bool "Use higher value (maximum)"

endchoice

config CMA_ALIGNMENT
int "Maximum PAGE_SIZE order of alignment for contiguous buffers"
range 4 9
default 8
help
DMA mapping framework by default aligns all buffers to the smallest
PAGE_SIZE order which is greater than or equal to the requested buffer
size. This works well for buffers up to a few hundreds kilobytes, but
for larger buffers it just a memory waste. With this parameter you can
specify the maximum PAGE_SIZE order for contiguous buffers. Larger
buffers will be aligned only to this specified order. The order is
expressed as a power of two multiplied by the PAGE_SIZE.

For example, if your system defaults to 4KiB pages, the order value
of 8 means that the buffers will be aligned up to 1MiB only.

If unsure, leave the default value "8".

config CMA_AREAS
int "Maximum count of the CMA device-private areas"
default 7
help
CMA allows to create CMA areas for particular devices. This parameter
sets the maximum number of such device private CMA areas in the
system.

If unsure, leave the default value "7".

endif

endmenu
1 change: 1 addition & 0 deletions drivers/base/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ obj-y := core.o bus.o dd.o syscore.o \
attribute_container.o transport_class.o \
topology.o
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-$(CONFIG_CMA) += dma-contiguous.o
obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
Expand Down

0 comments on commit c64be2b

Please sign in to comment.