Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1282753 > unrolled thread

[PATCH v3 0/7] mm/compaction: redesign compaction: part1

Started byJoonsoo Kim <js1304@gmail.com>
First post2015-12-03 08:20 +0100
Last post2015-12-03 08:20 +0100
Articles 5 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v3 0/7] mm/compaction: redesign compaction: part1 Joonsoo Kim <js1304@gmail.com> - 2015-12-03 08:20 +0100
    [PATCH v3 2/7] mm/compaction: remove unused defer_compaction() in compaction.h Joonsoo Kim <js1304@gmail.com> - 2015-12-03 08:20 +0100
      Re: [PATCH v3 2/7] mm/compaction: remove unused defer_compaction() in  compaction.h Vlastimil Babka <vbabka@suse.cz> - 2015-12-04 16:30 +0100
    [PATCH v3 6/7] mm/compaction: introduce migration scan limit Joonsoo Kim <js1304@gmail.com> - 2015-12-03 08:20 +0100
    [PATCH v3 7/7] mm/compaction: replace compaction deferring with compaction limit Joonsoo Kim <js1304@gmail.com> - 2015-12-03 08:20 +0100

#1282753 — [PATCH v3 0/7] mm/compaction: redesign compaction: part1

FromJoonsoo Kim <js1304@gmail.com>
Date2015-12-03 08:20 +0100
Subject[PATCH v3 0/7] mm/compaction: redesign compaction: part1
Message-ID<qBwlj-1No-7@gated-at.bofh.it>
Major changes from v2:
o Split patchset into two parts, one is for replacing compaction
deferring with compaction limit and the other is for changing
scanner activity
o Add some fixes and cleanup for current defer logic
o Fix opposite direction problem in "skip useless pfn when..." patch
o Reuse current defer logic for compaction limit
o Provide proper argument when calling __reset_isolation_suitable()
o Prevent async compaction while compaction limit is activated

Previous cover-letter isn't appropriate for this part1 patchset so
I just append link about it.

https://lkml.org/lkml/2015/8/23/182

New description:
Compaction deferring effectively reduces compaction overhead if
compaction success isn't expected. But, it is implemented that
skipping a number of compaction requests until compaction is re-enabled.
Due to this implementation, unfortunate compaction requestor will get
whole compaction overhead unlike others have zero overhead. And, after
deferring start to work, even if compaction success possibility is
restored, we should skip to compaction in some number of times.

This patch try to solve above problem by using compaction limit.
Instead of imposing compaction overhead to one unfortunate requestor,
compaction limit distributes overhead to all compaction requestors.
All requestors have a chance to migrate some amount of pages and
after limit is exhausted compaction will be stopped. This will fairly
distributes overhead to all compaction requestors. And, because we don't
defer compaction request, someone will succeed to compact as soon as
possible if compaction success possiblility is restored.

I tested this patch on my compaction benchmark and found that high-order
allocation latency is evenly distributed and there is no latency spike
in the situation where compaction success isn't possible.

Following is the result of each high-order allocation latency (ns).
Base vs Limit

9807 failure 825        9807 failure 10839
9808 failure 820        9808 failure 9762
9809 failure 827        9809 failure 8585
9810 failure 3751       9810 failure 14052
9811 failure 881        9811 failure 10781
9812 failure 827        9812 failure 9906
9813 failure 2447430    9813 failure 8925
9814 failure 8632       9814 failure 9185
9815 failure 1172       9815 failure 9076
9816 failure 1045       9816 failure 10860
9817 failure 1044       9817 failure 10571
9818 failure 1043       9818 failure 8789
9819 failure 979        9819 failure 9086
9820 failure 4338       9820 failure 43681
9821 failure 1001       9821 failure 9361
9822 failure 875        9822 failure 15175
9823 failure 822        9823 failure 9394
9824 failure 827        9824 failure 334341
9825 failure 829        9825 failure 15404
9826 failure 823        9826 failure 10419
9827 failure 824        9827 failure 11375
9828 failure 827        9828 failure 9416
9829 failure 822        9829 failure 9303
9830 failure 3646       9830 failure 18514
9831 failure 869        9831 failure 11064
9832 failure 820        9832 failure 9626
9833 failure 832        9833 failure 8794
9834 failure 820        9834 failure 10576
9835 failure 2450955    9835 failure 12260
9836 failure 9428       9836 failure 9049
9837 failure 1067       9837 failure 10346
9838 failure 968        9838 failure 8793
9839 failure 984        9839 failure 8932
9840 failure 4262       9840 failure 18436
9841 failure 964        9841 failure 11429
9842 failure 937        9842 failure 9433
9843 failure 828        9843 failure 8838
9844 failure 827        9844 failure 8948
9845 failure 822        9845 failure 13017
9846 failure 827        9846 failure 10795

