diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 350a1488ef13..49c7278f8d74 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1742,6 +1742,18 @@ cont: if (isolate_lru_page(compound_head(page))) continue; + /* MADV_FREE clears pte dirty bit and then marks the page + * lazyfree (clear SwapBacked). Inbetween if this lazyfreed page + * is touched by user then it becomes dirty. PPR in + * shrink_page_list in try_to_unmap finds the page dirty, marks + * it back as PageSwapBacked and skips reclaim. This can cause + * isolated count mismatch. + */ + if (PageAnon(page) && !PageSwapBacked(page)) { + putback_lru_page(page); + continue; + } + list_add(&page->lru, &page_list); inc_node_page_state(page, NR_ISOLATED_ANON + page_is_file_cache(page));