From 87e8391b858c3030c8c1e87e4c45ae406ce0e6cc Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Thu, 24 Mar 2022 17:49:08 +0800 Subject: [PATCH] mm/cma: support cma inactive feature When do active cma area, the reserved blocks from cma area will be insert into system memory, and the pages will be allocated first even then the system freelist is not empty. After system borrows pages from cma, the cma will do isolate/migrate them when the cma alloc happens, that spends much time and sometimes the pages are pinned result a page busy failure. This patch adds a CONFIG_CMA_INACTIVE to give a option, allows the cma area not active and then system can not borrows pages from cma. Signed-off-by: Jianqun Xu Change-Id: Iaaece4abda1ed0250e603e9255a59ebfa5c3a65f --- mm/Kconfig | 9 +++++++++ mm/cma.c | 12 ++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/mm/Kconfig b/mm/Kconfig index db74af09fe6d..9e7ad31e1aff 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -505,6 +505,15 @@ config CMA If unsure, say "n". +config CMA_INACTIVE + bool "CMA not active to system" + depends on CMA + help + This forbids the CMA to active its pages to system memory, to keep + page from CMA never be borrowed by system. + + If unsure, say "n". + config CMA_DEBUG bool "CMA debug messages (DEVELOPMENT)" depends on DEBUG_KERNEL && CMA diff --git a/mm/cma.c b/mm/cma.c index a7638d7487c4..c8b32947318a 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -111,6 +111,8 @@ static void __init cma_activate_area(struct cma *cma) if (!cma->bitmap) goto out_error; + if (IS_ENABLED(CONFIG_CMA_INACTIVE)) + goto out; /* * alloc_contig_range() requires the pfn range specified to be in the * same zone. Simplify by forcing the entire CMA resv range to be in the @@ -128,6 +130,7 @@ static void __init cma_activate_area(struct cma *cma) pfn += pageblock_nr_pages) init_cma_reserved_pageblock(pfn_to_page(pfn)); +out: mutex_init(&cma->lock); #ifdef CONFIG_CMA_DEBUGFS @@ -511,6 +514,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 (IS_ENABLED(CONFIG_CMA_INACTIVE)) { + page = pfn_to_page(pfn); + lru_cache_enable(); + goto out; + } ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, gfp_mask, &info); cma_info.nr_migrated += info.nr_migrated; cma_info.nr_reclaimed += info.nr_reclaimed; @@ -610,8 +618,8 @@ bool cma_release(struct cma *cma, const struct page *pages, unsigned int count) return false; VM_BUG_ON(pfn + count > cma->base_pfn + cma->count); - - free_contig_range(pfn, count); + if (!IS_ENABLED(CONFIG_CMA_INACTIVE)) + free_contig_range(pfn, count); cma_clear_bitmap(cma, pfn, count); trace_cma_release(cma->name, pfn, pages, count);