mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
mm/cma: support to set CMA area status
Add an optional empty property - 'inactive' for reserved memory, only do effect for regions with reusable property. CMA area in 'inactive' status means that the operating system can't alloc pages from the regions. Change-Id: I34ecde9bc9c2e3cec175e6c032911c1bae21295c Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
This commit is contained in:
@@ -37,4 +37,7 @@ extern struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align,
|
||||
extern bool cma_release(struct cma *cma, const struct page *pages, unsigned int count);
|
||||
|
||||
extern int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data);
|
||||
|
||||
extern void set_cma_area_inactive(struct cma *cma);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -270,6 +270,9 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
|
||||
if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
|
||||
dma_contiguous_set_default(cma);
|
||||
|
||||
if (of_get_flat_dt_prop(node, "inactive", NULL))
|
||||
set_cma_area_inactive(cma);
|
||||
|
||||
rmem->ops = &rmem_cma_ops;
|
||||
rmem->priv = cma;
|
||||
|
||||
|
||||
18
mm/cma.c
18
mm/cma.c
@@ -112,6 +112,9 @@ static int __init cma_activate_area(struct cma *cma)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (cma->inactive)
|
||||
goto done;
|
||||
|
||||
WARN_ON_ONCE(!pfn_valid(pfn));
|
||||
zone = page_zone(pfn_to_page(pfn));
|
||||
|
||||
@@ -133,6 +136,7 @@ static int __init cma_activate_area(struct cma *cma)
|
||||
init_cma_reserved_pageblock(pfn_to_page(base_pfn));
|
||||
} while (--i);
|
||||
|
||||
done:
|
||||
mutex_init(&cma->lock);
|
||||
|
||||
#ifdef CONFIG_CMA_DEBUGFS
|
||||
@@ -467,6 +471,11 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align,
|
||||
mutex_unlock(&cma->lock);
|
||||
|
||||
pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
|
||||
if (cma->inactive) {
|
||||
ret = 0;
|
||||
page = pfn_to_page(pfn);
|
||||
break;
|
||||
}
|
||||
mutex_lock(&cma_mutex);
|
||||
ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA,
|
||||
GFP_KERNEL | (no_warn ? __GFP_NOWARN : 0));
|
||||
@@ -535,7 +544,8 @@ bool cma_release(struct cma *cma, const struct page *pages, unsigned int count)
|
||||
|
||||
VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
|
||||
|
||||
free_contig_range(pfn, count);
|
||||
if (!cma->inactive)
|
||||
free_contig_range(pfn, count);
|
||||
cma_clear_bitmap(cma, pfn, count);
|
||||
trace_cma_release(pfn, pages, count);
|
||||
|
||||
@@ -557,3 +567,9 @@ int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data)
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cma_for_each_area);
|
||||
|
||||
void set_cma_area_inactive(struct cma *cma)
|
||||
{
|
||||
cma->inactive = true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(set_cma_area_inactive);
|
||||
|
||||
Reference in New Issue
Block a user