Skip to content

Commit accf624

Browse files
tehcastertorvalds
authored andcommitted
mm, kswapd: replace kswapd compaction with waking up kcompactd
Similarly to direct reclaim/compaction, kswapd attempts to combine reclaim and compaction to attempt making memory allocation of given order available. The details differ from direct reclaim e.g. in having high watermark as a goal. The code involved in kswapd's reclaim/compaction decisions has evolved to be quite complex. Testing reveals that it doesn't actually work in at least one scenario, and closer inspection suggests that it could be greatly simplified without compromising on the goal (make high-order page available) or efficiency (don't reclaim too much). The simplification relieas of doing all compaction in kcompactd, which is simply woken up when high watermarks are reached by kswapd's reclaim. The scenario where kswapd compaction doesn't work was found with mmtests test stress-highalloc configured to attempt order-9 allocations without direct reclaim, just waking up kswapd. There was no compaction attempt from kswapd during the whole test. Some added instrumentation shows what happens: - balance_pgdat() sets end_zone to Normal, as it's not balanced - reclaim is attempted on DMA zone, which sets nr_attempted to 99, but it cannot reclaim anything, so sc.nr_reclaimed is 0 - for zones DMA32 and Normal, kswapd_shrink_zone uses testorder=0, so it merely checks if high watermarks were reached for base pages. This is true, so no reclaim is attempted. For DMA, testorder=0 wasn't used, as compaction_suitable() returned COMPACT_SKIPPED - even though the pgdat_needs_compaction flag wasn't set to false, no compaction happens due to the condition sc.nr_reclaimed > nr_attempted being false (as 0 < 99) - priority-- due to nr_reclaimed being 0, repeat until priority reaches 0 pgdat_balanced() is false as only the small zone DMA appears balanced (curiously in that check, watermark appears OK and compaction_suitable() returns COMPACT_PARTIAL, because a lower classzone_idx is used there) Now, even if it was decided that reclaim shouldn't be attempted on the DMA zone, the scenario would be the same, as (sc.nr_reclaimed=0 > nr_attempted=0) is also false. The condition really should use >= as the comment suggests. Then there is a mismatch in the check for setting pgdat_needs_compaction to false using low watermark, while the rest uses high watermark, and who knows what other subtlety. Hopefully this demonstrates that this is unsustainable. Luckily we can simplify this a lot. The reclaim/compaction decisions make sense for direct reclaim scenario, but in kswapd, our primary goal is to reach high watermark in order-0 pages. Afterwards we can attempt compaction just once. Unlike direct reclaim, we don't reclaim extra pages (over the high watermark), the current code already disallows it for good reasons. After this patch, we simply wake up kcompactd to process the pgdat, after we have either succeeded or failed to reach the high watermarks in kswapd, which goes to sleep. We pass kswapd's order and classzone_idx, so kcompactd can apply the same criteria to determine which zones are worth compacting. Note that we use the classzone_idx from wakeup_kswapd(), not balanced_classzone_idx which can include higher zones that kswapd tried to balance too, but didn't consider them in pgdat_balanced(). Since kswapd now cannot create high-order pages itself, we need to adjust how it determines the zones to be balanced. The key element here is adding a "highorder" parameter to zone_balanced, which, when set to false, makes it consider only order-0 watermark instead of the desired higher order (this was done previously by kswapd_shrink_zone(), but not elsewhere). This false is passed for example in pgdat_balanced(). Importantly, wakeup_kswapd() uses true to make sure kswapd and thus kcompactd are woken up for a high-order allocation failure. The last thing is to decide what to do with pageblock_skip bitmap handling. Compaction maintains a pageblock_skip bitmap to record pageblocks where isolation recently failed. This bitmap can be reset by three ways: 1) direct compaction is restarting after going through the full deferred cycle 2) kswapd goes to sleep, and some other direct compaction has previously finished scanning the whole zone and set zone->compact_blockskip_flush. Note that a successful direct compaction clears this flag. 3) compaction was invoked manually via trigger in /proc The case 2) is somewhat fuzzy to begin with, but after introducing kcompactd we should update it. The check for direct compaction in 1), and to set the flush flag in 2) use current_is_kswapd(), which doesn't work for kcompactd. Thus, this patch adds bool direct_compaction to compact_control to use in 2). For the case 1) we remove the check completely - unlike the former kswapd compaction, kcompactd does use the deferred compaction functionality, so flushing tied to restarting from deferred compaction makes sense here. Note that when kswapd goes to sleep, kcompactd is woken up, so it will see the flushed pageblock_skip bits. This is different from when the former kswapd compaction observed the bits and I believe it makes more sense. Kcompactd can afford to be more thorough than a direct compaction trying to limit allocation latency, or kswapd whose primary goal is to reclaim. For testing, I used stress-highalloc configured to do order-9 allocations with GFP_NOWAIT|__GFP_HIGH|__GFP_COMP, so they relied just on kswapd/kcompactd reclaim/compaction (the interfering kernel builds in phases 1 and 2 work as usual): stress-highalloc 4.5-rc1+before 4.5-rc1+after -nodirect -nodirect Success 1 Min 1.00 ( 0.00%) 5.00 (-66.67%) Success 1 Mean 1.40 ( 0.00%) 6.20 (-55.00%) Success 1 Max 2.00 ( 0.00%) 7.00 (-16.67%) Success 2 Min 1.00 ( 0.00%) 5.00 (-66.67%) Success 2 Mean 1.80 ( 0.00%) 6.40 (-52.38%) Success 2 Max 3.00 ( 0.00%) 7.00 (-16.67%) Success 3 Min 34.00 ( 0.00%) 62.00 ( 1.59%) Success 3 Mean 41.80 ( 0.00%) 63.80 ( 1.24%) Success 3 Max 53.00 ( 0.00%) 65.00 ( 2.99%) User 3166.67 3181.09 System 1153.37 1158.25 Elapsed 1768.53 1799.37 4.5-rc1+before 4.5-rc1+after -nodirect -nodirect Direct pages scanned 32938 32797 Kswapd pages scanned 2183166 2202613 Kswapd pages reclaimed 2152359 2143524 Direct pages reclaimed 32735 32545 Percentage direct scans 1% 1% THP fault alloc 579 612 THP collapse alloc 304 316 THP splits 0 0 THP fault fallback 793 778 THP collapse fail 11 16 Compaction stalls 1013 1007 Compaction success 92 67 Compaction failures 920 939 Page migrate success 238457 721374 Page migrate failure 23021 23469 Compaction pages isolated 504695 1479924 Compaction migrate scanned 661390 8812554 Compaction free scanned 13476658 84327916 Compaction cost 262 838 After this patch we see improvements in allocation success rate (especially for phase 3) along with increased compaction activity. The compaction stalls (direct compaction) in the interfering kernel builds (probably THP's) also decreased somewhat thanks to kcompactd activity, yet THP alloc successes improved a bit. Note that elapsed and user time isn't so useful for this benchmark, because of the background interference being unpredictable. It's just to quickly spot some major unexpected differences. System time is somewhat more useful and that didn't increase. Also (after adjusting mmtests' ftrace monitor): Time kswapd awake 2547781 2269241 Time kcompactd awake 0 119253 Time direct compacting 939937 557649 Time kswapd compacting 0 0 Time kcompactd compacting 0 119099 The decrease of overal time spent compacting appears to not match the increased compaction stats. I suspect the tasks get rescheduled and since the ftrace monitor doesn't see that, the reported time is wall time, not CPU time. But arguably direct compactors care about overall latency anyway, whether busy compacting or waiting for CPU doesn't matter. And that latency seems to almost halved. It's also interesting how much time kswapd spent awake just going through all the priorities and failing to even try compacting, over and over. We can also configure stress-highalloc to perform both direct reclaim/compaction and wakeup kswapd/kcompactd, by using GFP_KERNEL|__GFP_HIGH|__GFP_COMP: stress-highalloc 4.5-rc1+before 4.5-rc1+after -direct -direct Success 1 Min 4.00 ( 0.00%) 9.00 (-50.00%) Success 1 Mean 8.00 ( 0.00%) 10.00 (-19.05%) Success 1 Max 12.00 ( 0.00%) 11.00 ( 15.38%) Success 2 Min 4.00 ( 0.00%) 9.00 (-50.00%) Success 2 Mean 8.20 ( 0.00%) 10.00 (-16.28%) Success 2 Max 13.00 ( 0.00%) 11.00 ( 8.33%) Success 3 Min 75.00 ( 0.00%) 74.00 ( 1.33%) Success 3 Mean 75.60 ( 0.00%) 75.20 ( 0.53%) Success 3 Max 77.00 ( 0.00%) 76.00 ( 0.00%) User 3344.73 3246.04 System 1194.24 1172.29 Elapsed 1838.04 1836.76 4.5-rc1+before 4.5-rc1+after -direct -direct Direct pages scanned 125146 120966 Kswapd pages scanned 2119757 2135012 Kswapd pages reclaimed 2073183 2108388 Direct pages reclaimed 124909 120577 Percentage direct scans 5% 5% THP fault alloc 599 652 THP collapse alloc 323 354 THP splits 0 0 THP fault fallback 806 793 THP collapse fail 17 16 Compaction stalls 2457 2025 Compaction success 906 518 Compaction failures 1551 1507 Page migrate success 2031423 2360608 Page migrate failure 32845 40852 Compaction pages isolated 4129761 4802025 Compaction migrate scanned 11996712 21750613 Compaction free scanned 214970969 344372001 Compaction cost 2271 2694 In this scenario, this patch doesn't change the overall success rate as direct compaction already tries all it can. There's however significant reduction in direct compaction stalls (that is, the number of allocations that went into direct compaction). The number of successes (i.e. direct compaction stalls that ended up with successful allocation) is reduced by the same number. This means the offload to kcompactd is working as expected, and direct compaction is reduced either due to detecting contention, or compaction deferred by kcompactd. In the previous version of this patchset there was some apparent reduction of success rate, but the changes in this version (such as using sync compaction only), new baseline kernel, and/or averaging results from 5 executions (my bet), made this go away. Ftrace-based stats seem to roughly agree: Time kswapd awake 2532984 2326824 Time kcompactd awake 0 257916 Time direct compacting 864839 735130 Time kswapd compacting 0 0 Time kcompactd compacting 0 257585 Signed-off-by: Vlastimil Babka <vbabka@suse.cz> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Rik van Riel <riel@redhat.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: David Rientjes <rientjes@google.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent e888ca3 commit accf624

File tree

3 files changed

+54
-104
lines changed

3 files changed

+54
-104
lines changed

mm/compaction.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,11 +1191,11 @@ static int __compact_finished(struct zone *zone, struct compact_control *cc,
11911191

11921192
/*
11931193
* Mark that the PG_migrate_skip information should be cleared
1194-
* by kswapd when it goes to sleep. kswapd does not set the
1194+
* by kswapd when it goes to sleep. kcompactd does not set the
11951195
* flag itself as the decision to be clear should be directly
11961196
* based on an allocation request.
11971197
*/
1198-
if (!current_is_kswapd())
1198+
if (cc->direct_compaction)
11991199
zone->compact_blockskip_flush = true;
12001200

12011201
return COMPACT_COMPLETE;
@@ -1338,10 +1338,9 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
13381338

13391339
/*
13401340
* Clear pageblock skip if there were failures recently and compaction
1341-
* is about to be retried after being deferred. kswapd does not do
1342-
* this reset as it'll reset the cached information when going to sleep.
1341+
* is about to be retried after being deferred.
13431342
*/
1344-
if (compaction_restarting(zone, cc->order) && !current_is_kswapd())
1343+
if (compaction_restarting(zone, cc->order))
13451344
__reset_isolation_suitable(zone);
13461345

13471346
/*
@@ -1477,6 +1476,7 @@ static unsigned long compact_zone_order(struct zone *zone, int order,
14771476
.mode = mode,
14781477
.alloc_flags = alloc_flags,
14791478
.classzone_idx = classzone_idx,
1479+
.direct_compaction = true,
14801480
};
14811481
INIT_LIST_HEAD(&cc.freepages);
14821482
INIT_LIST_HEAD(&cc.migratepages);

mm/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ struct compact_control {
172172
unsigned long last_migrated_pfn;/* Not yet flushed page being freed */
173173
enum migrate_mode mode; /* Async or sync migration mode */
174174
bool ignore_skip_hint; /* Scan blocks even if marked skip */
175+
bool direct_compaction; /* False from kcompactd or /proc/... */
175176
int order; /* order a direct compactor needs */
176177
const gfp_t gfp_mask; /* gfp mask of a direct compactor */
177178
const int alloc_flags; /* alloc flags of a direct compactor */

mm/vmscan.c

Lines changed: 48 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -2968,18 +2968,23 @@ static void age_active_anon(struct zone *zone, struct scan_control *sc)
29682968
} while (memcg);
29692969
}
29702970

2971-
static bool zone_balanced(struct zone *zone, int order,
2972-
unsigned long balance_gap, int classzone_idx)
2971+
static bool zone_balanced(struct zone *zone, int order, bool highorder,
2972+
unsigned long balance_gap, int classzone_idx)
29732973
{
2974-
if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone) +
2975-
balance_gap, classzone_idx))
2976-
return false;
2974+
unsigned long mark = high_wmark_pages(zone) + balance_gap;
29772975

2978-
if (IS_ENABLED(CONFIG_COMPACTION) && order && compaction_suitable(zone,
2979-
order, 0, classzone_idx) == COMPACT_SKIPPED)
2980-
return false;
2976+
/*
2977+
* When checking from pgdat_balanced(), kswapd should stop and sleep
2978+
* when it reaches the high order-0 watermark and let kcompactd take
2979+
* over. Other callers such as wakeup_kswapd() want to determine the
2980+
* true high-order watermark.
2981+
*/
2982+
if (IS_ENABLED(CONFIG_COMPACTION) && !highorder) {
2983+
mark += (1UL << order);
2984+
order = 0;
2985+
}
29812986

2982-
return true;
2987+
return zone_watermark_ok_safe(zone, order, mark, classzone_idx);
29832988
}
29842989

29852990
/*
@@ -3029,7 +3034,7 @@ static bool pgdat_balanced(pg_data_t *pgdat, int order, int classzone_idx)
30293034
continue;
30303035
}
30313036

3032-
if (zone_balanced(zone, order, 0, i))
3037+
if (zone_balanced(zone, order, false, 0, i))
30333038
balanced_pages += zone->managed_pages;
30343039
else if (!order)
30353040
return false;
@@ -3083,27 +3088,14 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining,
30833088
*/
30843089
static bool kswapd_shrink_zone(struct zone *zone,
30853090
int classzone_idx,
3086-
struct scan_control *sc,
3087-
unsigned long *nr_attempted)
3091+
struct scan_control *sc)
30883092
{
3089-
int testorder = sc->order;
30903093
unsigned long balance_gap;
30913094
bool lowmem_pressure;
30923095

30933096
/* Reclaim above the high watermark. */
30943097
sc->nr_to_reclaim = max(SWAP_CLUSTER_MAX, high_wmark_pages(zone));
30953098

3096-
/*
3097-
* Kswapd reclaims only single pages with compaction enabled. Trying
3098-
* too hard to reclaim until contiguous free pages have become
3099-
* available can hurt performance by evicting too much useful data
3100-
* from memory. Do not reclaim more than needed for compaction.
3101-
*/
3102-
if (IS_ENABLED(CONFIG_COMPACTION) && sc->order &&
3103-
compaction_suitable(zone, sc->order, 0, classzone_idx)
3104-
!= COMPACT_SKIPPED)
3105-
testorder = 0;
3106-
31073099
/*
31083100
* We put equal pressure on every zone, unless one zone has way too
31093101
* many pages free already. The "too many pages" is defined as the
@@ -3118,15 +3110,12 @@ static bool kswapd_shrink_zone(struct zone *zone,
31183110
* reclaim is necessary
31193111
*/
31203112
lowmem_pressure = (buffer_heads_over_limit && is_highmem(zone));
3121-
if (!lowmem_pressure && zone_balanced(zone, testorder,
3113+
if (!lowmem_pressure && zone_balanced(zone, sc->order, false,
31223114
balance_gap, classzone_idx))
31233115
return true;
31243116

31253117
shrink_zone(zone, sc, zone_idx(zone) == classzone_idx);
31263118

3127-
/* Account for the number of pages attempted to reclaim */
3128-
*nr_attempted += sc->nr_to_reclaim;
3129-
31303119
clear_bit(ZONE_WRITEBACK, &zone->flags);
31313120

31323121
/*
@@ -3136,7 +3125,7 @@ static bool kswapd_shrink_zone(struct zone *zone,
31363125
* waits.
31373126
*/
31383127
if (zone_reclaimable(zone) &&
3139-
zone_balanced(zone, testorder, 0, classzone_idx)) {
3128+
zone_balanced(zone, sc->order, false, 0, classzone_idx)) {
31403129
clear_bit(ZONE_CONGESTED, &zone->flags);
31413130
clear_bit(ZONE_DIRTY, &zone->flags);
31423131
}
@@ -3148,7 +3137,7 @@ static bool kswapd_shrink_zone(struct zone *zone,
31483137
* For kswapd, balance_pgdat() will work across all this node's zones until
31493138
* they are all at high_wmark_pages(zone).
31503139
*
3151-
* Returns the final order kswapd was reclaiming at
3140+
* Returns the highest zone idx kswapd was reclaiming at
31523141
*
31533142
* There is special handling here for zones which are full of pinned pages.
31543143
* This can happen if the pages are all mlocked, or if they are all used by
@@ -3165,8 +3154,7 @@ static bool kswapd_shrink_zone(struct zone *zone,
31653154
* interoperates with the page allocator fallback scheme to ensure that aging
31663155
* of pages is balanced across the zones.
31673156
*/
3168-
static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
3169-
int *classzone_idx)
3157+
static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
31703158
{
31713159
int i;
31723160
int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */
@@ -3183,9 +3171,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
31833171
count_vm_event(PAGEOUTRUN);
31843172

31853173
do {
3186-
unsigned long nr_attempted = 0;
31873174
bool raise_priority = true;
3188-
bool pgdat_needs_compaction = (order > 0);
31893175

31903176
sc.nr_reclaimed = 0;
31913177

@@ -3220,7 +3206,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
32203206
break;
32213207
}
32223208

3223-
if (!zone_balanced(zone, order, 0, 0)) {
3209+
if (!zone_balanced(zone, order, false, 0, 0)) {
32243210
end_zone = i;
32253211
break;
32263212
} else {
@@ -3236,24 +3222,6 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
32363222
if (i < 0)
32373223
goto out;
32383224

3239-
for (i = 0; i <= end_zone; i++) {
3240-
struct zone *zone = pgdat->node_zones + i;
3241-
3242-
if (!populated_zone(zone))
3243-
continue;
3244-
3245-
/*
3246-
* If any zone is currently balanced then kswapd will
3247-
* not call compaction as it is expected that the
3248-
* necessary pages are already available.
3249-
*/
3250-
if (pgdat_needs_compaction &&
3251-
zone_watermark_ok(zone, order,
3252-
low_wmark_pages(zone),
3253-
*classzone_idx, 0))
3254-
pgdat_needs_compaction = false;
3255-
}
3256-
32573225
/*
32583226
* If we're getting trouble reclaiming, start doing writepage
32593227
* even in laptop mode.
@@ -3297,8 +3265,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
32973265
* that that high watermark would be met at 100%
32983266
* efficiency.
32993267
*/
3300-
if (kswapd_shrink_zone(zone, end_zone,
3301-
&sc, &nr_attempted))
3268+
if (kswapd_shrink_zone(zone, end_zone, &sc))
33023269
raise_priority = false;
33033270
}
33043271

@@ -3311,49 +3278,29 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
33113278
pfmemalloc_watermark_ok(pgdat))
33123279
wake_up_all(&pgdat->pfmemalloc_wait);
33133280

3314-
/*
3315-
* Fragmentation may mean that the system cannot be rebalanced
3316-
* for high-order allocations in all zones. If twice the
3317-
* allocation size has been reclaimed and the zones are still
3318-
* not balanced then recheck the watermarks at order-0 to
3319-
* prevent kswapd reclaiming excessively. Assume that a
3320-
* process requested a high-order can direct reclaim/compact.
3321-
*/
3322-
if (order && sc.nr_reclaimed >= 2UL << order)
3323-
order = sc.order = 0;
3324-
33253281
/* Check if kswapd should be suspending */
33263282
if (try_to_freeze() || kthread_should_stop())
33273283
break;
33283284

3329-
/*
3330-
* Compact if necessary and kswapd is reclaiming at least the
3331-
* high watermark number of pages as requsted
3332-
*/
3333-
if (pgdat_needs_compaction && sc.nr_reclaimed > nr_attempted)
3334-
compact_pgdat(pgdat, order);
3335-
33363285
/*
33373286
* Raise priority if scanning rate is too low or there was no
33383287
* progress in reclaiming pages
33393288
*/
33403289
if (raise_priority || !sc.nr_reclaimed)
33413290
sc.priority--;
33423291
} while (sc.priority >= 1 &&
3343-
!pgdat_balanced(pgdat, order, *classzone_idx));
3292+
!pgdat_balanced(pgdat, order, classzone_idx));
33443293

33453294
out:
33463295
/*
3347-
* Return the order we were reclaiming at so prepare_kswapd_sleep()
3348-
* makes a decision on the order we were last reclaiming at. However,
3349-
* if another caller entered the allocator slow path while kswapd
3350-
* was awake, order will remain at the higher level
3296+
* Return the highest zone idx we were reclaiming at so
3297+
* prepare_kswapd_sleep() makes the same decisions as here.
33513298
*/
3352-
*classzone_idx = end_zone;
3353-
return order;
3299+
return end_zone;
33543300
}
33553301

3356-
static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
3302+
static void kswapd_try_to_sleep(pg_data_t *pgdat, int order,
3303+
int classzone_idx, int balanced_classzone_idx)
33573304
{
33583305
long remaining = 0;
33593306
DEFINE_WAIT(wait);
@@ -3364,7 +3311,8 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
33643311
prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
33653312

33663313
/* Try to sleep for a short interval */
3367-
if (prepare_kswapd_sleep(pgdat, order, remaining, classzone_idx)) {
3314+
if (prepare_kswapd_sleep(pgdat, order, remaining,
3315+
balanced_classzone_idx)) {
33683316
remaining = schedule_timeout(HZ/10);
33693317
finish_wait(&pgdat->kswapd_wait, &wait);
33703318
prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
@@ -3374,7 +3322,8 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
33743322
* After a short sleep, check if it was a premature sleep. If not, then
33753323
* go fully to sleep until explicitly woken up.
33763324
*/
3377-
if (prepare_kswapd_sleep(pgdat, order, remaining, classzone_idx)) {
3325+
if (prepare_kswapd_sleep(pgdat, order, remaining,
3326+
balanced_classzone_idx)) {
33783327
trace_mm_vmscan_kswapd_sleep(pgdat->node_id);
33793328

33803329
/*
@@ -3395,6 +3344,12 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
33953344
*/
33963345
reset_isolation_suitable(pgdat);
33973346

3347+
/*
3348+
* We have freed the memory, now we should compact it to make
3349+
* allocation of the requested order possible.
3350+
*/
3351+
wakeup_kcompactd(pgdat, order, classzone_idx);
3352+
33983353
if (!kthread_should_stop())
33993354
schedule();
34003355

@@ -3424,7 +3379,6 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
34243379
static int kswapd(void *p)
34253380
{
34263381
unsigned long order, new_order;
3427-
unsigned balanced_order;
34283382
int classzone_idx, new_classzone_idx;
34293383
int balanced_classzone_idx;
34303384
pg_data_t *pgdat = (pg_data_t*)p;
@@ -3457,23 +3411,19 @@ static int kswapd(void *p)
34573411
set_freezable();
34583412

34593413
order = new_order = 0;
3460-
balanced_order = 0;
34613414
classzone_idx = new_classzone_idx = pgdat->nr_zones - 1;
34623415
balanced_classzone_idx = classzone_idx;
34633416
for ( ; ; ) {
34643417
bool ret;
34653418

34663419
/*
3467-
* If the last balance_pgdat was unsuccessful it's unlikely a
3468-
* new request of a similar or harder type will succeed soon
3469-
* so consider going to sleep on the basis we reclaimed at
3420+
* While we were reclaiming, there might have been another
3421+
* wakeup, so check the values.
34703422
*/
3471-
if (balanced_order == new_order) {
3472-
new_order = pgdat->kswapd_max_order;
3473-
new_classzone_idx = pgdat->classzone_idx;
3474-
pgdat->kswapd_max_order = 0;
3475-
pgdat->classzone_idx = pgdat->nr_zones - 1;
3476-
}
3423+
new_order = pgdat->kswapd_max_order;
3424+
new_classzone_idx = pgdat->classzone_idx;
3425+
pgdat->kswapd_max_order = 0;
3426+
pgdat->classzone_idx = pgdat->nr_zones - 1;
34773427

34783428
if (order < new_order || classzone_idx > new_classzone_idx) {
34793429
/*
@@ -3483,7 +3433,7 @@ static int kswapd(void *p)
34833433
order = new_order;
34843434
classzone_idx = new_classzone_idx;
34853435
} else {
3486-
kswapd_try_to_sleep(pgdat, balanced_order,
3436+
kswapd_try_to_sleep(pgdat, order, classzone_idx,
34873437
balanced_classzone_idx);
34883438
order = pgdat->kswapd_max_order;
34893439
classzone_idx = pgdat->classzone_idx;
@@ -3503,9 +3453,8 @@ static int kswapd(void *p)
35033453
*/
35043454
if (!ret) {
35053455
trace_mm_vmscan_kswapd_wake(pgdat->node_id, order);
3506-
balanced_classzone_idx = classzone_idx;
3507-
balanced_order = balance_pgdat(pgdat, order,
3508-
&balanced_classzone_idx);
3456+
balanced_classzone_idx = balance_pgdat(pgdat, order,
3457+
classzone_idx);
35093458
}
35103459
}
35113460

@@ -3535,7 +3484,7 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx)
35353484
}
35363485
if (!waitqueue_active(&pgdat->kswapd_wait))
35373486
return;
3538-
if (zone_balanced(zone, order, 0, 0))
3487+
if (zone_balanced(zone, order, true, 0, 0))
35393488
return;
35403489

35413490
trace_mm_vmscan_wakeup_kswapd(pgdat->node_id, zone_idx(zone), order);

0 commit comments

Comments
 (0)