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:
Jianqun Xu
2020-06-28 16:54:33 +08:00
committed by Tao Huang
parent 069bb25961
commit 8d1e1e2de4
4 changed files with 24 additions and 1 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -13,6 +13,7 @@ struct cma {
spinlock_t mem_head_lock;
#endif
const char *name;
bool inactive;
};
extern struct cma cma_areas[MAX_CMA_AREAS];