UPSTREAM: 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.org Change-Id: Id62a91c8023afa27a84aa40ed912b650e8a112f2 Signed-off-by: Zi Yan <ziy@nvidia.com> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Vlastimil Babka <vbabka@suse.cz> Tested-by: Baolin 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: Andrew Morton <akpm@linux-foundation.org> (cherry picked from commit f37c0f6876a8eabe1477c87860460bc181f6cdbb) Bug: 420771453 Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
This commit is contained in:
@@ -1783,9 +1783,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)
|
||||||
@@ -1795,6 +1794,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)) {
|
||||||
@@ -1812,6 +1814,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2039,7 +2043,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2117,12 +2120,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);
|
||||||
@@ -2207,7 +2208,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;
|
||||||
@@ -2860,10 +2860,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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -189,7 +189,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;
|
||||||
@@ -263,10 +262,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);
|
||||||
|
Reference in New Issue
Block a user