aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/compaction.h16
-rw-r--r--mm/compaction.c9
-rw-r--r--mm/page_alloc.c5
3 files changed, 21 insertions, 9 deletions
diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index 091d72e70d8a..7e1c76e3cd68 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -62,6 +62,22 @@ static inline bool compaction_deferred(struct zone *zone, int order)
62 return zone->compact_considered < defer_limit; 62 return zone->compact_considered < defer_limit;
63} 63}
64 64
65/*
66 * Update defer tracking counters after successful compaction of given order,
67 * which means an allocation either succeeded (alloc_success == true) or is
68 * expected to succeed.
69 */
70static inline void compaction_defer_reset(struct zone *zone, int order,
71 bool alloc_success)
72{
73 if (alloc_success) {
74 zone->compact_considered = 0;
75 zone->compact_defer_shift = 0;
76 }
77 if (order >= zone->compact_order_failed)
78 zone->compact_order_failed = order + 1;
79}
80
65/* Returns true if restarting compaction after many failures */ 81/* Returns true if restarting compaction after many failures */
66static inline bool compaction_restarting(struct zone *zone, int order) 82static inline bool compaction_restarting(struct zone *zone, int order)
67{ 83{
diff --git a/mm/compaction.c b/mm/compaction.c
index a03995eddedb..927de97cab8d 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1124,12 +1124,11 @@ static void __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc)
1124 compact_zone(zone, cc); 1124 compact_zone(zone, cc);
1125 1125
1126 if (cc->order > 0) { 1126 if (cc->order > 0) {
1127 int ok = zone_watermark_ok(zone, cc->order, 1127 if (zone_watermark_ok(zone, cc->order,
1128 low_wmark_pages(zone), 0, 0); 1128 low_wmark_pages(zone), 0, 0))
1129 if (ok && cc->order >= zone->compact_order_failed) 1129 compaction_defer_reset(zone, cc->order, false);
1130 zone->compact_order_failed = cc->order + 1;
1131 /* Currently async compaction is never deferred. */ 1130 /* Currently async compaction is never deferred. */
1132 else if (!ok && cc->sync) 1131 else if (cc->sync)
1133 defer_compaction(zone, cc->order); 1132 defer_compaction(zone, cc->order);
1134 } 1133 }
1135 1134
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index b230e838883d..84da0e3bc886 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2235,10 +2235,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
2235 preferred_zone, migratetype); 2235 preferred_zone, migratetype);
2236 if (page) { 2236 if (page) {
2237 preferred_zone->compact_blockskip_flush = false; 2237 preferred_zone->compact_blockskip_flush = false;
2238 preferred_zone->compact_considered = 0; 2238 compaction_defer_reset(preferred_zone, order, true);
2239 preferred_zone->compact_defer_shift = 0;
2240 if (order >= preferred_zone->compact_order_failed)
2241 preferred_zone->compact_order_failed = order + 1;
2242 count_vm_event(COMPACTSUCCESS); 2239 count_vm_event(COMPACTSUCCESS);
2243 return page; 2240 return page;
2244 } 2241 }