On Mon, 2020-02-24 at 16:29 +0100, Vlastimil Babka wrote: > On 2/21/20 10:53 PM, Rik van Riel wrote: > > @@ -981,7 +981,9 @@ isolate_migratepages_block(struct > > compact_control *cc, unsigned long low_pfn, > > if (__isolate_lru_page(page, isolate_mode) != 0) > > goto isolate_fail; > > > > - VM_BUG_ON_PAGE(PageCompound(page), page); > > + /* The whole page is taken off the LRU; skip the tail > > pages. */ > > + if (PageCompound(page)) > > + low_pfn += compound_nr(page) - 1; > > > > /* Successfully isolated */ > > del_page_from_lru_list(page, lruvec, page_lru(page)); > > This continues by: > inc_node_page_state(page, NR_ISOLATED_ANON + > page_is_file_cache(page)); > > > I think it now needs to use mod_node_page_state() with > hpage_nr_pages(page) otherwise the counter will underflow after the > migration? You are absolutely right. I have not observed the underflow, but the functions doing the decrementing use hpage_nr_pages, and I need to do that as well on the incrementing side. Change made. > > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > > index a36736812596..38c8ddfcecc8 100644 > > --- a/mm/page_alloc.c > > +++ b/mm/page_alloc.c > > @@ -8253,14 +8253,16 @@ struct page *has_unmovable_pages(struct > > zone *zone, struct page *page, > > > > /* > > * Hugepages are not in LRU lists, but they're movable. > > + * THPs are on the LRU, but need to be counted as > > #small pages. > > * We need not scan over tail pages because we don't > > * handle each tail page individually in migration. > > */ > > - if (PageHuge(page)) { > > + if (PageTransHuge(page)) { > > Hmm, PageTransHuge() has VM_BUG_ON() for tail pages, while this code > is > written so that it can encounter a tail page and skip the rest of the > compound page properly. So I would be worried about this. Good point, a CMA allocation could start partway into a compound page. > Also PageTransHuge() is basically just a PageHead() so for each > non-hugetlbfs compound page this will assume it's a THP, while > correctly > it should reach the __PageMovable() || PageLRU(page) tests below. > > So probably this should do something like. > > if (PageHuge(page) || PageTransCompound(page)) { > ... > if (PageHuge(page) && !hpage_migration_supported)) return page. So far so good. > if (!PageLRU(head) && !__PageMovable(head)) return page I don't get this one, though. What about a THP that has not made it onto the LRU list yet for some reason? I don't think anonymous pages are marked __PageMovable, are they? It looks like they only have the PAGE_MAPPING_ANON flag set, not the PAGE_MAPPING_MOVABLE one. What am I missing? > ... > > > struct page *head = compound_head(page); > > unsigned int skip_pages; > > > > - if > > (!hugepage_migration_supported(page_hstate(head))) > > + if (PageHuge(page) && > > + !hugepage_migration_supported(page_hstate(h > > ead))) > > return page; > > > > skip_pages = compound_nr(head) - (page - head); > > > > -- All Rights Reversed.