Commit f37c0f68 authored by Zi Yan's avatar Zi Yan Committed by Andrew Morton

mm: page_alloc: set migratetype inside move_freepages()

This avoids changing migratetype after move_freepages() or
move_freepages_block(), which is error prone.  It also prepares for
upcoming changes to fix move_freepages() not moving free pages partially
in the range.

Link: https://lkml.kernel.org/r/20240320180429.678181-9-hannes@cmpxchg.orgSigned-off-by: default avatarZi Yan <ziy@nvidia.com>
Signed-off-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Reviewed-by: default avatarVlastimil Babka <vbabka@suse.cz>
Tested-by: default avatarBaolin Wang <baolin.wang@linux.alibaba.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: "Huang, Ying" <ying.huang@intel.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 55612e80
...@@ -1586,9 +1586,8 @@ static inline struct page *__rmqueue_cma_fallback(struct zone *zone, ...@@ -1586,9 +1586,8 @@ static inline struct page *__rmqueue_cma_fallback(struct zone *zone,
#endif #endif
/* /*
* Move the free pages in a range to the freelist tail of the requested type. * Change the type of a block and move all its free pages to that
* Note that start_page and end_pages are not aligned on a pageblock * type's freelist.
* boundary. If alignment is required, use move_freepages_block()
*/ */
static int move_freepages(struct zone *zone, unsigned long start_pfn, static int move_freepages(struct zone *zone, unsigned long start_pfn,
unsigned long end_pfn, int migratetype) unsigned long end_pfn, int migratetype)
...@@ -1598,6 +1597,9 @@ static int move_freepages(struct zone *zone, unsigned long start_pfn, ...@@ -1598,6 +1597,9 @@ static int move_freepages(struct zone *zone, unsigned long start_pfn,
unsigned int order; unsigned int order;
int pages_moved = 0; int pages_moved = 0;
VM_WARN_ON(start_pfn & (pageblock_nr_pages - 1));
VM_WARN_ON(start_pfn + pageblock_nr_pages - 1 != end_pfn);
for (pfn = start_pfn; pfn <= end_pfn;) { for (pfn = start_pfn; pfn <= end_pfn;) {
page = pfn_to_page(pfn); page = pfn_to_page(pfn);
if (!PageBuddy(page)) { if (!PageBuddy(page)) {
...@@ -1615,6 +1617,8 @@ static int move_freepages(struct zone *zone, unsigned long start_pfn, ...@@ -1615,6 +1617,8 @@ static int move_freepages(struct zone *zone, unsigned long start_pfn,
pages_moved += 1 << order; pages_moved += 1 << order;
} }
set_pageblock_migratetype(pfn_to_page(start_pfn), migratetype);
return pages_moved; return pages_moved;
} }
...@@ -1842,7 +1846,6 @@ steal_suitable_fallback(struct zone *zone, struct page *page, ...@@ -1842,7 +1846,6 @@ steal_suitable_fallback(struct zone *zone, struct page *page,
if (free_pages + alike_pages >= (1 << (pageblock_order-1)) || if (free_pages + alike_pages >= (1 << (pageblock_order-1)) ||
page_group_by_mobility_disabled) { page_group_by_mobility_disabled) {
move_freepages(zone, start_pfn, end_pfn, start_type); move_freepages(zone, start_pfn, end_pfn, start_type);
set_pageblock_migratetype(page, start_type);
return __rmqueue_smallest(zone, order, start_type); return __rmqueue_smallest(zone, order, start_type);
} }
...@@ -1916,12 +1919,10 @@ static void reserve_highatomic_pageblock(struct page *page, struct zone *zone) ...@@ -1916,12 +1919,10 @@ static void reserve_highatomic_pageblock(struct page *page, struct zone *zone)
/* Yoink! */ /* Yoink! */
mt = get_pageblock_migratetype(page); mt = get_pageblock_migratetype(page);
/* Only reserve normal pageblocks (i.e., they can merge with others) */ /* Only reserve normal pageblocks (i.e., they can merge with others) */
if (migratetype_is_mergeable(mt)) { if (migratetype_is_mergeable(mt))
if (move_freepages_block(zone, page, MIGRATE_HIGHATOMIC) != -1) { if (move_freepages_block(zone, page,
set_pageblock_migratetype(page, MIGRATE_HIGHATOMIC); MIGRATE_HIGHATOMIC) != -1)
zone->nr_reserved_highatomic += pageblock_nr_pages; zone->nr_reserved_highatomic += pageblock_nr_pages;
}
}
out_unlock: out_unlock:
spin_unlock_irqrestore(&zone->lock, flags); spin_unlock_irqrestore(&zone->lock, flags);
...@@ -2000,7 +2001,6 @@ static bool unreserve_highatomic_pageblock(const struct alloc_context *ac, ...@@ -2000,7 +2001,6 @@ static bool unreserve_highatomic_pageblock(const struct alloc_context *ac,
* not fail on zone boundaries. * not fail on zone boundaries.
*/ */
WARN_ON_ONCE(ret == -1); WARN_ON_ONCE(ret == -1);
set_pageblock_migratetype(page, ac->migratetype);
if (ret > 0) { if (ret > 0) {
spin_unlock_irqrestore(&zone->lock, flags); spin_unlock_irqrestore(&zone->lock, flags);
return ret; return ret;
...@@ -2682,10 +2682,9 @@ int __isolate_free_page(struct page *page, unsigned int order) ...@@ -2682,10 +2682,9 @@ int __isolate_free_page(struct page *page, unsigned int order)
* Only change normal pageblocks (i.e., they can merge * Only change normal pageblocks (i.e., they can merge
* with others) * with others)
*/ */
if (migratetype_is_mergeable(mt) && if (migratetype_is_mergeable(mt))
move_freepages_block(zone, page, move_freepages_block(zone, page,
MIGRATE_MOVABLE) != -1) MIGRATE_MOVABLE);
set_pageblock_migratetype(page, MIGRATE_MOVABLE);
} }
} }
......
...@@ -188,7 +188,6 @@ static int set_migratetype_isolate(struct page *page, int migratetype, int isol_ ...@@ -188,7 +188,6 @@ static int set_migratetype_isolate(struct page *page, int migratetype, int isol_
return -EBUSY; return -EBUSY;
} }
__mod_zone_freepage_state(zone, -nr_pages, mt); __mod_zone_freepage_state(zone, -nr_pages, mt);
set_pageblock_migratetype(page, MIGRATE_ISOLATE);
zone->nr_isolate_pageblock++; zone->nr_isolate_pageblock++;
spin_unlock_irqrestore(&zone->lock, flags); spin_unlock_irqrestore(&zone->lock, flags);
return 0; return 0;
...@@ -262,10 +261,10 @@ static void unset_migratetype_isolate(struct page *page, int migratetype) ...@@ -262,10 +261,10 @@ static void unset_migratetype_isolate(struct page *page, int migratetype)
*/ */
WARN_ON_ONCE(nr_pages == -1); WARN_ON_ONCE(nr_pages == -1);
__mod_zone_freepage_state(zone, nr_pages, migratetype); __mod_zone_freepage_state(zone, nr_pages, migratetype);
} } else {
set_pageblock_migratetype(page, migratetype); set_pageblock_migratetype(page, migratetype);
if (isolated_page)
__putback_isolated_page(page, order, migratetype); __putback_isolated_page(page, order, migratetype);
}
zone->nr_isolate_pageblock--; zone->nr_isolate_pageblock--;
out: out:
spin_unlock_irqrestore(&zone->lock, flags); spin_unlock_irqrestore(&zone->lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment