Commit 2139cbe627b8910ded55148f87ee10f7485408ed
Committed by
Linus Torvalds
1 parent
770c8aaaf6
Exists in
master
and in
20 other branches
cma: fix counting of isolated pages
Isolated free pages shouldn't be accounted to NR_FREE_PAGES counter. Fix it by properly decreasing/increasing NR_FREE_PAGES counter in set_migratetype_isolate()/unset_migratetype_isolate() and removing counter adjustment for isolated pages from free_one_page() and split_free_page(). Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Cc: Michal Nazarewicz <mina86@mina86.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Mel Gorman <mgorman@suse.de> Cc: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 16 additions and 5 deletions Side-by-side Diff
mm/page_alloc.c
... | ... | @@ -691,7 +691,8 @@ |
691 | 691 | zone->pages_scanned = 0; |
692 | 692 | |
693 | 693 | __free_one_page(page, zone, order, migratetype); |
694 | - __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order); | |
694 | + if (unlikely(migratetype != MIGRATE_ISOLATE)) | |
695 | + __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order); | |
695 | 696 | spin_unlock(&zone->lock); |
696 | 697 | } |
697 | 698 | |
... | ... | @@ -1392,6 +1393,7 @@ |
1392 | 1393 | unsigned int order; |
1393 | 1394 | unsigned long watermark; |
1394 | 1395 | struct zone *zone; |
1396 | + int mt; | |
1395 | 1397 | |
1396 | 1398 | BUG_ON(!PageBuddy(page)); |
1397 | 1399 | |
... | ... | @@ -1407,7 +1409,10 @@ |
1407 | 1409 | list_del(&page->lru); |
1408 | 1410 | zone->free_area[order].nr_free--; |
1409 | 1411 | rmv_page_order(page); |
1410 | - __mod_zone_page_state(zone, NR_FREE_PAGES, -(1UL << order)); | |
1412 | + | |
1413 | + mt = get_pageblock_migratetype(page); | |
1414 | + if (unlikely(mt != MIGRATE_ISOLATE)) | |
1415 | + __mod_zone_page_state(zone, NR_FREE_PAGES, -(1UL << order)); | |
1411 | 1416 | |
1412 | 1417 | if (alloc_order != order) |
1413 | 1418 | expand(zone, page, alloc_order, order, |
mm/page_isolation.c
... | ... | @@ -76,8 +76,12 @@ |
76 | 76 | |
77 | 77 | out: |
78 | 78 | if (!ret) { |
79 | + unsigned long nr_pages; | |
80 | + | |
79 | 81 | set_pageblock_isolate(page); |
80 | - move_freepages_block(zone, page, MIGRATE_ISOLATE); | |
82 | + nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE); | |
83 | + | |
84 | + __mod_zone_page_state(zone, NR_FREE_PAGES, -nr_pages); | |
81 | 85 | } |
82 | 86 | |
83 | 87 | spin_unlock_irqrestore(&zone->lock, flags); |
84 | 88 | |
... | ... | @@ -89,12 +93,14 @@ |
89 | 93 | void unset_migratetype_isolate(struct page *page, unsigned migratetype) |
90 | 94 | { |
91 | 95 | struct zone *zone; |
92 | - unsigned long flags; | |
96 | + unsigned long flags, nr_pages; | |
97 | + | |
93 | 98 | zone = page_zone(page); |
94 | 99 | spin_lock_irqsave(&zone->lock, flags); |
95 | 100 | if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE) |
96 | 101 | goto out; |
97 | - move_freepages_block(zone, page, migratetype); | |
102 | + nr_pages = move_freepages_block(zone, page, migratetype); | |
103 | + __mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages); | |
98 | 104 | restore_pageblock_isolate(page, migratetype); |
99 | 105 | out: |
100 | 106 | spin_unlock_irqrestore(&zone->lock, flags); |