From: "Kirill A. Shutemov" <kirill@shutemov.name>
To: Lucian Adrian Grijincu <lucian@fb.com>
Cc: linux-mm@kvack.org, Souptick Joarder <jrdr.linux@gmail.com>,
linux-kernel@vger.kernel.org, Michal Hocko <mhocko@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Rik van Riel <riel@fb.com>, Roman Gushchin <guro@fb.com>
Subject: Re: [PATCH v3] mm: memory: fix /proc/meminfo reporting for MLOCK_ONFAULT
Date: Mon, 16 Sep 2019 18:26:19 +0300 [thread overview]
Message-ID: <20190916152619.vbi3chozlrzdiuqy@box> (raw)
In-Reply-To: <20190913211119.416168-1-lucian@fb.com>
On Fri, Sep 13, 2019 at 02:11:19PM -0700, Lucian Adrian Grijincu wrote:
> As pages are faulted in MLOCK_ONFAULT correctly updates
> /proc/self/smaps, but doesn't update /proc/meminfo's Mlocked field.
I don't think there's something wrong with this behaviour. It is okay to
keep the page an evictable LRU list (and not account it to NR_MLOCKED).
Some pages, like partly mapped THP will never be on unevictable LRU,
others will be found by vmscan later.
So, it's not bug per se.
Said that, we probably should try to put pages on unevictable LRU sooner
rather than later.
>
> - Before this /proc/meminfo fields didn't change as pages were faulted in:
>
> = Start =
> /proc/meminfo
> Unevictable: 10128 kB
> Mlocked: 10132 kB
> = Creating testfile =
>
> = after mlock2(MLOCK_ONFAULT) =
> /proc/meminfo
> Unevictable: 10128 kB
> Mlocked: 10132 kB
> /proc/self/smaps
> 7f8714000000-7f8754000000 rw-s 00000000 08:04 50857050 /root/testfile
> Locked: 0 kB
>
> = after reading half of the file =
> /proc/meminfo
> Unevictable: 10128 kB
> Mlocked: 10132 kB
> /proc/self/smaps
> 7f8714000000-7f8754000000 rw-s 00000000 08:04 50857050 /root/testfile
> Locked: 524288 kB
>
> = after reading the entire the file =
> /proc/meminfo
> Unevictable: 10128 kB
> Mlocked: 10132 kB
> /proc/self/smaps
> 7f8714000000-7f8754000000 rw-s 00000000 08:04 50857050 /root/testfile
> Locked: 1048576 kB
>
> = after munmap =
> /proc/meminfo
> Unevictable: 10128 kB
> Mlocked: 10132 kB
> /proc/self/smaps
>
> - After: /proc/meminfo fields are properly updated as pages are touched:
>
> = Start =
> /proc/meminfo
> Unevictable: 60 kB
> Mlocked: 60 kB
> = Creating testfile =
>
> = after mlock2(MLOCK_ONFAULT) =
> /proc/meminfo
> Unevictable: 60 kB
> Mlocked: 60 kB
> /proc/self/smaps
> 7f2b9c600000-7f2bdc600000 rw-s 00000000 08:04 63045798 /root/testfile
> Locked: 0 kB
>
> = after reading half of the file =
> /proc/meminfo
> Unevictable: 524220 kB
> Mlocked: 524220 kB
> /proc/self/smaps
> 7f2b9c600000-7f2bdc600000 rw-s 00000000 08:04 63045798 /root/testfile
> Locked: 524288 kB
>
> = after reading the entire the file =
> /proc/meminfo
> Unevictable: 1048496 kB
> Mlocked: 1048508 kB
> /proc/self/smaps
> 7f2b9c600000-7f2bdc600000 rw-s 00000000 08:04 63045798 /root/testfile
> Locked: 1048576 kB
>
> = after munmap =
> /proc/meminfo
> Unevictable: 176 kB
> Mlocked: 60 kB
> /proc/self/smaps
>
> Repro code.
> ---
>
> int mlock2wrap(const void* addr, size_t len, int flags) {
> return syscall(SYS_mlock2, addr, len, flags);
> }
>
> void smaps() {
> char smapscmd[1000];
> snprintf(
> smapscmd,
> sizeof(smapscmd) - 1,
> "grep testfile -A 20 /proc/%d/smaps | grep -E '(testfile|Locked)'",
> getpid());
> printf("/proc/self/smaps\n");
> fflush(stdout);
> system(smapscmd);
> }
>
> void meminfo() {
> const char* meminfocmd = "grep -E '(Mlocked|Unevictable)' /proc/meminfo";
> printf("/proc/meminfo\n");
> fflush(stdout);
> system(meminfocmd);
> }
>
> { \
> int rc = (call); \
> if (rc != 0) { \
> printf("error %d %s\n", rc, strerror(errno)); \
> exit(1); \
> } \
> }
> int main(int argc, char* argv[]) {
> printf("= Start =\n");
> meminfo();
>
> printf("= Creating testfile =\n");
> size_t size = 1 << 30; // 1 GiB
> int fd = open("testfile", O_CREAT | O_RDWR, 0666);
> {
> void* buf = malloc(size);
> write(fd, buf, size);
> free(buf);
> }
> int ret = 0;
> void* addr = NULL;
> addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
>
> if (argc > 1) {
> PCHECK(mlock2wrap(addr, size, MLOCK_ONFAULT));
> printf("= after mlock2(MLOCK_ONFAULT) =\n");
> meminfo();
> smaps();
>
> for (size_t i = 0; i < size / 2; i += 4096) {
> ret += ((char*)addr)[i];
> }
> printf("= after reading half of the file =\n");
> meminfo();
> smaps();
>
> for (size_t i = 0; i < size; i += 4096) {
> ret += ((char*)addr)[i];
> }
> printf("= after reading the entire the file =\n");
> meminfo();
> smaps();
>
> } else {
> PCHECK(mlock(addr, size));
> printf("= after mlock =\n");
> meminfo();
> smaps();
> }
>
> PCHECK(munmap(addr, size));
> printf("= after munmap =\n");
> meminfo();
> smaps();
>
> return ret;
> }
>
> ---
>
> Signed-off-by: Lucian Adrian Grijincu <lucian@fb.com>
> Acked-by: Souptick Joarder <jrdr.linux@gmail.com>
> ---
> mm/memory.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/mm/memory.c b/mm/memory.c
> index e0c232fe81d9..55da24f33bc4 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -3311,6 +3311,8 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
> } else {
> inc_mm_counter_fast(vma->vm_mm, mm_counter_file(page));
> page_add_file_rmap(page, false);
> + if (vma->vm_flags & VM_LOCKED && !PageTransCompound(page))
> + mlock_vma_page(page);
Why do you only do this for file pages?
> }
> set_pte_at(vma->vm_mm, vmf->address, vmf->pte, entry);
>
> --
> 2.17.1
>
>
--
Kirill A. Shutemov
next prev parent reply other threads:[~2019-09-16 15:26 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-13 21:11 Lucian Adrian Grijincu
2019-09-13 21:17 ` [Potential Spoof] " Roman Gushchin
2019-09-16 11:35 ` Michal Hocko
2019-09-16 21:34 ` Lucian Grijincu
2019-09-16 15:26 ` Kirill A. Shutemov [this message]
2019-09-17 10:15 ` Michal Hocko
2019-09-17 11:35 ` Kirill A. Shutemov
2019-09-23 8:50 ` Michal Hocko
2019-09-17 11:37 ` Kirill A. Shutemov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190916152619.vbi3chozlrzdiuqy@box \
--to=kirill@shutemov.name \
--cc=akpm@linux-foundation.org \
--cc=guro@fb.com \
--cc=jrdr.linux@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lucian@fb.com \
--cc=mhocko@kernel.org \
--cc=riel@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox