ANDROID: mm: introduce GCMA
This patch introduces GCMA (Guaranteed Contiguous Memory Allocator) cleacache backend which reserves some amount of memory at the boot and then it stores clean file-backed pages from LRU eviction or invalidation. Since then, if file system couldn't find page from page cache, GCMA will serve the data instead of IO operation if the page stays in the GCMA. Thus, GCMA can be regarded as extend page cache for only clean file-backed pages on the LRU list. * Goal GCMA(Guaranteed Contiguous Memory Allocator) aims to guarantee contiguous memory allocation success as well as deterministic. - How it is deterministic - GCMA keeps only clean file-backed pages on the reserved memory, which are already backed to original file in the storage. Thus, when drivers claim to use the memory range, GCMA could discard those clean file-backed pages quickly unlike page migration from CMA. The page migration latency is very fluctuated depending on the number of page mapping and page status. - How it guarantees 100% allocation success - Since GCMA keeps only pages freed from page cache, System except GCMA itself couldn't reference those pages any longer. It means no one could access the page so GCMA could discard them any time quickly unlike that CMA depends on other random subsystem's page refcount activities. note: https://lwn.net/Articles/619865/ Originally, the idea was posted by SeongJae Park and me but it couldn't be merged to upstream at that time due to lacking of time and interest. This series is totally rewritten from the beginning since then. The cleancache operations in this patch are following: * gcma_cc_init_fs: create new GCMA fs instance for newly mounted fs * gcma_cc_store_page : store evicted pages from page cache to GCMA * gcma_cc_load_page : load page from GCMA to page cache * gcma_cc_invalidate_page : invalidate @page from GCMA * gcma_cc_invalidate_inode : invalidate every pages in the @inode * gcma_cc_invalidate_fs : invalidate all inodes in the fs The major data structures are fololwing: The gcma_fs represents a mounted fs cleacache backends. It manages inodes for the file system. The structure will be created when a FS is activated. The gcma_inode represents a inode. It manages pages for the inode using xarray. The data structure will be created when GCMA will serve the first page from page cache layer and it will be destoyed when the last page in the gcma_inode is erased. GCMA manages every page in LRU order and evict them under memory pressure to accept recent pages. GCMA exposes following stats * stored: how many cache pages stored to GCMA * loaded: how many times cached pages loaded from GCMA * evicted: how many times cached pages on GCMA were evicted * cached: how many cached pages GCMA has currently * discarded: how many cached pages were discarded by GCMA allocation Bug: 236887352 Bug: 391879760 Change-Id: Icba7fca105afa26fc74fb9d79aaad37718650d25 Signed-off-by: Minchan Kim <minchan@google.com> Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
committed by
Carlos Llamas
parent
a0a44b9ff9
commit
ccf872ebe4
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __GCMA_H__
|
||||
#define __GCMA_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_GCMA
|
||||
extern void gcma_alloc_range(unsigned long start_pfn, unsigned long end_pfn);
|
||||
extern void gcma_free_range(unsigned long start_pfn, unsigned long end_pfn);
|
||||
extern int register_gcma_area(const char *name, phys_addr_t base,
|
||||
phys_addr_t size);
|
||||
#else
|
||||
static inline void gcma_alloc_range(unsigned long start_pfn,
|
||||
unsigned long end_pfn) {}
|
||||
static inline void gcma_free_range(unsigned long start_pfn,
|
||||
unsigned long end_pfn) {}
|
||||
static inline int register_gcma_area(const char *name, phys_addr_t base,
|
||||
phys_addr_t size) { return -EINVAL; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+14
@@ -984,6 +984,20 @@ config CMA_AREAS
|
||||
|
||||
If unsure, leave the default value "8" in UMA and "20" in NUMA.
|
||||
|
||||
config GCMA
|
||||
bool "GCMA (Guaranteed Contiguous Memory Allocator)"
|
||||
depends on CLEANCACHE
|
||||
help
|
||||
This enables the clean-cache backed CMA (Contiguous Memory Allocator)
|
||||
It reserves a region of memory and allows only clean file-backed pages
|
||||
to be allocated from it. This way, the kernel can use the memory for
|
||||
pagecache and when a subsystem requests for contiguous area, the
|
||||
allocated pages are discarded right away to serve the contiguous
|
||||
request. It guarantees the allocation to always succeed and to be
|
||||
deterministic.
|
||||
|
||||
If unsure, say "n".
|
||||
|
||||
config MEM_SOFT_DIRTY
|
||||
bool "Track memory changes"
|
||||
depends on CHECKPOINT_RESTORE && HAVE_ARCH_SOFT_DIRTY && PROC_FS
|
||||
|
||||
@@ -119,6 +119,7 @@ obj-$(CONFIG_ZSMALLOC) += zsmalloc.o
|
||||
obj-$(CONFIG_Z3FOLD) += z3fold.o
|
||||
obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
|
||||
obj-$(CONFIG_CMA) += cma.o
|
||||
obj-$(CONFIG_GCMA) += gcma.o
|
||||
obj-$(CONFIG_NUMA) += numa.o
|
||||
obj-$(CONFIG_NUMA_MEMBLKS) += numa_memblks.o
|
||||
obj-$(CONFIG_NUMA_EMU) += numa_emulation.o
|
||||
|
||||
Reference in New Issue
Block a user