mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
![Lucas Stach](/assets/img/avatar_default.png)
The callers of the DMA alloc functions already provide the proper context GFP flags. Make sure to pass them through to the CMA allocator, to make the CMA compaction context aware. Link: http://lkml.kernel.org/r/20170127172328.18574-3-l.stach@pengutronix.de Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Acked-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Radim Krcmar <rkrcmar@redhat.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Chris Zankel <chris@zankel.net> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Alexander Graf <agraf@suse.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
164 lines
4.5 KiB
C
164 lines
4.5 KiB
C
#ifndef __LINUX_CMA_H
|
|
#define __LINUX_CMA_H
|
|
|
|
/*
|
|
* 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>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License or (at your optional) any later version of the license.
|
|
*/
|
|
|
|
/*
|
|
* Contiguous Memory Allocator
|
|
*
|
|
* The Contiguous Memory Allocator (CMA) makes it possible to
|
|
* allocate big contiguous chunks of memory after the system has
|
|
* booted.
|
|
*
|
|
* Why is it needed?
|
|
*
|
|
* Various devices on embedded systems have no scatter-getter and/or
|
|
* IO map support and require contiguous blocks of memory to
|
|
* operate. They include devices such as cameras, hardware video
|
|
* coders, etc.
|
|
*
|
|
* Such devices often require big memory buffers (a full HD frame
|
|
* is, for instance, more then 2 mega pixels large, i.e. more than 6
|
|
* MB of memory), which makes mechanisms such as kmalloc() or
|
|
* alloc_page() ineffective.
|
|
*
|
|
* At the same time, a solution where a big memory region is
|
|
* reserved for a device is suboptimal since often more memory is
|
|
* reserved then strictly required and, moreover, the memory is
|
|
* inaccessible to page system even if device drivers don't use it.
|
|
*
|
|
* CMA tries to solve this issue by operating on memory regions
|
|
* where only movable pages can be allocated from. This way, kernel
|
|
* can use the memory for pagecache and when device driver requests
|
|
* it, allocated pages can be migrated.
|
|
*
|
|
* Driver usage
|
|
*
|
|
* CMA should not be used by the device drivers directly. It is
|
|
* only a helper framework for dma-mapping subsystem.
|
|
*
|
|
* For more information, see kernel-docs in drivers/base/dma-contiguous.c
|
|
*/
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
#include <linux/device.h>
|
|
|
|
struct cma;
|
|
struct page;
|
|
|
|
#ifdef CONFIG_DMA_CMA
|
|
|
|
extern struct cma *dma_contiguous_default_area;
|
|
|
|
static inline struct cma *dev_get_cma_area(struct device *dev)
|
|
{
|
|
if (dev && dev->cma_area)
|
|
return dev->cma_area;
|
|
return dma_contiguous_default_area;
|
|
}
|
|
|
|
static inline void dev_set_cma_area(struct device *dev, struct cma *cma)
|
|
{
|
|
if (dev)
|
|
dev->cma_area = cma;
|
|
}
|
|
|
|
static inline void dma_contiguous_set_default(struct cma *cma)
|
|
{
|
|
dma_contiguous_default_area = cma;
|
|
}
|
|
|
|
void dma_contiguous_reserve(phys_addr_t addr_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);
|
|
|
|
/**
|
|
* dma_declare_contiguous() - reserve area for contiguous memory handling
|
|
* for particular device
|
|
* @dev: Pointer to device structure.
|
|
* @size: Size of the reserved memory.
|
|
* @base: Start address of the reserved memory (optional, 0 for any).
|
|
* @limit: End address of the reserved memory (optional, 0 for any).
|
|
*
|
|
* This function reserves memory for specified device. It should be
|
|
* called by board specific code when early allocator (memblock or bootmem)
|
|
* is still activate.
|
|
*/
|
|
|
|
static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
|
|
phys_addr_t base, phys_addr_t limit)
|
|
{
|
|
struct cma *cma;
|
|
int ret;
|
|
ret = dma_contiguous_reserve_area(size, base, limit, &cma, true);
|
|
if (ret == 0)
|
|
dev_set_cma_area(dev, cma);
|
|
|
|
return ret;
|
|
}
|
|
|
|
struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
|
|
unsigned int order, gfp_t gfp_mask);
|
|
bool dma_release_from_contiguous(struct device *dev, struct page *pages,
|
|
int count);
|
|
|
|
#else
|
|
|
|
static inline struct cma *dev_get_cma_area(struct device *dev)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void dev_set_cma_area(struct device *dev, struct cma *cma) { }
|
|
|
|
static inline void dma_contiguous_set_default(struct cma *cma) { }
|
|
|
|
static inline void dma_contiguous_reserve(phys_addr_t limit) { }
|
|
|
|
static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
|
|
phys_addr_t limit, struct cma **res_cma,
|
|
bool fixed)
|
|
{
|
|
return -ENOSYS;
|
|
}
|
|
|
|
static inline
|
|
int dma_declare_contiguous(struct device *dev, phys_addr_t size,
|
|
phys_addr_t base, phys_addr_t limit)
|
|
{
|
|
return -ENOSYS;
|
|
}
|
|
|
|
static inline
|
|
struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
|
|
unsigned int order, gfp_t gfp_mask)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline
|
|
bool dma_release_from_contiguous(struct device *dev, struct page *pages,
|
|
int count)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|