diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 703fe5bc2535dca3d1b4bbb75a4d1e368ff2f34b..fec4bc9cc5b5b935e945c51a6f7227369d235f5d 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -1148,6 +1148,7 @@ CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y CONFIG_PER_VMA_LOCK=y CONFIG_LOCK_MM_AND_FIND_VMA=y CONFIG_MEMORY_RELIABLE=y +CONFIG_GMEM=y # # Data Access Monitoring diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index c9e816e54003230a5504f29d5427055a9a9fee06..ad7f1dedd2b6eda35aecbf60dd1a606c3ca2f2e7 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -1163,6 +1163,7 @@ CONFIG_LRU_GEN=y CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y CONFIG_PER_VMA_LOCK=y CONFIG_LOCK_MM_AND_FIND_VMA=y +CONFIG_GMEM=y # # Data Access Monitoring diff --git a/drivers/base/node.c b/drivers/base/node.c index 493d533f8375560a1503167363b42480b4d2b897..aa4d2ca266aa871d7c90d3c2cd7a29a4698c931e 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -928,6 +928,9 @@ static struct node_attr node_state_attr[] = { [N_CPU] = _NODE_ATTR(has_cpu, N_CPU), [N_GENERIC_INITIATOR] = _NODE_ATTR(has_generic_initiator, N_GENERIC_INITIATOR), +#ifdef CONFIG_GMEM + [N_HETEROGENEOUS] = _NODE_ATTR(has_hetero_memory, N_HETEROGENEOUS), +#endif }; static struct attribute *node_state_attrs[] = { @@ -940,6 +943,9 @@ static struct attribute *node_state_attrs[] = { &node_state_attr[N_MEMORY].attr.attr, &node_state_attr[N_CPU].attr.attr, &node_state_attr[N_GENERIC_INITIATOR].attr.attr, +#ifdef CONFIG_GMEM + &node_state_attr[N_HETEROGENEOUS].attr.attr, +#endif NULL }; diff --git a/include/linux/device.h b/include/linux/device.h index 56d93a1ffb7b6a619e30249b4b1ddabdc5750e67..f88b261652d594614f01e4bc792011ba40bc5df9 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -31,6 +31,7 @@ #include #include #include +#include #include struct device; @@ -805,6 +806,9 @@ struct device { #ifdef CONFIG_DMA_OPS_BYPASS bool dma_ops_bypass : 1; #endif +#ifdef CONFIG_GMEM + KABI_RESERVE(gmem_0) +#endif }; /** diff --git a/include/linux/mm.h b/include/linux/mm.h index c00def598f9522ffb052fe3208a65847b306a20c..5c49fb4091d777ef98da0331e2e114e49f5008d9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -327,12 +327,14 @@ extern unsigned int kobjsize(const void *objp); #define VM_HIGH_ARCH_BIT_3 35 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_BIT_4 36 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_BIT_5 37 /* bit only usable on 64-bit architectures */ +#define VM_HIGH_ARCH_BIT_24 56 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_0 BIT(VM_HIGH_ARCH_BIT_0) #define VM_HIGH_ARCH_1 BIT(VM_HIGH_ARCH_BIT_1) #define VM_HIGH_ARCH_2 BIT(VM_HIGH_ARCH_BIT_2) #define VM_HIGH_ARCH_3 BIT(VM_HIGH_ARCH_BIT_3) #define VM_HIGH_ARCH_4 BIT(VM_HIGH_ARCH_BIT_4) #define VM_HIGH_ARCH_5 BIT(VM_HIGH_ARCH_BIT_5) +#define VM_HIGH_ARCH_24 BIT(VM_HIGH_ARCH_BIT_24) #endif /* CONFIG_ARCH_USES_HIGH_VMA_FLAGS */ #ifdef CONFIG_ARCH_HAS_PKEYS @@ -363,6 +365,12 @@ extern unsigned int kobjsize(const void *objp); # define VM_SHADOW_STACK VM_NONE #endif +#ifdef CONFIG_GMEM +#define VM_PEER_SHARED VM_HIGH_ARCH_24 +#else +#define VM_PEER_SHARED VM_NONE +#endif + #if defined(CONFIG_X86) # define VM_PAT VM_ARCH_1 /* PAT reserves whole VMA at once (x86) */ #elif defined(CONFIG_PPC) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index a077f60819d9e00cc715e406c933725b8b4f87d3..7aca9dc3c2420a777384f744c0c2f6fce7434c7f 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -940,6 +941,10 @@ struct mm_struct { #ifdef CONFIG_MEMORY_RELIABLE /* total used reliable pages */ atomic_long_t reliable_nr_page; +#endif +#ifdef CONFIG_GMEM + KABI_RESERVE(gmem_0) + KABI_RESERVE(gmem_1) #endif } __randomize_layout; diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 8d07116caaf1b037c3121bd8ca5011dd4568cdc2..56dd145de01f2276a2a1865446ae7b25884a7b61 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -407,6 +407,9 @@ enum node_states { N_MEMORY, /* The node has memory(regular, high, movable) */ N_CPU, /* The node has one or more cpus */ N_GENERIC_INITIATOR, /* The node has one or more Generic Initiators */ +#ifdef CONFIG_GMEM + N_HETEROGENEOUS, /* The node has heterogeneous memory */ +#endif NR_NODE_STATES }; diff --git a/mm/Kconfig b/mm/Kconfig index 2df11b146c8402b69c6671f96df0f41c390c817d..2f53a2787acb2bada93423875a5d1634646a3991 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1365,6 +1365,20 @@ config MEMORY_RELIABLE To enable this function, mirrored memory is needed and "kernelcore=reliable" need to be added in kernel parameters. +config GMEM + bool "generalized memory management for external memory devices" + depends on (ARM64 || X86_64) && MMU && TRANSPARENT_HUGEPAGE + select ARCH_USES_HIGH_VMA_FLAGS + default y + help + Supporting GMEM (generalized memory management) for external memory + devices + + GMEM extends Linux MM to share its machine-independent MM code. Only + high-level interface is provided for device drivers. This prevents + accelerator drivers from reinventing the wheel, but relies on drivers to + implement their hardware-dependent functions declared by GMEM. + source "mm/damon/Kconfig" endmenu diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 42e434224e6773d566a03a1558b56bd1c6d1f2b2..9b5c42b706cf97702e13070f1e3acab468046658 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -192,6 +192,9 @@ EXPORT_SYMBOL(latent_entropy); nodemask_t node_states[NR_NODE_STATES] __read_mostly = { [N_POSSIBLE] = NODE_MASK_ALL, [N_ONLINE] = { { [0] = 1UL } }, +#ifdef CONFIG_GMEM + [N_HETEROGENEOUS] = NODE_MASK_NONE, +#endif #ifndef CONFIG_NUMA [N_NORMAL_MEMORY] = { { [0] = 1UL } }, #ifdef CONFIG_HIGHMEM