On Tue, May 28, 2019 at 10:54:32PM +0800, Hillf Danton wrote: > > On Mon, 20 May 2019 12:52:50 +0900 Minchan Kim wrote: > > +unsigned long reclaim_pages(struct list_head *page_list) > > +{ > > + int nid = -1; > > + unsigned long nr_isolated[2] = {0, }; > > + unsigned long nr_reclaimed = 0; > > + LIST_HEAD(node_page_list); > > + struct reclaim_stat dummy_stat; > > + struct scan_control sc = { > > + .gfp_mask = GFP_KERNEL, > > + .priority = DEF_PRIORITY, > > + .may_writepage = 1, > > + .may_unmap = 1, > > + .may_swap = 1, > > + }; > > + > > + while (!list_empty(page_list)) { > > + struct page *page; > > + > > + page = lru_to_page(page_list); > > + list_del(&page->lru); > > + > > + if (nid == -1) { > > + nid = page_to_nid(page); > > + INIT_LIST_HEAD(&node_page_list); > > + nr_isolated[0] = nr_isolated[1] = 0; > > + } > > + > > + if (nid == page_to_nid(page)) { > > + list_add(&page->lru, &node_page_list); > > + nr_isolated[!!page_is_file_cache(page)] += > > + hpage_nr_pages(page); > > + continue; > > + } > > + > Now, page's node != nid and any page on the node_page_list has > node == nid. > > + nid = page_to_nid(page); > > After updating nid, we get the node id of the isolated pages lost. > > > + > > + mod_node_page_state(NODE_DATA(nid), NR_ISOLATED_ANON, > > + nr_isolated[0]); > > + mod_node_page_state(NODE_DATA(nid), NR_ISOLATED_FILE, > > + nr_isolated[1]); > > + nr_reclaimed += shrink_page_list(&node_page_list, > > + NODE_DATA(nid), &sc, TTU_IGNORE_ACCESS, > > And nid no longer matches the node of the pages to be shrunk. > > > + &dummy_stat, true); > > + while (!list_empty(&node_page_list)) { > > + struct page *page = lru_to_page(page_list); > > Non-empty node_page_list will never become empty if pages are deleted > only from the page_list. Sure. They were last minute change. I will fix it. Thanks for the review!