[RFC PATCH 09/11] mm: Count isolated pages as "treated"

From: Alexander Duyck
Date: Thu May 30 2019 - 17:58:25 EST


From: Alexander Duyck <alexander.h.duyck@xxxxxxxxxxxxxxx>

Treat isolated pages as though they have already been treated. We do this
so that we can avoid trying to treat pages that have been marked for
isolation. The issue is that we don't want to run into issues where we are
treating a page, and when we put it back we find it has been moved into the
isolated migratetype, nor would we want to pull pages out of the isolated
migratetype and then find that they are now being located in a different
migratetype.

To avoid those issues we can specifically mark all isolated pages as being
"treated" and avoid special case handling for them since they will never be
merged anyway, so we can just add them to the head of the free_list.

In addition we will skip over the isolate migratetype when getting raw
pages.

Signed-off-by: Alexander Duyck <alexander.h.duyck@xxxxxxxxxxxxxxx>
---
include/linux/mmzone.h | 7 +++++++
mm/aeration.c | 8 ++++++--
mm/page_alloc.c | 2 +-
3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index be996e8ca6b5..f749ccfcc62a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -137,6 +137,13 @@ static inline void add_to_free_area_tail(struct page *page, struct free_area *ar
{
area->nr_free_treated++;

+#ifdef CONFIG_MEMORY_ISOLATION
+ /* Bypass membrane for isolated pages, all are considered "treated" */
+ if (migratetype == MIGRATE_ISOLATE) {
+ list_add(&page->lru, &area->free_list[migratetype]);
+ return;
+ }
+#endif
BUG_ON(area->treatment_mt != migratetype);

/* Insert page above membrane, then move membrane to the page */
diff --git a/mm/aeration.c b/mm/aeration.c
index aaf8af8d822f..f921295ed3ae 100644
--- a/mm/aeration.c
+++ b/mm/aeration.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/memory_aeration.h>
+#include <linux/mm.h>
#include <linux/mmzone.h>
+#include <linux/page-isolation.h>
#include <linux/gfp.h>
#include <linux/export.h>
#include <linux/delay.h>
@@ -83,8 +85,10 @@ static int __aerator_fill(struct zone *zone, unsigned int size)
* new raw pages can build. In the meantime move on
* to the next migratetype.
*/
- if (++mt >= MIGRATE_TYPES)
- mt = 0;
+ do {
+ if (++mt >= MIGRATE_TYPES)
+ mt = 0;
+ } while (is_migrate_isolate(mt));

/*
* Pull pages from free list until we have drained
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e79c65413dc9..e3800221414b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -989,7 +989,7 @@ static inline void __free_one_page(struct page *page,
set_page_order(page, order);

area = &zone->free_area[order];
- if (PageTreated(page)) {
+ if (is_migrate_isolate(migratetype) || PageTreated(page)) {
add_to_free_area_treated(page, area, migratetype);
return;
}