[PATCHv4] mm: optimization on page allocation when CMA enabled

Message ID 1683685251-2059-1-git-send-email-zhaoyang.huang@unisoc.com
State New
Headers
Series [PATCHv4] mm: optimization on page allocation when CMA enabled |

Commit Message

zhaoyang.huang May 10, 2023, 2:20 a.m. UTC
  From: Zhaoyang Huang <zhaoyang.huang@unisoc.com>

Let us look at the series of scenarios below with WMARK_LOW=25MB,WMARK_MIN=5MB
(managed pages 1.9GB). We can know that current 'fixed 1/2 ratio' start to use
CMA since C which actually has caused U&R lower than WMARK_LOW (this should be
deemed as against current memory policy, that is, UNMOVABLE & RECLAIMABLE should
either stay around WATERMARK_LOW when no allocation or do reclaim via entering
slowpath)

-- Free_pages
|
|
-- WMARK_LOW
|
-- Free_CMA
|
|
--

Free_CMA/Free_pages(MB)      A(12/30)     B(12/25)     C(12/20)
fixed 1/2 ratio                 N             N           Y
this commit                     Y             Y           Y

Signed-off-by: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
---
v2: do proportion check when zone_watermark_ok, update commit message
v3: update coding style and simplify the logic when zone_watermark_ok
v4: code update according to Roman's suggest
---
---
 mm/page_alloc.c | 44 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 4 deletions(-)
  

Comments

Roman Gushchin May 10, 2023, 10:08 p.m. UTC | #1
On Wed, May 10, 2023 at 10:20:51AM +0800, zhaoyang.huang wrote:
> From: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
> 
> Let us look at the series of scenarios below with WMARK_LOW=25MB,WMARK_MIN=5MB
> (managed pages 1.9GB). We can know that current 'fixed 1/2 ratio' start to use
> CMA since C which actually has caused U&R lower than WMARK_LOW (this should be
> deemed as against current memory policy, that is, UNMOVABLE & RECLAIMABLE should
> either stay around WATERMARK_LOW when no allocation or do reclaim via entering
> slowpath)
> 
> -- Free_pages
> |
> |
> -- WMARK_LOW
> |
> -- Free_CMA
> |
> |
> --
> 
> Free_CMA/Free_pages(MB)      A(12/30)     B(12/25)     C(12/20)
> fixed 1/2 ratio                 N             N           Y
> this commit                     Y             Y           Y
> 
> Signed-off-by: Zhaoyang Huang <zhaoyang.huang@unisoc.com>

I'm mostly fine with the code. The commit message is still very confusing to me,
not sure I understand what exactly this table means. And you still use "U&R".

Also I'm a bit concerned about potential performance implications. Would be
great to provide some benchmarks or some data.
Probably it's ok because of we have pcp caches on top, but I'm not 100% sure.

Thanks!
  
Zhaoyang Huang May 11, 2023, 2:43 a.m. UTC | #2
On Thu, May 11, 2023 at 6:08 AM Roman Gushchin <roman.gushchin@linux.dev> wrote:
>
> On Wed, May 10, 2023 at 10:20:51AM +0800, zhaoyang.huang wrote:
> > From: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
> >
> > Let us look at the series of scenarios below with WMARK_LOW=25MB,WMARK_MIN=5MB
> > (managed pages 1.9GB). We can know that current 'fixed 1/2 ratio' start to use
> > CMA since C which actually has caused U&R lower than WMARK_LOW (this should be
> > deemed as against current memory policy, that is, UNMOVABLE & RECLAIMABLE should
> > either stay around WATERMARK_LOW when no allocation or do reclaim via entering
> > slowpath)
> >
> > -- Free_pages
> > |
> > |
> > -- WMARK_LOW
> > |
> > -- Free_CMA
> > |
> > |
> > --
> >
> > Free_CMA/Free_pages(MB)      A(12/30)     B(12/25)     C(12/20)
> > fixed 1/2 ratio                 N             N           Y
> > this commit                     Y             Y           Y
> >
> > Signed-off-by: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
>
> I'm mostly fine with the code. The commit message is still very confusing to me,
> not sure I understand what exactly this table means. And you still use "U&R".
I would like to highlight the scenario "A&B" where the previous fixed
1/2 ratio introduces over use of UNMOVABLE & RECLAIMABLE. I will try
to make it more clear by v5
>
> Also I'm a bit concerned about potential performance implications. Would be
> great to provide some benchmarks or some data.
> Probably it's ok because of we have pcp caches on top, but I'm not 100% sure.
This patch helps solve my OOM issue in v5.15. Actually, It inherit the
logic of 1/2 ratio and just behave differently when free pages is
around corresponding watermark
>
> Thanks!
  

Patch

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 0745aed..4719800 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3071,6 +3071,43 @@  static bool unreserve_highatomic_pageblock(const struct alloc_context *ac,
 
 }
 
+#ifdef CONFIG_CMA
+/*
+ * GFP_MOVABLE allocation could drain UNMOVABLE & RECLAIMABLE page blocks via
+ * the help of CMA which makes GFP_KERNEL failed. Checking if zone_watermark_ok
+ * again without ALLOC_CMA to see if to use CMA first.
+ */
+static bool use_cma_first(struct zone *zone, unsigned int order, unsigned int alloc_flags)
+{
+	unsigned long watermark;
+	bool cma_first = false;
+
+	watermark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK);
+	/* check if GFP_MOVABLE pass previous zone_watermark_ok via the help of CMA */
+	if (zone_watermark_ok(zone, order, watermark, 0, alloc_flags & (~ALLOC_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.
+		 */
+		cma_first = (zone_page_state(zone, NR_FREE_CMA_PAGES) >
+				zone_page_state(zone, NR_FREE_PAGES) / 2);
+	} else {
+		/*
+		 * watermark failed means UNMOVABLE & RECLAIMBLE is not enough
+		 * now, we should use cma first to keep them stay around the
+		 * corresponding watermark
+		 */
+		cma_first = true;
+	}
+	return cma_first;
+}
+#else
+static bool use_cma_first(struct zone *zone, unsigned int order, unsigned int alloc_flags)
+{
+	return false;
+}
+#endif
 /*
  * Do the hard work of removing an element from the buddy allocator.
  * Call me with the zone->lock already held.
@@ -3084,12 +3121,11 @@  static bool unreserve_highatomic_pageblock(const struct alloc_context *ac,
 	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 base on judging zone_watermark_ok again
+		 * to see if the latest check got pass via the help of CMA
 		 */
 		if (alloc_flags & ALLOC_CMA &&
-		    zone_page_state(zone, NR_FREE_CMA_PAGES) >
-		    zone_page_state(zone, NR_FREE_PAGES) / 2) {
+			use_cma_first(zone, order, alloc_flags)) {
 			page = __rmqueue_cma_fallback(zone, order);
 			if (page)
 				return page;