From: Naoya Horiguchi <naoya.horiguchi@xxxxxxx> When offlining memory section with hwpoisoned pages, the hwpoisons are canceled. But num_poisoned_pages is not updated for that event, so the counter becomes inconsistent. Add num_poisoned_pages_dec() in __offline_isolated_pages(). PageHWPoison can be set on a tail page of some high order buddy page, so we need check PageHWPoison on each subpage. Signed-off-by: Naoya Horiguchi <naoya.horiguchi@xxxxxxx> --- mm/page_alloc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6e5b4488a0c5..dcd962855617 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -9487,12 +9487,15 @@ void __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) zone = page_zone(pfn_to_page(pfn)); spin_lock_irqsave(&zone->lock, flags); while (pfn < end_pfn) { + int i; + page = pfn_to_page(pfn); /* * The HWPoisoned page may be not in buddy system, and * page_count() is not 0. */ if (unlikely(!PageBuddy(page) && PageHWPoison(page))) { + num_poisoned_pages_dec(); pfn++; continue; } @@ -9510,6 +9513,9 @@ void __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) BUG_ON(page_count(page)); BUG_ON(!PageBuddy(page)); order = buddy_order(page); + for (i = 0; i < 1 << order; i++) + if (PageHWPoison(page + i)) + num_poisoned_pages_dec(); del_page_from_free_list(page, zone, order); pfn += (1 << order); } -- 2.25.1