diff options
author | Michal Nazarewicz <mina86@xxxxxxxxxx> | 2011-12-20 08:53:33 +0800 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2011-12-26 15:09:42 +0800 |
commit | cff293c606578cfbbbea6092db71d89763741b8e (patch) | |
tree | eb49c37aa42148d4bb6d5a7169c50a7f2256bf72 /mm | |
parent | 9661604073fad76e64ef5aae52193b78e8bb4779 (diff) |
If page is on PCP list while pageblock it belongs to gets isolated,
the page's private still holds the old migrate type. This means
that free_pcppages_bulk() will put the page on a freelist of the
old migrate type instead of MIGRATE_ISOLATE.
This commit changes that by explicitly checking whether page's
pageblock's migrate type is MIGRATE_ISOLATE and if it is, overwrites
page's private data.
Signed-off-by: Michal Nazarewicz <mina86@xxxxxxxxxx>
Signed-off-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 2b8ba3aebf6..7cfd08448bc 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -628,6 +628,18 @@ static void free_pcppages_bulk(struct zone *zone, int count, page = list_entry(list->prev, struct page, lru); /* must delete as __free_one_page list manipulates */ list_del(&page->lru); + + /* + * When page is isolated in set_migratetype_isolate() + * function it's page_private is not changed since the + * function has no way of knowing if it can touch it. + * This means that when a page is on PCP list, it's + * page_private no longer matches the desired migrate + * type. + */ + if (get_pageblock_migratetype(page) == MIGRATE_ISOLATE) + set_page_private(page, MIGRATE_ISOLATE); + /* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */ __free_one_page(page, zone, 0, page_private(page)); trace_mm_page_pcpu_drain(page, 0, page_private(page)); |