Files
kernel/include/linux
David Rientjes b676b293fb mm, thp: fix mapped pages avoiding unevictable list on mlock
When a transparent hugepage is mapped and it is included in an mlock()
range, follow_page() incorrectly avoids setting the page's mlock bit and
moving it to the unevictable lru.

This is evident if you try to mlock(), munlock(), and then mlock() a
range again.  Currently:

	#define MAP_SIZE	(4 << 30)	/* 4GB */

	void *ptr = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
			 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
	mlock(ptr, MAP_SIZE);

		$ grep -E "Unevictable|Inactive\(anon" /proc/meminfo
		Inactive(anon):     6304 kB
		Unevictable:     4213924 kB

	munlock(ptr, MAP_SIZE);

		Inactive(anon):  4186252 kB
		Unevictable:       19652 kB

	mlock(ptr, MAP_SIZE);

		Inactive(anon):  4198556 kB
		Unevictable:       21684 kB

Notice that less than 2MB was added to the unevictable list; this is
because these pages in the range are not transparent hugepages since the
4GB range was allocated with mmap() and has no specific alignment.  If
posix_memalign() were used instead, unevictable would not have grown at
all on the second mlock().

The fix is to call mlock_vma_page() so that the mlock bit is set and the
page is added to the unevictable list.  With this patch:

	mlock(ptr, MAP_SIZE);

		Inactive(anon):     4056 kB
		Unevictable:     4213940 kB

	munlock(ptr, MAP_SIZE);

		Inactive(anon):  4198268 kB
		Unevictable:       19636 kB

	mlock(ptr, MAP_SIZE);

		Inactive(anon):     4008 kB
		Unevictable:     4213940 kB

Signed-off-by: David Rientjes <rientjes@google.com>
Acked-by: Hugh Dickins <hughd@google.com>
Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michel Lespinasse <walken@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-10-09 16:23:02 +09:00
..
2012-09-19 19:08:53 -06:00
2012-09-27 14:28:09 -03:00
2012-10-06 03:04:35 +09:00
2012-09-19 19:08:46 -06:00
2012-09-17 15:00:38 -07:00
2012-09-17 15:00:38 -07:00
2012-08-21 01:19:54 -07:00
2012-09-05 12:18:11 -07:00
2012-09-27 09:29:33 -04:00
2012-09-26 21:10:00 -04:00
2012-09-19 19:50:20 +02:00
2012-10-06 03:04:56 +09:00
2012-10-01 18:39:45 -04:00
2012-09-07 14:57:45 -04:00
2012-09-11 10:15:02 +02:00
2012-09-26 13:52:36 -07:00
2012-08-22 10:24:41 -04:00
2012-09-17 15:00:37 -07:00
2012-10-09 16:22:54 +09:00
2012-10-09 16:23:00 +09:00
2012-10-06 03:05:24 +09:00
2012-09-27 10:47:59 +02:00
2012-10-09 16:22:24 +09:00
2012-10-05 22:23:53 +02:00
2012-09-13 09:08:02 -06:00
2012-08-21 20:50:25 +02:00
2012-10-06 03:05:01 +09:00
2012-10-09 16:22:24 +09:00
2012-09-06 09:17:01 -07:00
2012-10-09 16:22:55 +09:00
2012-08-21 16:28:31 +02:00
2012-10-09 16:22:32 +09:00
2012-09-05 17:21:36 -07:00
2012-09-28 15:05:15 +09:30