Re: [PATCHv2, RFC 05/30] thp, mm: avoid PageUnevictable on active/inactivelru lists

From: Ric Mason
Date: Thu Apr 04 2013 - 23:42:50 EST


Hi Kirill,
On 03/22/2013 06:11 PM, Kirill A. Shutemov wrote:
Dave Hansen wrote:
On 03/14/2013 10:50 AM, Kirill A. Shutemov wrote:
active/inactive lru lists can contain unevicable pages (i.e. ramfs pages
that have been placed on the LRU lists when first allocated), but these
pages must not have PageUnevictable set - otherwise shrink_active_list
goes crazy:
...
For lru_add_page_tail(), it means we should not set PageUnevictable()
for tail pages unless we're sure that it will go to LRU_UNEVICTABLE.
The tail page will go LRU_UNEVICTABLE if head page is not on LRU or if
it's marked PageUnevictable() too.
This is only an issue once you're using lru_add_page_tail() for
non-anonymous pages, right?
I'm not sure about that. Documentation/vm/unevictable-lru.txt:

Some examples of these unevictable pages on the LRU lists are:

(1) ramfs pages that have been placed on the LRU lists when first allocated.

(2) SHM_LOCK'd shared memory pages. shmctl(SHM_LOCK) does not attempt to
allocate or fault in the pages in the shared memory region. This happens
when an application accesses the page the first time after SHM_LOCK'ing
the segment.

(3) mlocked pages that could not be isolated from the LRU and moved to the
unevictable list in mlock_vma_page().

(4) Pages mapped into multiple VM_LOCKED VMAs, but try_to_munlock() couldn't
acquire the VMA's mmap semaphore to test the flags and set PageMlocked.
munlock_vma_page() was forced to let the page back on to the normal LRU
list for vmscan to handle.

diff --git a/mm/swap.c b/mm/swap.c
index 92a9be5..31584d0 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -762,7 +762,8 @@ void lru_add_page_tail(struct page *page, struct page *page_tail,
lru = LRU_INACTIVE_ANON;
}
} else {
- SetPageUnevictable(page_tail);
+ if (!PageLRU(page) || PageUnevictable(page))
+ SetPageUnevictable(page_tail);
lru = LRU_UNEVICTABLE;
}
You were saying above that ramfs pages can get on the normal
active/inactive lists. But, this will end up getting them on the
unevictable list, right? So, we have normal ramfs pages on the
active/inactive lists, but ramfs pages after a huge-page-split on the
unevictable list. That seems a bit inconsistent.
Yeah, it's confusing.

I was able to trigger another bug on this code:
if page_evictable(page_tail) is false and PageLRU(page) is true, page_tail
will go to the same lru as page, but nobody cares to sync page_tail
active/inactive state with page. So we can end up with inactive page on
active lru...

I've updated the patch for the next interation. You can check it in git.
It should be cleaner. Description need to be updated.

Hope you can send out soon. ;-)



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/