mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			67 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From d3682a46e323983f46ad03e27cc535e9c2304a71 Mon Sep 17 00:00:00 2001
 | 
						|
From: David Plowman <david.plowman@raspberrypi.com>
 | 
						|
Date: Tue, 29 Mar 2022 16:10:06 +0100
 | 
						|
Subject: [PATCH] mm,page_alloc,cma: introduce a customisable threshold for
 | 
						|
 allocating pages in cma
 | 
						|
 | 
						|
On some platforms the cma area can be half the entire system memory,
 | 
						|
meaning that allocations start happening in the cma area immediately.
 | 
						|
This leads to fragmentation and subsequent fatal cma_alloc failures.
 | 
						|
 | 
						|
We introduce an "alloc_in_cma_threshold" parameter which requires that
 | 
						|
this many sixteenths of the free pages must be in cma before it will
 | 
						|
try to use them. By default this is set to 12, but the previous
 | 
						|
behaviour can be restored by setting it to 8 on startup.
 | 
						|
 | 
						|
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
 | 
						|
---
 | 
						|
 mm/page_alloc.c | 28 +++++++++++++++++++++++++---
 | 
						|
 1 file changed, 25 insertions(+), 3 deletions(-)
 | 
						|
 | 
						|
--- a/mm/page_alloc.c
 | 
						|
+++ b/mm/page_alloc.c
 | 
						|
@@ -253,6 +253,27 @@ EXPORT_SYMBOL(init_on_alloc);
 | 
						|
 DEFINE_STATIC_KEY_MAYBE(CONFIG_INIT_ON_FREE_DEFAULT_ON, init_on_free);
 | 
						|
 EXPORT_SYMBOL(init_on_free);
 | 
						|
 
 | 
						|
+#define ALLOC_IN_CMA_THRESHOLD_MAX 16
 | 
						|
+#define ALLOC_IN_CMA_THRESHOLD_DEFAULT 12
 | 
						|
+
 | 
						|
+static unsigned long _alloc_in_cma_threshold __read_mostly
 | 
						|
+				= ALLOC_IN_CMA_THRESHOLD_DEFAULT;
 | 
						|
+
 | 
						|
+static int __init alloc_in_cma_threshold_setup(char *buf)
 | 
						|
+{
 | 
						|
+	unsigned long res;
 | 
						|
+
 | 
						|
+	if (kstrtoul(buf, 10, &res) < 0 ||
 | 
						|
+	    res > ALLOC_IN_CMA_THRESHOLD_MAX) {
 | 
						|
+		pr_err("Bad alloc_cma_threshold value\n");
 | 
						|
+		return 0;
 | 
						|
+	}
 | 
						|
+	_alloc_in_cma_threshold = res;
 | 
						|
+	pr_info("Setting alloc_in_cma_threshold to %lu\n", res);
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+early_param("alloc_in_cma_threshold", alloc_in_cma_threshold_setup);
 | 
						|
+
 | 
						|
 static bool _init_on_alloc_enabled_early __read_mostly
 | 
						|
 				= IS_ENABLED(CONFIG_INIT_ON_ALLOC_DEFAULT_ON);
 | 
						|
 static int __init early_init_on_alloc(char *buf)
 | 
						|
@@ -3073,12 +3094,13 @@ __rmqueue(struct zone *zone, unsigned in
 | 
						|
 	if (IS_ENABLED(CONFIG_CMA)) {
 | 
						|
 		/*
 | 
						|
 		 * Balance movable allocations between regular and CMA areas by
 | 
						|
-		 * allocating from CMA when over half of the zone's free memory
 | 
						|
-		 * is in the CMA area.
 | 
						|
+		 * allocating from CMA when over more than a given proportion of
 | 
						|
+		 * the zone's free memory is in the CMA area.
 | 
						|
 		 */
 | 
						|
 		if (alloc_flags & ALLOC_CMA &&
 | 
						|
 		    zone_page_state(zone, NR_FREE_CMA_PAGES) >
 | 
						|
-		    zone_page_state(zone, NR_FREE_PAGES) / 2) {
 | 
						|
+		    zone_page_state(zone, NR_FREE_PAGES) / ALLOC_IN_CMA_THRESHOLD_MAX
 | 
						|
+		    * _alloc_in_cma_threshold) {
 | 
						|
 			page = __rmqueue_cma_fallback(zone, order);
 | 
						|
 			if (page)
 | 
						|
 				return page;
 |