2017-11-07 19:30:07 +03:00
// SPDX-License-Identifier: GPL-2.0+
2011-12-29 16:09:51 +04:00
/*
* Contiguous Memory Allocator for DMA mapping framework
* Copyright ( c ) 2010 - 2011 by Samsung Electronics .
* Written by :
* Marek Szyprowski < m . szyprowski @ samsung . com >
* Michal Nazarewicz < mina86 @ mina86 . com >
*/
# define pr_fmt(fmt) "cma: " fmt
# ifdef CONFIG_CMA_DEBUG
# ifndef DEBUG
# define DEBUG
# endif
# endif
# include <asm/page.h>
# include <asm/dma-contiguous.h>
# include <linux/memblock.h>
# include <linux/err.h>
2012-10-18 11:29:44 +04:00
# include <linux/sizes.h>
2011-12-29 16:09:51 +04:00
# include <linux/dma-contiguous.h>
2014-08-07 03:05:25 +04:00
# include <linux/cma.h>
2011-12-29 16:09:51 +04:00
# ifdef CONFIG_CMA_SIZE_MBYTES
# define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
# else
# define CMA_SIZE_MBYTES 0
# endif
2014-08-07 03:05:25 +04:00
struct cma * dma_contiguous_default_area ;
2011-12-29 16:09:51 +04:00
/*
* Default global CMA area size can be defined in kernel ' s . config .
2013-09-18 08:04:48 +04:00
* This is useful mainly for distro maintainers to create a kernel
2011-12-29 16:09:51 +04:00
* that works correctly for most supported systems .
* The size can be set in bytes or as a percentage of the total memory
* in the system .
*
* Users , who want to set the size of global CMA area for their system
* should use cma = kernel parameter .
*/
2019-10-20 08:03:22 +03:00
static const phys_addr_t size_bytes __initconst =
( phys_addr_t ) CMA_SIZE_MBYTES * SZ_1M ;
static phys_addr_t size_cmdline __initdata = - 1 ;
static phys_addr_t base_cmdline __initdata ;
static phys_addr_t limit_cmdline __initdata ;
2011-12-29 16:09:51 +04:00
static int __init early_cma ( char * p )
{
2018-09-17 06:24:20 +03:00
if ( ! p ) {
pr_err ( " Config string not provided \n " ) ;
return - EINVAL ;
}
2011-12-29 16:09:51 +04:00
size_cmdline = memparse ( p , & p ) ;
2014-06-05 03:06:54 +04:00
if ( * p ! = ' @ ' )
return 0 ;
base_cmdline = memparse ( p + 1 , & p ) ;
if ( * p ! = ' - ' ) {
limit_cmdline = base_cmdline + size_cmdline ;
return 0 ;
}
limit_cmdline = memparse ( p + 1 , & p ) ;
2011-12-29 16:09:51 +04:00
return 0 ;
}
early_param ( " cma " , early_cma ) ;
# ifdef CONFIG_CMA_SIZE_PERCENTAGE
2012-12-05 18:29:25 +04:00
static phys_addr_t __init __maybe_unused cma_early_percent_memory ( void )
2011-12-29 16:09:51 +04:00
{
struct memblock_region * reg ;
unsigned long total_pages = 0 ;
/*
* We cannot use memblock_phys_mem_size ( ) here , because
* memblock_analyze ( ) has not been called yet .
*/
for_each_memblock ( memory , reg )
total_pages + = memblock_region_memory_end_pfn ( reg ) -
memblock_region_memory_base_pfn ( reg ) ;
return ( total_pages * CONFIG_CMA_SIZE_PERCENTAGE / 100 ) < < PAGE_SHIFT ;
}
# else
2012-12-05 18:29:25 +04:00
static inline __maybe_unused phys_addr_t cma_early_percent_memory ( void )
2011-12-29 16:09:51 +04:00
{
return 0 ;
}
# endif
/**
2013-07-29 16:31:45 +04:00
* dma_contiguous_reserve ( ) - reserve area ( s ) for contiguous memory handling
2011-12-29 16:09:51 +04:00
* @ limit : End address of the reserved memory ( optional , 0 for any ) .
*
* This function reserves memory from early allocator . It should be
* called by arch specific code once the early allocator ( memblock or bootmem )
* has been activated and all other subsystems have already allocated / reserved
* memory .
*/
void __init dma_contiguous_reserve ( phys_addr_t limit )
{
2012-12-05 18:29:25 +04:00
phys_addr_t selected_size = 0 ;
2014-06-05 03:06:54 +04:00
phys_addr_t selected_base = 0 ;
phys_addr_t selected_limit = limit ;
bool fixed = false ;
2011-12-29 16:09:51 +04:00
pr_debug ( " %s(limit %08lx) \n " , __func__ , ( unsigned long ) limit ) ;
if ( size_cmdline ! = - 1 ) {
selected_size = size_cmdline ;
2014-06-05 03:06:54 +04:00
selected_base = base_cmdline ;
selected_limit = min_not_zero ( limit_cmdline , limit ) ;
if ( base_cmdline + size_cmdline = = limit_cmdline )
fixed = true ;
2011-12-29 16:09:51 +04:00
} else {
# ifdef CONFIG_CMA_SIZE_SEL_MBYTES
selected_size = size_bytes ;
# elif defined(CONFIG_CMA_SIZE_SEL_PERCENTAGE)
selected_size = cma_early_percent_memory ( ) ;
# elif defined(CONFIG_CMA_SIZE_SEL_MIN)
selected_size = min ( size_bytes , cma_early_percent_memory ( ) ) ;
# elif defined(CONFIG_CMA_SIZE_SEL_MAX)
selected_size = max ( size_bytes , cma_early_percent_memory ( ) ) ;
# endif
}
2013-07-29 16:31:45 +04:00
if ( selected_size & & ! dma_contiguous_default_area ) {
2011-12-29 16:09:51 +04:00
pr_debug ( " %s: reserving %ld MiB for global area \n " , __func__ ,
2012-12-05 18:29:25 +04:00
( unsigned long ) selected_size / SZ_1M ) ;
2011-12-29 16:09:51 +04:00
2014-06-05 03:06:54 +04:00
dma_contiguous_reserve_area ( selected_size , selected_base ,
selected_limit ,
& dma_contiguous_default_area ,
fixed ) ;
2011-12-29 16:09:51 +04:00
}
2014-06-05 03:06:54 +04:00
}
2011-12-29 16:09:51 +04:00
2014-08-07 03:05:19 +04:00
/**
* dma_contiguous_reserve_area ( ) - reserve custom contiguous area
* @ size : Size of the reserved area ( in bytes ) ,
* @ base : Base address of the reserved area optional , use 0 for any
* @ limit : End address of the reserved memory ( optional , 0 for any ) .
* @ res_cma : Pointer to store the created cma region .
* @ fixed : hint about where to place the reserved area
*
* This function reserves memory from early allocator . It should be
* called by arch specific code once the early allocator ( memblock or bootmem )
* has been activated and all other subsystems have already allocated / reserved
* memory . This function allows to create custom reserved areas for specific
* devices .
*
* If @ fixed is true , reserve contiguous area at exactly @ base . If false ,
* reserve in range from @ base to @ limit .
*/
int __init dma_contiguous_reserve_area ( phys_addr_t size , phys_addr_t base ,
phys_addr_t limit , struct cma * * res_cma ,
bool fixed )
{
int ret ;
2017-04-18 21:27:03 +03:00
ret = cma_declare_contiguous ( base , size , limit , 0 , 0 , fixed ,
" reserved " , res_cma ) ;
2014-08-07 03:05:19 +04:00
if ( ret )
return ret ;
/* Architecture specific contiguous memory fixup. */
2014-08-07 03:05:25 +04:00
dma_contiguous_early_fixup ( cma_get_base ( * res_cma ) ,
cma_get_size ( * res_cma ) ) ;
2014-08-07 03:05:19 +04:00
return 0 ;
}
2011-12-29 16:09:51 +04:00
/**
2014-08-07 03:05:19 +04:00
* dma_alloc_from_contiguous ( ) - allocate pages from contiguous area
* @ dev : Pointer to device for which the allocation is performed .
* @ count : Requested number of pages .
* @ align : Requested alignment of pages ( in PAGE_SIZE order ) .
2018-08-18 01:49:00 +03:00
* @ no_warn : Avoid printing message about failed allocation .
2011-12-29 16:09:51 +04:00
*
2014-08-07 03:05:19 +04:00
* This function allocates memory buffer for specified device . It uses
* device specific contiguous memory area if available or the default
* global one . Requires architecture specific dev_get_cma_area ( ) helper
* function .
2011-12-29 16:09:51 +04:00
*/
2015-10-22 23:32:11 +03:00
struct page * dma_alloc_from_contiguous ( struct device * dev , size_t count ,
2018-08-18 01:49:00 +03:00
unsigned int align , bool no_warn )
2011-12-29 16:09:51 +04:00
{
2014-08-07 03:05:19 +04:00
if ( align > CONFIG_CMA_ALIGNMENT )
align = CONFIG_CMA_ALIGNMENT ;
2018-08-18 01:49:00 +03:00
return cma_alloc ( dev_get_cma_area ( dev ) , count , align , no_warn ) ;
2011-12-29 16:09:51 +04:00
}
2014-08-07 03:05:19 +04:00
/**
* dma_release_from_contiguous ( ) - release allocated pages
* @ dev : Pointer to device for which the pages were allocated .
* @ pages : Allocated pages .
* @ count : Number of allocated pages .
*
* This function releases memory allocated by dma_alloc_from_contiguous ( ) .
* It returns false when provided pages do not belong to contiguous area and
* true otherwise .
*/
bool dma_release_from_contiguous ( struct device * dev , struct page * pages ,
int count )
{
2014-08-07 03:05:25 +04:00
return cma_release ( dev_get_cma_area ( dev ) , pages , count ) ;
2014-08-07 03:05:19 +04:00
}
2014-10-14 02:51:09 +04:00
dma-contiguous: add dma_{alloc,free}_contiguous() helpers
Both dma_alloc_from_contiguous() and dma_release_from_contiguous() are
very simply implemented, but requiring callers to pass certain
parameters like count and align, and taking a boolean parameter to check
__GFP_NOWARN in the allocation flags. So every function call duplicates
similar work:
unsigned long order = get_order(size);
size_t count = size >> PAGE_SHIFT;
page = dma_alloc_from_contiguous(dev, count, order,
gfp & __GFP_NOWARN);
[...]
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
Additionally, as CMA can be used only in the context which permits
sleeping, most of callers do a gfpflags_allow_blocking() check and a
corresponding fallback allocation of normal pages upon any false result:
if (gfpflags_allow_blocking(flag))
page = dma_alloc_from_contiguous();
if (!page)
page = alloc_pages();
[...]
if (!dma_release_from_contiguous(dev, page, count))
__free_pages(page, get_order(size));
So this patch simplifies those function calls by abstracting these
operations into the two new functions: dma_{alloc,free}_contiguous.
As some callers of dma_{alloc,release}_from_contiguous() might be
complicated, this patch just implements these two new functions to
kernel/dma/direct.c only as an initial step.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Tested-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
2019-05-24 07:06:32 +03:00
/**
* dma_alloc_contiguous ( ) - allocate contiguous pages
* @ dev : Pointer to device for which the allocation is performed .
* @ size : Requested allocation size .
* @ gfp : Allocation flags .
*
* This function allocates contiguous memory buffer for specified device . It
* first tries to use device specific contiguous memory area if available or
* the default global one , then tries a fallback allocation of normal pages .
2019-05-24 07:06:33 +03:00
*
* Note that it byapss one - page size of allocations from the global area as
* the addresses within one page are always contiguous , so there is no need
* to waste CMA pages for that kind ; it also helps reduce fragmentations .
dma-contiguous: add dma_{alloc,free}_contiguous() helpers
Both dma_alloc_from_contiguous() and dma_release_from_contiguous() are
very simply implemented, but requiring callers to pass certain
parameters like count and align, and taking a boolean parameter to check
__GFP_NOWARN in the allocation flags. So every function call duplicates
similar work:
unsigned long order = get_order(size);
size_t count = size >> PAGE_SHIFT;
page = dma_alloc_from_contiguous(dev, count, order,
gfp & __GFP_NOWARN);
[...]
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
Additionally, as CMA can be used only in the context which permits
sleeping, most of callers do a gfpflags_allow_blocking() check and a
corresponding fallback allocation of normal pages upon any false result:
if (gfpflags_allow_blocking(flag))
page = dma_alloc_from_contiguous();
if (!page)
page = alloc_pages();
[...]
if (!dma_release_from_contiguous(dev, page, count))
__free_pages(page, get_order(size));
So this patch simplifies those function calls by abstracting these
operations into the two new functions: dma_{alloc,free}_contiguous.
As some callers of dma_{alloc,release}_from_contiguous() might be
complicated, this patch just implements these two new functions to
kernel/dma/direct.c only as an initial step.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Tested-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
2019-05-24 07:06:32 +03:00
*/
struct page * dma_alloc_contiguous ( struct device * dev , size_t size , gfp_t gfp )
{
2019-08-20 05:45:49 +03:00
size_t count = size > > PAGE_SHIFT ;
dma-contiguous: add dma_{alloc,free}_contiguous() helpers
Both dma_alloc_from_contiguous() and dma_release_from_contiguous() are
very simply implemented, but requiring callers to pass certain
parameters like count and align, and taking a boolean parameter to check
__GFP_NOWARN in the allocation flags. So every function call duplicates
similar work:
unsigned long order = get_order(size);
size_t count = size >> PAGE_SHIFT;
page = dma_alloc_from_contiguous(dev, count, order,
gfp & __GFP_NOWARN);
[...]
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
Additionally, as CMA can be used only in the context which permits
sleeping, most of callers do a gfpflags_allow_blocking() check and a
corresponding fallback allocation of normal pages upon any false result:
if (gfpflags_allow_blocking(flag))
page = dma_alloc_from_contiguous();
if (!page)
page = alloc_pages();
[...]
if (!dma_release_from_contiguous(dev, page, count))
__free_pages(page, get_order(size));
So this patch simplifies those function calls by abstracting these
operations into the two new functions: dma_{alloc,free}_contiguous.
As some callers of dma_{alloc,release}_from_contiguous() might be
complicated, this patch just implements these two new functions to
kernel/dma/direct.c only as an initial step.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Tested-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
2019-05-24 07:06:32 +03:00
struct page * page = NULL ;
2019-05-24 07:06:33 +03:00
struct cma * cma = NULL ;
if ( dev & & dev - > cma_area )
cma = dev - > cma_area ;
else if ( count > 1 )
cma = dma_contiguous_default_area ;
dma-contiguous: add dma_{alloc,free}_contiguous() helpers
Both dma_alloc_from_contiguous() and dma_release_from_contiguous() are
very simply implemented, but requiring callers to pass certain
parameters like count and align, and taking a boolean parameter to check
__GFP_NOWARN in the allocation flags. So every function call duplicates
similar work:
unsigned long order = get_order(size);
size_t count = size >> PAGE_SHIFT;
page = dma_alloc_from_contiguous(dev, count, order,
gfp & __GFP_NOWARN);
[...]
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
Additionally, as CMA can be used only in the context which permits
sleeping, most of callers do a gfpflags_allow_blocking() check and a
corresponding fallback allocation of normal pages upon any false result:
if (gfpflags_allow_blocking(flag))
page = dma_alloc_from_contiguous();
if (!page)
page = alloc_pages();
[...]
if (!dma_release_from_contiguous(dev, page, count))
__free_pages(page, get_order(size));
So this patch simplifies those function calls by abstracting these
operations into the two new functions: dma_{alloc,free}_contiguous.
As some callers of dma_{alloc,release}_from_contiguous() might be
complicated, this patch just implements these two new functions to
kernel/dma/direct.c only as an initial step.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Tested-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
2019-05-24 07:06:32 +03:00
/* CMA can be used only in the context which permits sleeping */
if ( cma & & gfpflags_allow_blocking ( gfp ) ) {
2019-08-20 05:45:49 +03:00
size_t align = get_order ( size ) ;
2019-07-26 22:34:32 +03:00
size_t cma_align = min_t ( size_t , align , CONFIG_CMA_ALIGNMENT ) ;
page = cma_alloc ( cma , count , cma_align , gfp & __GFP_NOWARN ) ;
dma-contiguous: add dma_{alloc,free}_contiguous() helpers
Both dma_alloc_from_contiguous() and dma_release_from_contiguous() are
very simply implemented, but requiring callers to pass certain
parameters like count and align, and taking a boolean parameter to check
__GFP_NOWARN in the allocation flags. So every function call duplicates
similar work:
unsigned long order = get_order(size);
size_t count = size >> PAGE_SHIFT;
page = dma_alloc_from_contiguous(dev, count, order,
gfp & __GFP_NOWARN);
[...]
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
Additionally, as CMA can be used only in the context which permits
sleeping, most of callers do a gfpflags_allow_blocking() check and a
corresponding fallback allocation of normal pages upon any false result:
if (gfpflags_allow_blocking(flag))
page = dma_alloc_from_contiguous();
if (!page)
page = alloc_pages();
[...]
if (!dma_release_from_contiguous(dev, page, count))
__free_pages(page, get_order(size));
So this patch simplifies those function calls by abstracting these
operations into the two new functions: dma_{alloc,free}_contiguous.
As some callers of dma_{alloc,release}_from_contiguous() might be
complicated, this patch just implements these two new functions to
kernel/dma/direct.c only as an initial step.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Tested-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
2019-05-24 07:06:32 +03:00
}
return page ;
}
/**
* dma_free_contiguous ( ) - release allocated pages
* @ dev : Pointer to device for which the pages were allocated .
* @ page : Pointer to the allocated pages .
* @ size : Size of allocated pages .
*
* This function releases memory allocated by dma_alloc_contiguous ( ) . As the
* cma_release returns false when provided pages do not belong to contiguous
* area and true otherwise , this function then does a fallback __free_pages ( )
* upon a false - return .
*/
void dma_free_contiguous ( struct device * dev , struct page * page , size_t size )
{
2019-07-26 22:34:33 +03:00
if ( ! cma_release ( dev_get_cma_area ( dev ) , page ,
PAGE_ALIGN ( size ) > > PAGE_SHIFT ) )
dma-contiguous: add dma_{alloc,free}_contiguous() helpers
Both dma_alloc_from_contiguous() and dma_release_from_contiguous() are
very simply implemented, but requiring callers to pass certain
parameters like count and align, and taking a boolean parameter to check
__GFP_NOWARN in the allocation flags. So every function call duplicates
similar work:
unsigned long order = get_order(size);
size_t count = size >> PAGE_SHIFT;
page = dma_alloc_from_contiguous(dev, count, order,
gfp & __GFP_NOWARN);
[...]
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
Additionally, as CMA can be used only in the context which permits
sleeping, most of callers do a gfpflags_allow_blocking() check and a
corresponding fallback allocation of normal pages upon any false result:
if (gfpflags_allow_blocking(flag))
page = dma_alloc_from_contiguous();
if (!page)
page = alloc_pages();
[...]
if (!dma_release_from_contiguous(dev, page, count))
__free_pages(page, get_order(size));
So this patch simplifies those function calls by abstracting these
operations into the two new functions: dma_{alloc,free}_contiguous.
As some callers of dma_{alloc,release}_from_contiguous() might be
complicated, this patch just implements these two new functions to
kernel/dma/direct.c only as an initial step.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Tested-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
2019-05-24 07:06:32 +03:00
__free_pages ( page , get_order ( size ) ) ;
}
2014-10-14 02:51:09 +04:00
/*
* Support for reserved memory regions defined in device tree
*/
# ifdef CONFIG_OF_RESERVED_MEM
# include <linux/of.h>
# include <linux/of_fdt.h>
# include <linux/of_reserved_mem.h>
# undef pr_fmt
# define pr_fmt(fmt) fmt
2014-10-30 00:50:29 +03:00
static int rmem_cma_device_init ( struct reserved_mem * rmem , struct device * dev )
2014-10-14 02:51:09 +04:00
{
dev_set_cma_area ( dev , rmem - > priv ) ;
2014-10-30 00:50:29 +03:00
return 0 ;
2014-10-14 02:51:09 +04:00
}
static void rmem_cma_device_release ( struct reserved_mem * rmem ,
struct device * dev )
{
dev_set_cma_area ( dev , NULL ) ;
}
static const struct reserved_mem_ops rmem_cma_ops = {
. device_init = rmem_cma_device_init ,
. device_release = rmem_cma_device_release ,
} ;
static int __init rmem_cma_setup ( struct reserved_mem * rmem )
{
phys_addr_t align = PAGE_SIZE < < max ( MAX_ORDER - 1 , pageblock_order ) ;
phys_addr_t mask = align - 1 ;
unsigned long node = rmem - > fdt_node ;
2020-01-10 20:19:33 +03:00
bool default_cma = of_get_flat_dt_prop ( node , " linux,cma-default " , NULL ) ;
2014-10-14 02:51:09 +04:00
struct cma * cma ;
int err ;
2020-01-10 20:19:33 +03:00
if ( size_cmdline ! = - 1 & & default_cma ) {
pr_info ( " Reserved memory: bypass %s node, using cmdline CMA params instead \n " ,
rmem - > name ) ;
return - EBUSY ;
}
2014-10-14 02:51:09 +04:00
if ( ! of_get_flat_dt_prop ( node , " reusable " , NULL ) | |
of_get_flat_dt_prop ( node , " no-map " , NULL ) )
return - EINVAL ;
if ( ( rmem - > base & mask ) | | ( rmem - > size & mask ) ) {
pr_err ( " Reserved memory: incorrect alignment of CMA region \n " ) ;
return - EINVAL ;
}
2017-04-18 21:27:03 +03:00
err = cma_init_reserved_mem ( rmem - > base , rmem - > size , 0 , rmem - > name , & cma ) ;
2014-10-14 02:51:09 +04:00
if ( err ) {
pr_err ( " Reserved memory: unable to setup CMA region \n " ) ;
return err ;
}
/* Architecture specific contiguous memory fixup. */
dma_contiguous_early_fixup ( rmem - > base , rmem - > size ) ;
2020-01-10 20:19:33 +03:00
if ( default_cma )
2014-10-14 02:51:09 +04:00
dma_contiguous_set_default ( cma ) ;
rmem - > ops = & rmem_cma_ops ;
rmem - > priv = cma ;
pr_info ( " Reserved memory: created CMA memory pool at %pa, size %ld MiB \n " ,
& rmem - > base , ( unsigned long ) rmem - > size / SZ_1M ) ;
return 0 ;
}
RESERVEDMEM_OF_DECLARE ( cma , " shared-dma-pool " , rmem_cma_setup ) ;
# endif