Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8debfd47 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mm/page_alloc: fix incorrect isolation behavior by rechecking migratetype"

parents f371d213 8b283f35
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -370,6 +370,16 @@ struct zone {
	unsigned long		compact_cached_free_pfn;
	unsigned long		compact_cached_migrate_pfn;
#endif

#ifdef CONFIG_MEMORY_ISOLATION
	/*
	 * Number of isolated pageblock. It is used to solve incorrect
	 * freepage counting problem due to racy retrieving migratetype
	 * of pageblock. Protected by zone->lock.
	 */
	unsigned long           nr_isolate_pageblock;
#endif

#ifdef CONFIG_MEMORY_HOTPLUG
	/* see spanned/present_pages for more description */
	seqlock_t		span_seqlock;
+8 −0
Original line number Diff line number Diff line
@@ -2,6 +2,10 @@
#define __LINUX_PAGEISOLATION_H

#ifdef CONFIG_MEMORY_ISOLATION
static inline bool has_isolate_pageblock(struct zone *zone)
{
	return zone->nr_isolate_pageblock;
}
static inline bool is_migrate_isolate_page(struct page *page)
{
	return get_pageblock_migratetype(page) == MIGRATE_ISOLATE;
@@ -11,6 +15,10 @@ static inline bool is_migrate_isolate(int migratetype)
	return migratetype == MIGRATE_ISOLATE;
}
#else
static inline bool has_isolate_pageblock(struct zone *zone)
{
	return false;
}
static inline bool is_migrate_isolate_page(struct page *page)
{
	return false;
+9 −2
Original line number Diff line number Diff line
@@ -718,9 +718,16 @@ static void free_one_page(struct zone *zone, struct page *page, int order,
	spin_lock(&zone->lock);
	zone->pages_scanned = 0;

	__free_one_page(page, zone, order, migratetype);
	if (unlikely(!is_migrate_isolate(migratetype)))
	if (unlikely(has_isolate_pageblock(zone) ||
		is_migrate_isolate(migratetype))) {
		migratetype = get_pageblock_migratetype(page);
		if (is_migrate_isolate(migratetype))
			goto skip_counting;
	}
	__mod_zone_freepage_state(zone, 1 << order, migratetype);

skip_counting:
	__free_one_page(page, zone, order, migratetype);
	spin_unlock(&zone->lock);
}

+2 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ out:
		int migratetype = get_pageblock_migratetype(page);

		set_pageblock_migratetype(page, MIGRATE_ISOLATE);
		zone->nr_isolate_pageblock++;
		nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE);

		__mod_zone_freepage_state(zone, -nr_pages, migratetype);
@@ -82,6 +83,7 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype)
	nr_pages = move_freepages_block(zone, page, migratetype);
	__mod_zone_freepage_state(zone, nr_pages, migratetype);
	set_pageblock_migratetype(page, migratetype);
	zone->nr_isolate_pageblock--;
out:
	spin_unlock_irqrestore(&zone->lock, flags);
}