Loading include/linux/mmzone.h +10 −0 Original line number Diff line number Diff line Loading @@ -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; Loading include/linux/page-isolation.h +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading mm/page_alloc.c +9 −2 Original line number Diff line number Diff line Loading @@ -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); } Loading mm/page_isolation.c +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); } Loading Loading
include/linux/mmzone.h +10 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
include/linux/page-isolation.h +8 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading
mm/page_alloc.c +9 −2 Original line number Diff line number Diff line Loading @@ -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); } Loading
mm/page_isolation.c +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); } Loading