| From 22146c3ce98962436e401f7b7016a6f664c9ffb5 Mon Sep 17 00:00:00 2001 |
| From: Mike Kravetz <mike.kravetz@oracle.com> |
| Date: Fri, 26 Oct 2018 15:10:58 -0700 |
| Subject: hugetlbfs: dirty pages as they are added to pagecache |
| |
| From: Mike Kravetz <mike.kravetz@oracle.com> |
| |
| commit 22146c3ce98962436e401f7b7016a6f664c9ffb5 upstream. |
| |
| Some test systems were experiencing negative huge page reserve counts and |
| incorrect file block counts. This was traced to /proc/sys/vm/drop_caches |
| removing clean pages from hugetlbfs file pagecaches. When non-hugetlbfs |
| explicit code removes the pages, the appropriate accounting is not |
| performed. |
| |
| This can be recreated as follows: |
| fallocate -l 2M /dev/hugepages/foo |
| echo 1 > /proc/sys/vm/drop_caches |
| fallocate -l 2M /dev/hugepages/foo |
| grep -i huge /proc/meminfo |
| AnonHugePages: 0 kB |
| ShmemHugePages: 0 kB |
| HugePages_Total: 2048 |
| HugePages_Free: 2047 |
| HugePages_Rsvd: 18446744073709551615 |
| HugePages_Surp: 0 |
| Hugepagesize: 2048 kB |
| Hugetlb: 4194304 kB |
| ls -lsh /dev/hugepages/foo |
| 4.0M -rw-r--r--. 1 root root 2.0M Oct 17 20:05 /dev/hugepages/foo |
| |
| To address this issue, dirty pages as they are added to pagecache. This |
| can easily be reproduced with fallocate as shown above. Read faulted |
| pages will eventually end up being marked dirty. But there is a window |
| where they are clean and could be impacted by code such as drop_caches. |
| So, just dirty them all as they are added to the pagecache. |
| |
| Link: http://lkml.kernel.org/r/b5be45b8-5afe-56cd-9482-28384699a049@oracle.com |
| Fixes: 6bda666a03f0 ("hugepages: fold find_or_alloc_pages into huge_no_page()") |
| Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> |
| Acked-by: Mihcla Hocko <mhocko@suse.com> |
| Reviewed-by: Khalid Aziz <khalid.aziz@oracle.com> |
| Cc: Hugh Dickins <hughd@google.com> |
| Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> |
| Cc: "Aneesh Kumar K . V" <aneesh.kumar@linux.vnet.ibm.com> |
| Cc: Andrea Arcangeli <aarcange@redhat.com> |
| Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com> |
| Cc: Davidlohr Bueso <dave@stgolabs.net> |
| Cc: Alexander Viro <viro@zeniv.linux.org.uk> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| mm/hugetlb.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/mm/hugetlb.c |
| +++ b/mm/hugetlb.c |
| @@ -3645,6 +3645,12 @@ int huge_add_to_page_cache(struct page * |
| return err; |
| ClearPagePrivate(page); |
| |
| + /* |
| + * set page dirty so that it will not be removed from cache/file |
| + * by non-hugetlbfs specific code paths. |
| + */ |
| + set_page_dirty(page); |
| + |
| spin_lock(&inode->i_lock); |
| inode->i_blocks += blocks_per_huge_page(h); |
| spin_unlock(&inode->i_lock); |