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> --- kernel/sysctl.c | 15 +++++++++++++++ mm/page_alloc.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index e2d83c602b01..1de17f161be3 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -128,6 +128,7 @@ static int __maybe_unused one = 1; static int __maybe_unused two = 2; static int __maybe_unused four = 4; static unsigned long one_ul = 1; +static int ten = 10; static int one_hundred = 100; #ifdef CONFIG_PRINTK static int ten_thousand = 10000; @@ -174,6 +175,11 @@ extern int unaligned_dump_stack; extern int no_unaligned_warning; #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); + + static bool virtual_ptr(void **ptr, void *base, size_t size, void *cur); #define sysctl_virtual(sysctl) \ int sysctl ## _virtual(struct ctl_table *table, int write, \ @@ -1664,6 +1670,15 @@ static struct ctl_table vm_table[] = { .extra2 = &one_hundred, }, #endif + { + .procname = "warn_high_order", + .data = &warn_order, + .maxlen = sizeof(warn_order), + .mode = 0644, + .proc_handler = &proc_warn_high_order, + .extra1 = &zero, + .extra2 = &ten, + }, { } }; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6f7cb012508e..e0a390866d4f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3138,6 +3138,37 @@ static void __alloc_collect_stats(gfp_t gfp_mask, unsigned int order, #endif } +struct static_key warn_high_order_key = STATIC_KEY_INIT_FALSE; +int warn_order = MAX_ORDER+1; + +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)) + WARN(atomic_dec_return(&warn_count), + "order %d >= %d, gfp 0x%x\n", + order, tmp_warn_order, gfp_mask); + } +} + /* * This is the 'heart' of the zoned buddy allocator. */ @@ -3161,6 +3192,8 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, WARN_ON_ONCE((gfp_mask & __GFP_FS) && current->journal_info && !(current->flags & PF_MEMALLOC)); + warn_high_order(order, gfp_mask); + if (should_fail_alloc_page(gfp_mask, order)) return NULL; -- 2.13.6 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel