[PATCH] mm/compaction: use proper zoneid for compaction_suitable()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



By now there're three compaction paths,
- direct compaction
- kcompactd compcation
- proc triggered compaction
When we do compaction in all these paths, we will use compaction_suitable()
to check whether a zone is suitable to do compaction.

There're some issues around the usage of compaction_suitable().
We don't use the proper zoneid in kcompactd_node_suitable() when try to
wakeup kcompactd. In the kcompactd compaction paths, we call
compaction_suitable() twice and the zoneid isn't proper in the second call.
For proc triggered compaction, the classzone_idx is always zero.

In order to fix these issues, I change the type of classzone_idx in the
struct compact_control from const int to int and assign the proper zoneid
before calling compact_zone().

This patch also fixes some comments in struct compact_control, as these
fields are not only for direct compactor but also for all other compactors.

Fixes: ebff398017c6("mm, compaction: pass classzone_idx and alloc_flags to watermark checking")
Fixes: 698b1b30642f("mm, compaction: introduce kcompactd")
Signed-off-by: Yafang Shao <laoar.shao@xxxxxxxxx>
Cc: Vlastimil Babka <vbabka@xxxxxxx>
Cc: Arnd Bergmann <arnd@xxxxxxxx>
Cc: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx>
Cc: Rik van Riel <riel@xxxxxxxxxx>
Cc: Yafang Shao <shaoyafang@xxxxxxxxxxxxxx>
---
 mm/compaction.c | 12 +++++-------
 mm/internal.h   | 10 +++++-----
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index ac4ead0..984dea7 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -2425,6 +2425,7 @@ static void compact_node(int nid)
 			continue;
 
 		cc.zone = zone;
+		cc.classzone_idx = zoneid;
 
 		compact_zone(&cc, NULL);
 
@@ -2508,7 +2509,7 @@ static bool kcompactd_node_suitable(pg_data_t *pgdat)
 			continue;
 
 		if (compaction_suitable(zone, pgdat->kcompactd_max_order, 0,
-					classzone_idx) == COMPACT_CONTINUE)
+					zoneid) == COMPACT_CONTINUE)
 			return true;
 	}
 
@@ -2526,7 +2527,6 @@ static void kcompactd_do_work(pg_data_t *pgdat)
 	struct compact_control cc = {
 		.order = pgdat->kcompactd_max_order,
 		.search_order = pgdat->kcompactd_max_order,
-		.classzone_idx = pgdat->kcompactd_classzone_idx,
 		.mode = MIGRATE_SYNC_LIGHT,
 		.ignore_skip_hint = false,
 		.gfp_mask = GFP_KERNEL,
@@ -2535,7 +2535,7 @@ static void kcompactd_do_work(pg_data_t *pgdat)
 							cc.classzone_idx);
 	count_compact_event(KCOMPACTD_WAKE);
 
-	for (zoneid = 0; zoneid <= cc.classzone_idx; zoneid++) {
+	for (zoneid = 0; zoneid <= pgdat->kcompactd_classzone_idx; zoneid++) {
 		int status;
 
 		zone = &pgdat->node_zones[zoneid];
@@ -2545,14 +2545,12 @@ static void kcompactd_do_work(pg_data_t *pgdat)
 		if (compaction_deferred(zone, cc.order))
 			continue;
 
-		if (compaction_suitable(zone, cc.order, 0, zoneid) !=
-							COMPACT_CONTINUE)
-			continue;
-
 		if (kthread_should_stop())
 			return;
 
 		cc.zone = zone;
+		cc.classzone_idx = zoneid;
+
 		status = compact_zone(&cc, NULL);
 
 		if (status == COMPACT_SUCCESS) {
diff --git a/mm/internal.h b/mm/internal.h
index 0d5f720..c224a16 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -190,11 +190,11 @@ struct compact_control {
 	unsigned long total_free_scanned;
 	unsigned short fast_search_fail;/* failures to use free list searches */
 	short search_order;		/* order to start a fast search at */
-	const gfp_t gfp_mask;		/* gfp mask of a direct compactor */
-	int order;			/* order a direct compactor needs */
-	int migratetype;		/* migratetype of direct compactor */
-	const unsigned int alloc_flags;	/* alloc flags of a direct compactor */
-	const int classzone_idx;	/* zone index of a direct compactor */
+	const gfp_t gfp_mask;		/* gfp mask of a compactor */
+	int order;			/* order a compactor needs */
+	int migratetype;		/* migratetype of a compactor */
+	const unsigned int alloc_flags;	/* alloc flags of a compactor */
+	int classzone_idx;		/* zone index of a compactor */
 	enum migrate_mode mode;		/* Async or sync migration mode */
 	bool ignore_skip_hint;		/* Scan blocks even if marked skip */
 	bool no_set_skip_hint;		/* Don't mark blocks for skipping */
-- 
1.8.3.1




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux