On 5/15/23 13:33, Mel Gorman wrote: > isolate_migratepages_block should mark a pageblock as skip if scanning > started on an aligned pageblock boundary but it only updates the skip > flag if the first migration candidate is also aligned. Tracing during > a compaction stress load (mmtests: workload-usemem-stress-numa-compact) > that many pageblocks are not marked skip causing excessive scanning of > blocks that had been recently checked. Update pageblock skip based on > "valid_page" which is set if scanning started on a pageblock boundary. > > Signed-off-by: Mel Gorman <mgorman@xxxxxxxxxxxxxxxxxxx> I wonder if this has an unintended side-effect that if we resume isolate_migratepages_block() of a partially compacted pageblock to finish it, test_and_set_skip() will now tell us to abort, because we already set the skip bit in the previous call. This would include the cc->finish_pageblock rescan cases. So unless I miss something that already prevents that, I agree we should not tie setting the skip bit to pageblock_aligned(pfn), but maybe if we are not pageblock aligned, we should ignore the already-set skip bit, as it was most likely being set by us in the previous iteration and should not prevent us from finishing the pageblock? > --- > mm/compaction.c | 15 +++++---------- > 1 file changed, 5 insertions(+), 10 deletions(-) > > diff --git a/mm/compaction.c b/mm/compaction.c > index accc6568091a..d7be990b1d60 100644 > --- a/mm/compaction.c > +++ b/mm/compaction.c > @@ -392,18 +392,14 @@ void reset_isolation_suitable(pg_data_t *pgdat) > * Sets the pageblock skip bit if it was clear. Note that this is a hint as > * locks are not required for read/writers. Returns true if it was already set. > */ > -static bool test_and_set_skip(struct compact_control *cc, struct page *page, > - unsigned long pfn) > +static bool test_and_set_skip(struct compact_control *cc, struct page *page) > { > bool skip; > > - /* Do no update if skip hint is being ignored */ > + /* Do not update if skip hint is being ignored */ > if (cc->ignore_skip_hint) > return false; > > - if (!pageblock_aligned(pfn)) > - return false; > - > skip = get_pageblock_skip(page); > if (!skip && !cc->no_set_skip_hint) > set_pageblock_skip(page); > @@ -470,8 +466,7 @@ static void update_cached_migrate(struct compact_control *cc, unsigned long pfn) > { > } > > -static bool test_and_set_skip(struct compact_control *cc, struct page *page, > - unsigned long pfn) > +static bool test_and_set_skip(struct compact_control *cc, struct page *page) > { > return false; > } > @@ -1075,9 +1070,9 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn, > lruvec_memcg_debug(lruvec, page_folio(page)); > > /* Try get exclusive access under lock */ > - if (!skip_updated) { > + if (!skip_updated && valid_page) { > skip_updated = true; > - if (test_and_set_skip(cc, page, low_pfn)) > + if (test_and_set_skip(cc, valid_page)) > goto isolate_abort; > } >