As you can see, Base has a latency spike periodically, but,
in Limit, latency is distributed evenly.

This patchset is based on linux-next-20151106 +
"restore COMPACT_CLUSTER_MAX to 32" + "__compact_pgdat() code cleanuup"
which are sent by me today.

Thanks.

Joonsoo Kim (7):
  mm/compaction: skip useless pfn when updating cached pfn
  mm/compaction: remove unused defer_compaction() in compaction.h
  mm/compaction: initialize compact_order_failed to MAX_ORDER
  mm/compaction: update defer counter when allocation is expected to
    succeed
  mm/compaction: respect compaction order when updating defer counter
  mm/compaction: introduce migration scan limit
  mm/compaction: replace compaction deferring with compaction limit

 include/linux/compaction.h        |   3 -
 include/linux/mmzone.h            |   6 +-
 include/trace/events/compaction.h |   7 +-
 mm/compaction.c                   | 188 ++++++++++++++++++++++++--------------
 mm/internal.h                     |   1 +
 mm/page_alloc.c                   |   4 +-
 6 files changed, 125 insertions(+), 84 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1282754 — [PATCH v3 2/7] mm/compaction: remove unused defer_compaction() in compaction.h

FromJoonsoo Kim <js1304@gmail.com>
Date2015-12-03 08:20 +0100
Subject[PATCH v3 2/7] mm/compaction: remove unused defer_compaction() in compaction.h
Message-ID<qBwlj-1No-17@gated-at.bofh.it>
In reply to#1282753
It's not used externally. Remove it in compaction.h.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
 include/linux/compaction.h | 1 -
 mm/compaction.c            | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index 4cd4ddf..359b07a 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -46,7 +46,6 @@ extern void reset_isolation_suitable(pg_data_t *pgdat);
 extern unsigned long compaction_suitable(struct zone *zone, int order,
 					int alloc_flags, int classzone_idx);
 
-extern void defer_compaction(struct zone *zone, int order);
 extern bool compaction_deferred(struct zone *zone, int order);
 extern void compaction_defer_reset(struct zone *zone, int order,
 				bool alloc_success);
diff --git a/mm/compaction.c b/mm/compaction.c
index 564047c..f144494 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -124,7 +124,7 @@ static struct page *pageblock_pfn_to_page(unsigned long start_pfn,
  * allocation success. 1 << compact_defer_limit compactions are skipped up
  * to a limit of 1 << COMPACT_MAX_DEFER_SHIFT
  */
-void defer_compaction(struct zone *zone, int order)
+static void defer_compaction(struct zone *zone, int order)
 {
 	zone->compact_considered = 0;
 	zone->compact_defer_shift++;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1283915 — Re: [PATCH v3 2/7] mm/compaction: remove unused defer_compaction() in compaction.h

FromVlastimil Babka <vbabka@suse.cz>
Date2015-12-04 16:30 +0100
SubjectRe: [PATCH v3 2/7] mm/compaction: remove unused defer_compaction() in compaction.h
Message-ID<qC0t3-4sT-7@gated-at.bofh.it>
In reply to#1282754
On 12/03/2015 08:11 AM, Joonsoo Kim wrote:
> It's not used externally. Remove it in compaction.h.
>
> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

Acked-by: Vlastimil Babka <vbabka@suse.cz>

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1282755 — [PATCH v3 6/7] mm/compaction: introduce migration scan limit

FromJoonsoo Kim <js1304@gmail.com>
Date2015-12-03 08:20 +0100
Subject[PATCH v3 6/7] mm/compaction: introduce migration scan limit
Message-ID<qBwlj-1No-15@gated-at.bofh.it>
In reply to#1282753
This is preparation step to replace compaction deferring with compaction
limit. Whole reason why we need to replace it will be mentioned in
the following patch.

In this patch, migration_scan_limit is assigned and accounted, but, not
checked to finish. So, there is no functional change.

Currently, amount of migration_scan_limit is chosen to imitate compaction
deferring logic. We can tune it easily if overhead looks insane, but,
it would be further work.
Also, amount of migration_scan_limit is adapted by compact_defer_shift.
More fails increase compact_defer_shift and this will limit compaction
more.

There are two interesting changes. One is that cached pfn is always
updated while limit is activated. Otherwise, we would scan same range
over and over. Second one is that async compaction is skipped while
limit is activated, for algorithm correctness. Until now, even if
failure case, sync compaction continue to work when both scanner is met
so COMPACT_COMPLETE usually happens in sync compaction. But, limit is
applied, sync compaction is finished if limit is exhausted so
COMPACT_COMPLETE usually happens in async compaction. Because we don't
consider async COMPACT_COMPLETE as actual fail while we reset cached
scanner pfn, defer mechanism doesn't work well. And, async compaction
would not be easy to succeed in this case so skipping async compaction
doesn't result in much difference.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
 mm/compaction.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 mm/internal.h   |  1 +
 2 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index 1a75a6e..b23f6d9 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -116,6 +116,67 @@ static struct page *pageblock_pfn_to_page(unsigned long start_pfn,
 
 #ifdef CONFIG_COMPACTION
 
+/*
+ * order == -1 is expected when compacting via
+ * /proc/sys/vm/compact_memory
+ */
+static inline bool is_via_compact_memory(int order)
+{
+	return order == -1;
+}
+
+#define COMPACT_MIN_SCAN_LIMIT (pageblock_nr_pages)
+
+static bool excess_migration_scan_limit(struct compact_control *cc)
+{
+	/* Disable scan limit for now */
+	return false;
+}
+
+static void set_migration_scan_limit(struct compact_control *cc)
+{
+	struct zone *zone = cc->zone;
+	int order = cc->order;
+	unsigned long limit = zone->managed_pages;
+
+	cc->migration_scan_limit = LONG_MAX;
+	if (is_via_compact_memory(order))
+		return;
+
+	if (order < zone->compact_order_failed)
+		return;
+
+	if (!zone->compact_defer_shift)
+		return;
+
+	/*
+	 * Do not allow async compaction during limit work. In this case,
+	 * async compaction would not be easy to succeed and we need to
+	 * ensure that COMPACT_COMPLETE occurs by sync compaction for
+	 * algorithm correctness and prevention of async compaction will
+	 * lead it.
+	 */
+	if (cc->mode == MIGRATE_ASYNC) {
+		cc->migration_scan_limit = -1;
+		return;
+	}
+
+	/* Migration scanner usually scans less than 1/4 pages */
+	limit >>= 2;
+
+	/*
+	 * Deferred compaction restart compaction every 64 compaction
+	 * attempts and it rescans whole zone range. To imitate it,
+	 * we set limit to 1/64 of scannable range.
+	 */
+	limit >>= 6;
+
+	/* Degradation scan limit according to defer shift */
+	limit >>= zone->compact_defer_shift;
+
+	cc->migration_scan_limit = max(limit, COMPACT_MIN_SCAN_LIMIT);
+}
+
 /* Do not skip compaction more than 64 times */
 #define COMPACT_MAX_DEFER_SHIFT 6
 
@@ -263,10 +324,15 @@ static void update_pageblock_skip(struct compact_control *cc,
 	if (!page)
 		return;
 
-	if (nr_isolated)
+	/*
+	 * Always update cached_pfn if compaction has scan_limit,
+	 * otherwise we would scan same range over and over.
+	 */
+	if (cc->migration_scan_limit == LONG_MAX && nr_isolated)
 		return;
 
-	set_pageblock_skip(page);
+	if (!nr_isolated)
+		set_pageblock_skip(page);
 
 	/* Update where async and sync compaction should restart */
 	if (migrate_scanner) {
@@ -822,6 +888,8 @@ isolate_success:
 	if (locked)
 		spin_unlock_irqrestore(&zone->lru_lock, flags);
 
+	cc->migration_scan_limit -= nr_scanned;
+
 	trace_mm_compaction_isolate_migratepages(start_pfn, low_pfn,
 						nr_scanned, nr_isolated);
 
@@ -1186,15 +1254,6 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
 	return cc->nr_migratepages ? ISOLATE_SUCCESS : ISOLATE_NONE;
 }
 
-/*
- * order == -1 is expected when compacting via
- * /proc/sys/vm/compact_memory
- */
-static inline bool is_via_compact_memory(int order)
-{
-	return order == -1;
-}
-
 static int __compact_finished(struct zone *zone, struct compact_control *cc,
 			    const int migratetype)
 {
@@ -1224,6 +1283,9 @@ static int __compact_finished(struct zone *zone, struct compact_control *cc,
 	if (is_via_compact_memory(cc->order))
 		return COMPACT_CONTINUE;
 
+	if (excess_migration_scan_limit(cc))
+		return COMPACT_PARTIAL;
+
 	/* Compaction run is not finished if the watermark is not met */
 	watermark = low_wmark_pages(zone);
 
@@ -1382,6 +1444,10 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
 	}
 	cc->last_migrated_pfn = 0;
 
+	set_migration_scan_limit(cc);
+	if (excess_migration_scan_limit(cc))
+		return COMPACT_SKIPPED;
+
 	trace_mm_compaction_begin(start_pfn, cc->migrate_pfn,
 				cc->free_pfn, end_pfn, sync);
 
diff --git a/mm/internal.h b/mm/internal.h
index dbe0436..bb8225c 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -164,6 +164,7 @@ struct compact_control {
 	unsigned long free_pfn;		/* isolate_freepages search base */
 	unsigned long migrate_pfn;	/* isolate_migratepages search base */
 	unsigned long last_migrated_pfn;/* Not yet flushed page being freed */
+	long migration_scan_limit;      /* Limit migration scanner activity */
 	enum migrate_mode mode;		/* Async or sync migration mode */
 	bool ignore_skip_hint;		/* Scan blocks even if marked skip */
 	int order;			/* order a direct compactor needs */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1282756 — [PATCH v3 7/7] mm/compaction: replace compaction deferring with compaction limit

FromJoonsoo Kim <js1304@gmail.com>
Date2015-12-03 08:20 +0100
Subject[PATCH v3 7/7] mm/compaction: replace compaction deferring with compaction limit
Message-ID<qBwlj-1No-19@gated-at.bofh.it>
In reply to#1282753
Compaction deferring effectively reduces compaction overhead if
compaction success isn't expected. But, it is implemented that
skipping a number of compaction requests until compaction is re-enabled.
Due to this implementation, unfortunate compaction requestor will get
whole compaction overhead unlike others have zero overhead. And, after
deferring start to work, even if compaction success possibility is
restored, we should skip to compaction in some number of times.

This patch try to solve above problem by using compaction limit.
Instead of imposing compaction overhead to one unfortunate requestor,
compaction limit distributes overhead to all compaction requestors.
All requestors have a chance to migrate some amount of pages and
after limit is exhausted compaction will be stopped. This will fairly
distributes overhead to all compaction requestors. And, because we don't
defer compaction request, someone will succeed to compact as soon as
possible if compaction success possiblility is restored.

Following is whole workflow enabled by this change.

- if sync compaction fails, compact_order_failed is set to current order
- if it fails again, compact_defer_shift is adjusted
- with positive compact_defer_shift, migration_scan_limit is assigned and
compaction limit is activated
- if compaction limit is activated, compaction would be stopped when
migration_scan_limit is exhausted
- when success, compact_defer_shift and compact_order_failed is reset and
compaction limit is deactivated
- compact_defer_shift can be grown up to COMPACT_MAX_DEFER_SHIFT

Most of changes are mechanical ones to remove compact_considered which
is not needed now. Note that, after restart, compact_defer_shift is
subtracted by 1 to avoid invoking __reset_isolation_suitable()
repeatedly.

I tested this patch on my compaction benchmark and found that high-order
allocation latency is evenly distributed and there is no latency spike
in the situation where compaction success isn't possible.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
 include/linux/mmzone.h            |  6 ++---
 include/trace/events/compaction.h |  7 ++----
 mm/compaction.c                   | 47 +++++++++++++--------------------------
 3 files changed, 20 insertions(+), 40 deletions(-)

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index e23a9e7..ebb6400 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -511,11 +511,9 @@ struct zone {
 
 #ifdef CONFIG_COMPACTION
 	/*
-	 * On compaction failure, 1<<compact_defer_shift compactions
-	 * are skipped before trying again. The number attempted since
-	 * last failure is tracked with compact_considered.
+	 * On compaction failure, compaction will be limited by
+	 * compact_defer_shift.
 	 */
-	unsigned int		compact_considered;
 	unsigned int		compact_defer_shift;
 	int			compact_order_failed;
 #endif
diff --git a/include/trace/events/compaction.h b/include/trace/events/compaction.h
index c92d1e1..ab7bed1 100644
--- a/include/trace/events/compaction.h
+++ b/include/trace/events/compaction.h
@@ -305,7 +305,6 @@ DECLARE_EVENT_CLASS(mm_compaction_defer_template,
 		__field(int, nid)
 		__field(enum zone_type, idx)
 		__field(int, order)
-		__field(unsigned int, considered)
 		__field(unsigned int, defer_shift)
 		__field(int, order_failed)
 	),
@@ -314,18 +313,16 @@ DECLARE_EVENT_CLASS(mm_compaction_defer_template,
 		__entry->nid = zone_to_nid(zone);
 		__entry->idx = zone_idx(zone);
 		__entry->order = order;
-		__entry->considered = zone->compact_considered;
 		__entry->defer_shift = zone->compact_defer_shift;
 		__entry->order_failed = zone->compact_order_failed;
 	),
 
-	TP_printk("node=%d zone=%-8s order=%d order_failed=%d consider=%u limit=%lu",
+	TP_printk("node=%d zone=%-8s order=%d order_failed=%d defer=%u",
 		__entry->nid,
 		__print_symbolic(__entry->idx, ZONE_TYPE),
 		__entry->order,
 		__entry->order_failed,
-		__entry->considered,
-		1UL << __entry->defer_shift)
+		__entry->defer_shift)
 );
 
 DEFINE_EVENT(mm_compaction_defer_template, mm_compaction_deferred,
diff --git a/mm/compaction.c b/mm/compaction.c
index b23f6d9..f3f9dc0 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -129,8 +129,7 @@ static inline bool is_via_compact_memory(int order)
 
 static bool excess_migration_scan_limit(struct compact_control *cc)
 {
-	/* Disable scan limit for now */
-	return false;
+	return cc->migration_scan_limit < 0 ? true : false;
 }
 
 static void set_migration_scan_limit(struct compact_control *cc)
@@ -143,10 +142,7 @@ static void set_migration_scan_limit(struct compact_control *cc)
 	if (is_via_compact_memory(order))
 		return;
 
-	if (order < zone->compact_order_failed)
-		return;
-
-	if (!zone->compact_defer_shift)
+	if (!compaction_deferred(zone, order))
 		return;
 
 	/*
@@ -188,13 +184,10 @@ static void set_migration_scan_limit(struct compact_control *cc)
 static void defer_compaction(struct zone *zone, int order)
 {
 	if (order < zone->compact_order_failed) {
-		zone->compact_considered = 0;
 		zone->compact_defer_shift = 0;
 		zone->compact_order_failed = order;
-	} else {
-		zone->compact_considered = 0;
+	} else
 		zone->compact_defer_shift++;
-	}
 
 	if (zone->compact_defer_shift > COMPACT_MAX_DEFER_SHIFT)
 		zone->compact_defer_shift = COMPACT_MAX_DEFER_SHIFT;
@@ -202,19 +195,13 @@ static void defer_compaction(struct zone *zone, int order)
 	trace_mm_compaction_defer_compaction(zone, order);
 }
 
-/* Returns true if compaction should be skipped this time */
+/* Returns true if compaction is limited */
 bool compaction_deferred(struct zone *zone, int order)
 {
-	unsigned long defer_limit = 1UL << zone->compact_defer_shift;
-
 	if (order < zone->compact_order_failed)
 		return false;
 
-	/* Avoid possible overflow */
-	if (++zone->compact_considered > defer_limit)
-		zone->compact_considered = defer_limit;
-
-	if (zone->compact_considered >= defer_limit)
+	if (!zone->compact_defer_shift)
 		return false;
 
 	trace_mm_compaction_deferred(zone, order);
@@ -226,7 +213,6 @@ bool compaction_deferred(struct zone *zone, int order)
 static void compaction_defer_reset(struct zone *zone, int order)
 {
 	if (order >= zone->compact_order_failed) {
-		zone->compact_considered = 0;
 		zone->compact_defer_shift = 0;
 		zone->compact_order_failed = order + 1;
 	}
@@ -240,8 +226,7 @@ bool compaction_restarting(struct zone *zone, int order)
 	if (order < zone->compact_order_failed)
 		return false;
 
-	return zone->compact_defer_shift == COMPACT_MAX_DEFER_SHIFT &&
-		zone->compact_considered >= 1UL << zone->compact_defer_shift;
+	return zone->compact_defer_shift == COMPACT_MAX_DEFER_SHIFT;
 }
 
 /* Returns true if the pageblock should be scanned for pages to isolate. */
@@ -266,7 +251,7 @@ static void reset_cached_positions(struct zone *zone)
  * should be skipped for page isolation when the migrate and free page scanner
  * meet.
  */
-static void __reset_isolation_suitable(struct zone *zone)
+static void __reset_isolation_suitable(struct zone *zone, bool restart)
 {
 	unsigned long start_pfn = zone->zone_start_pfn;
 	unsigned long end_pfn = zone_end_pfn(zone);
@@ -274,6 +259,11 @@ static void __reset_isolation_suitable(struct zone *zone)
 
 	zone->compact_blockskip_flush = false;
 
+	if (restart) {
+		/* To prevent restart at next compaction attempt */
+		zone->compact_defer_shift = COMPACT_MAX_DEFER_SHIFT - 1;
+	}
+
 	/* Walk the zone and mark every pageblock as suitable for isolation */
 	for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
 		struct page *page;
@@ -304,7 +294,7 @@ void reset_isolation_suitable(pg_data_t *pgdat)
 
 		/* Only flush if a full compaction finished recently */
 		if (zone->compact_blockskip_flush)
-			__reset_isolation_suitable(zone);
+			__reset_isolation_suitable(zone, false);
 	}
 }
 
@@ -1424,7 +1414,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
 	 * this reset as it'll reset the cached information when going to sleep.
 	 */
 	if (compaction_restarting(zone, cc->order) && !current_is_kswapd())
-		__reset_isolation_suitable(zone);
+		__reset_isolation_suitable(zone, true);
 
 	/*
 	 * Setup to move all movable pages to the end of the zone. Used cached
@@ -1615,9 +1605,6 @@ unsigned long try_to_compact_pages(gfp_t gfp_mask, unsigned int order,
 		int status;
 		int zone_contended;
 
-		if (compaction_deferred(zone, order))
-			continue;
-
 		status = compact_zone_order(zone, order, gfp_mask, mode,
 				&zone_contended, alloc_flags,
 				ac->classzone_idx);
@@ -1713,11 +1700,9 @@ static void __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc)
 		 * cached scanner positions.
 		 */
 		if (is_via_compact_memory(cc->order))
-			__reset_isolation_suitable(zone);
+			__reset_isolation_suitable(zone, false);
 
-		if (is_via_compact_memory(cc->order) ||
-				!compaction_deferred(zone, cc->order))
-			compact_zone(zone, cc);
+		compact_zone(zone, cc);
 
 		VM_BUG_ON(!list_empty(&cc->freepages));
 		VM_BUG_ON(!list_empty(&cc->migratepages));
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web