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:
Minchan Kim
2023-02-08 16:47:16 -08:00
committed by Carlos Llamas
parent a0a44b9ff9
commit ccf872ebe4
4 changed files with 1052 additions and 0 deletions
+21
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
+1016
View File
File diff suppressed because it is too large Load Diff