[Devel] [PATCH vz7] mm: fix high order allocation warning limits

Oleg Babin obabin at virtuozzo.com
Wed Mar 7 16:29:38 MSK 2018


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. Make the default value and the maximum value to be the same.

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.

https://jira.sw.ru/browse/PSBM-82202
Signed-off-by: Oleg Babin <obabin at virtuozzo.com>
---
 kernel/sysctl.c | 7 ++++---
 mm/page_alloc.c | 6 ++++--
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 70f1219..99ed610c 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -128,7 +128,6 @@ 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;
@@ -176,6 +175,8 @@ extern int no_unaligned_warning;
 #endif
 
 extern int warn_order;
+extern int warn_order_min;
+extern int warn_order_max;
 extern int proc_warn_high_order(struct ctl_table *table, int write,
 			void __user *buffer, size_t *lenp, loff_t *ppos);
 
@@ -1669,8 +1670,8 @@ static struct ctl_table vm_table[] = {
 		.maxlen		= sizeof(warn_order),
 		.mode		= 0644,
 		.proc_handler	= &proc_warn_high_order,
-		.extra1		= &zero,
-		.extra2		= &ten,
+		.extra1		= &warn_order_min,
+		.extra2		= &warn_order_max,
 	},
 	{ }
 };
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index fed5d87..7a08e4c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3168,7 +3168,9 @@ static void __alloc_collect_stats(gfp_t gfp_mask, unsigned int order,
 }
 
 struct static_key warn_high_order_key = STATIC_KEY_INIT_FALSE;
-int warn_order = MAX_ORDER+1;
+int warn_order_min = 0;
+int warn_order_max = MAX_ORDER + 1;
+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)
@@ -3192,7 +3194,7 @@ static __always_inline void warn_high_order(int order, gfp_t gfp_mask)
 		int tmp_warn_order = smp_load_acquire(&warn_order);
 
 		if (order >= tmp_warn_order && !(gfp_mask & __GFP_NOWARN))
-			WARN(atomic_dec_return(&warn_count),
+			WARN(atomic_dec_if_positive(&warn_count) >= 0,
 				"order %d >= %d, gfp 0x%x\n",
 				order, tmp_warn_order, gfp_mask);
 	}
-- 
1.8.3.1



More information about the Devel mailing list