From: Andrey Ryabinin <aryabi...@virtuozzo.com> Add sysctl vm.warn_high_order. If set it will warn about about allocations with order >= vm.warn_high_order. Prints only 32 warning at most and skips all __GFP_NOWARN allocations. Disabled by default.
https://jira.sw.ru/browse/PSBM-79892 Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com> +++ mm: fix high order allocation warning limits After sysctl parameter 'vm.warn_high_order' is modified it can't be returned back to the default value MAX_ORDER+1, only to the fixed value 10. Set the maximum value to 100 which is always larger than any maximum order. Also set the default value to MAX_ORDER as it is already the value which can never be allocated. Also there is a logic to stop generating the warning after 32 occurences, but the logic is broken (the warning is generated even after the counter becomes less than zero). Modify the procedure of checking the counter. mFixes: 1ab81385c03f ("mm: add warning about high order allocations") https://jira.sw.ru/browse/PSBM-82202 Signed-off-by: Oleg Babin <oba...@virtuozzo.com> Acked-by: Andrey Ryabinin <aryabi...@virtuozzo.com> https://jira.sw.ru/browse/PSBM-103814 (cherry picked from commit d853914118665ae6fe7b87bd4702215ba6f5daef) Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com> +++ mm: add __GFP_ flag to hide verified high order allocation warnings Using __GFP_NOWARN to hide known high order allocation warnings is not the best solution as it supresses allocation failures as well, so let's add an independent __GFP_ORDER_NOWARN flag for that. mFixes: 22b422587aab mm: add warning about high order allocations https://pmc.acronis.com/browse/VSTOR-20383 https://pmc.acronis.com/browse/VSTOR-20349 Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com> https://jira.sw.ru/browse/PSBM-103814 (cherry picked from commit 66f0d9c1678847ee476af8d511839728d144c83b) Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com> (cherry picked from vz8 commit b536d715903644b3095ab2f935a205bca3af49da) Signed-off-by: Andrey Zhadchenko <andrey.zhadche...@virtuozzo.com> --- include/linux/gfp.h | 9 +++++++-- kernel/sysctl.c | 13 +++++++++++++ mm/page_alloc.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 55b2ec1..39de4eb 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -55,8 +55,9 @@ #define ___GFP_ACCOUNT 0x400000u #define ___GFP_ZEROTAGS 0x800000u #define ___GFP_SKIP_KASAN_POISON 0x1000000u +#define ___GFP_ORDER_NOWARN 0x2000000u #ifdef CONFIG_LOCKDEP -#define ___GFP_NOLOCKDEP 0x2000000u +#define ___GFP_NOLOCKDEP 0x4000000u #else #define ___GFP_NOLOCKDEP 0 #endif @@ -238,18 +239,22 @@ * %__GFP_SKIP_KASAN_POISON returns a page which does not need to be poisoned * on deallocation. Typically used for userspace pages. Currently only has an * effect in HW tags mode. + * + * __GFP_ORDER_NOWARN suppresses reports about allocation of too high order + * pages. */ #define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN) #define __GFP_COMP ((__force gfp_t)___GFP_COMP) #define __GFP_ZERO ((__force gfp_t)___GFP_ZERO) #define __GFP_ZEROTAGS ((__force gfp_t)___GFP_ZEROTAGS) #define __GFP_SKIP_KASAN_POISON ((__force gfp_t)___GFP_SKIP_KASAN_POISON) +#define __GFP_ORDER_NOWARN ((__force gfp_t)___GFP_ORDER_NOWARN) /* Disable lockdep for GFP context tracking */ #define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP) /* Room for N __GFP_FOO bits */ -#define __GFP_BITS_SHIFT (25 + IS_ENABLED(CONFIG_LOCKDEP)) +#define __GFP_BITS_SHIFT (26 + IS_ENABLED(CONFIG_LOCKDEP)) #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /** diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 081e4217..65d57a4 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -155,6 +155,10 @@ #include <linux/fanotify.h> #endif +extern int warn_order; +extern int proc_warn_high_order(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + #ifdef CONFIG_PROC_SYSCTL /** @@ -3171,6 +3175,15 @@ int proc_do_static_key(struct ctl_table *table, int write, .extra2 = SYSCTL_ONE, }, #endif + { + .procname = "warn_high_order", + .data = &warn_order, + .maxlen = sizeof(warn_order), + .mode = 0644, + .proc_handler = &proc_warn_high_order, + .extra1 = SYSCTL_ONE, + .extra2 = &one_hundred, + }, { } }; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 07512b8..710e60e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5346,6 +5346,38 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid, } EXPORT_SYMBOL_GPL(__alloc_pages_bulk); +struct static_key warn_high_order_key = STATIC_KEY_INIT_FALSE; +int warn_order = MAX_ORDER; + +int proc_warn_high_order(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (!ret) { + smp_wmb(); + static_key_slow_inc(&warn_high_order_key); + } + + return ret; +} + +static __always_inline void warn_high_order(int order, gfp_t gfp_mask) +{ + static atomic_t warn_count = ATOMIC_INIT(32); + + if (static_key_false(&warn_high_order_key)) { + int tmp_warn_order = smp_load_acquire(&warn_order); + + if (order >= tmp_warn_order && + !(gfp_mask & (__GFP_NOWARN|__GFP_ORDER_NOWARN))) + WARN(atomic_dec_if_positive(&warn_count) >= 0, + "order %d >= %d, gfp 0x%x\n", + order, tmp_warn_order, gfp_mask); + } +} + /* * This is the 'heart' of the zoned buddy allocator. */ @@ -5376,6 +5408,9 @@ struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid, */ gfp = current_gfp_context(gfp); alloc_gfp = gfp; + + warn_high_order(order, gfp); + if (!prepare_alloc_pages(gfp, order, preferred_nid, nodemask, &ac, &alloc_gfp, &alloc_flags)) return NULL; -- 1.8.3.1 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel