From 0bbd80928ba5819af6fcdf1f736f4306970a83fb Mon Sep 17 00:00:00 2001 From: Liam Mark Date: Wed, 8 Apr 2020 22:08:27 -0700 Subject: [PATCH] mm: Allow only __GFP_OFFLINABLE allocations from Movable zone Ensure that only allocations which include __GFP_OFFLINABLE can be satisfied from zone Movable. This restriction helps reduces the likelihood of a page in the movable zone being pinned which would prevent memory from being offlined. In the past we allowed all __GFP_CMA allocations to be satisfied from Movable zone but now add support to differentiate between __GFP_CMA allocations and __GFP_OFFLINABLE allocations so that we can target certain allocations at CMA regions and certain allocations at the Movable zone. Change-Id: If2a9381b6d677f825ad53af9cd64f206d41da211 Signed-off-by: Liam Mark --- include/linux/gfp.h | 26 +++++++++++++++----------- mm/Kconfig | 8 ++++++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 8abea3e45d0b..51868a24e5c3 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -39,19 +39,20 @@ struct vm_area_struct; #define ___GFP_HARDWALL 0x100000u #define ___GFP_THISNODE 0x200000u #define ___GFP_ACCOUNT 0x400000u +#ifdef CONFIG_LOCKDEP +#define ___GFP_NOLOCKDEP 0x800000u +#else +#define ___GFP_NOLOCKDEP 0 +#endif #ifdef CONFIG_CMA_DIRECT_UTILIZATION -#define ___GFP_CMA 0x800000u +#define ___GFP_CMA 0x1000000u #else #define ___GFP_CMA 0 #endif -#ifdef CONFIG_LOCKDEP -#ifdef CONFIG_CMA_DIRECT_UTILIZATION -#define ___GFP_NOLOCKDEP 0x1000000u +#ifdef CONFIG_LIMIT_MOVABLE_ZONE_ALLOC +#define ___GFP_OFFLINABLE 0x2000000u #else -#define __GFP_NOLOCKDEP 0x800000u -#endif -#else -#define ___GFP_NOLOCKDEP 0 +#define ___GFP_OFFLINABLE 0 #endif /* If the above are modified, __GFP_BITS_SHIFT may need updating */ @@ -67,6 +68,7 @@ struct vm_area_struct; #define __GFP_DMA32 ((__force gfp_t)___GFP_DMA32) #define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE) /* ZONE_MOVABLE allowed */ #define __GFP_CMA ((__force gfp_t)___GFP_CMA) +#define __GFP_OFFLINABLE ((__force gfp_t)___GFP_OFFLINABLE) #define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE) /** @@ -227,8 +229,10 @@ struct vm_area_struct; #define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP) /* Room for N __GFP_FOO bits */ -#ifdef CONFIG_CMA_DIRECT_UTILIZATION -#define __GFP_BITS_SHIFT (24 + IS_ENABLED(CONFIG_LOCKDEP)) +#ifdef CONFIG_LIMIT_MOVABLE_ZONE_ALLOC +#define __GFP_BITS_SHIFT 26 +#elif defined CONFIG_CMA_DIRECT_UTILIZATION +#define __GFP_BITS_SHIFT 25 #else #define __GFP_BITS_SHIFT (23 + IS_ENABLED(CONFIG_LOCKDEP)) #endif @@ -458,7 +462,7 @@ static inline enum zone_type gfp_zone(gfp_t flags) int bit; if (!IS_ENABLED(CONFIG_HIGHMEM)) { - if ((flags & __GFP_MOVABLE) && !(flags & __GFP_CMA)) + if ((flags & __GFP_MOVABLE) && !(flags & __GFP_OFFLINABLE)) flags &= ~__GFP_HIGHMEM; } diff --git a/mm/Kconfig b/mm/Kconfig index e3de9157cf22..e3abea672f99 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -558,6 +558,14 @@ config CMA_PCP_LISTS allocations, as the amount of non-CMA memory to be reclaimed should be smaller. +config LIMIT_MOVABLE_ZONE_ALLOC + bool "Limit types of allocations from Movable zone" + help + Ensure that only allocations which include __GFP_OFFLINABLE can be + satisfied from zone Movable. This restriction helps reduce the + likelihood of a page in the movable zone being pinned which would + prevent memory from being offlined. + config MEM_SOFT_DIRTY bool "Track memory changes" depends on CHECKPOINT_RESTORE && HAVE_ARCH_SOFT_DIRTY && PROC_FS