[Devel] [PATCH RHEL7 COMMIT] mm: add warning about high order allocations
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Jan 18 16:35:31 MSK 2018
The commit is pushed to "branch-rh7-3.10.0-693.11.6.vz7.42.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.11.6.vz7.42.1
------>
commit 2669ee7a8b5a8c5dd4c6a0ba02da63aa8da607a4
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date: Thu Jan 18 16:35:05 2018 +0300
mm: add warning about high order allocations
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 <aryabinin at 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 9267ac19d76f..70f1219103a5 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, \
@@ -1657,6 +1663,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 91e0681620b4..ec66148d09ba 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3136,6 +3136,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.
*/
@@ -3159,6 +3190,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;
More information about the Devel
mailing list