* [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables @ 2021-04-19 13:54 David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 1/5] mm: make variable names for populate_vma_page_range() consistent David Hildenbrand ` (4 more replies) 0 siblings, 5 replies; 8+ messages in thread From: David Hildenbrand @ 2021-04-19 13:54 UTC (permalink / raw) To: linux-kernel Cc: linux-mm, David Hildenbrand, Andrea Arcangeli, Andrew Morton, Arnd Bergmann, Chris Zankel, Dave Hansen, Helge Deller, Hugh Dickins, Ivan Kokshaysky, James E.J. Bottomley, Jann Horn, Jason Gunthorpe, Kirill A. Shutemov, Linux API, Matthew Wilcox (Oracle), Matt Turner, Max Filippov, Michael S. Tsirkin, Michal Hocko, Mike Kravetz, Minchan Kim, Oscar Salvador, Peter Xu, Ram Pai, Richard Henderson, Rik van Riel, Rolf Eike Beer, Shuah Khan, Thomas Bogendoerfer, Vlastimil Babka Excessive details on MADV_POPULATE_(READ|WRITE) can be found in patch #2. v1 -> v2: - "mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables" -- Renamed patch/series to match what's happening -- prefault page tables -- Clarified MADV_POPULATE_READ semantics on file holes and that we might want fallocate(). -- Updated/clarified description -- Dropped -EINVAL and -EBUSY checks -- Added a comment regarding FOLL_TOUCH and why we don't care that pages will get set dirty when triggering write-faults for now. -- Reran and extended performance measurements by more fallocate() combinations RFCv2 -> v1 - "mm: fix variable name in declaration of populate_vma_page_range()" -- Added - "mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault ..." -- Fix detection of memory holes when we have to re-lookup the VMA -- Return -EHWPOISON to user space when we hit HW poisoned pages -- Make variable names in definition and declaration consistent - "MAINTAINERS: add tools/testing/selftests/vm/ to MEMORY MANAGEMENT" -- Added - "selftests/vm: add protection_keys_32 / protection_keys_64 to gitignore" -- Added - "selftests/vm: add test for MADV_POPULATE_(READ|WRITE)" -- Added RFC -> RFCv2: - Fix re-locking (-> set "locked = 1;") - Don't mimic MAP_POPULATE semantics: --> Explicit READ/WRITE request instead of selecting it automatically, which makes it more generic and better suited for some use cases (e.g., we usually want to prefault shmem writable) --> Require proper access permissions - Introduce and use faultin_vma_page_range() --> Properly handle HWPOISON pages (FOLL_HWPOISON) --> Require proper access permissions (!FOLL_FORCE) - Let faultin_vma_page_range() check for compatible mappings/permissions - Extend patch description and add some performance numbers David Hildenbrand (5): mm: make variable names for populate_vma_page_range() consistent mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables MAINTAINERS: add tools/testing/selftests/vm/ to MEMORY MANAGEMENT selftests/vm: add protection_keys_32 / protection_keys_64 to gitignore selftests/vm: add test for MADV_POPULATE_(READ|WRITE) MAINTAINERS | 1 + arch/alpha/include/uapi/asm/mman.h | 3 + arch/mips/include/uapi/asm/mman.h | 3 + arch/parisc/include/uapi/asm/mman.h | 3 + arch/xtensa/include/uapi/asm/mman.h | 3 + include/uapi/asm-generic/mman-common.h | 3 + mm/gup.c | 58 ++++ mm/internal.h | 5 +- mm/madvise.c | 66 ++++ tools/testing/selftests/vm/.gitignore | 3 + tools/testing/selftests/vm/Makefile | 1 + tools/testing/selftests/vm/madv_populate.c | 342 +++++++++++++++++++++ tools/testing/selftests/vm/run_vmtests.sh | 16 + 13 files changed, 506 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/vm/madv_populate.c -- 2.30.2 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/5] mm: make variable names for populate_vma_page_range() consistent 2021-04-19 13:54 [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables David Hildenbrand @ 2021-04-19 13:54 ` David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 3/5] MAINTAINERS: add tools/testing/selftests/vm/ to MEMORY MANAGEMENT David Hildenbrand ` (3 subsequent siblings) 4 siblings, 0 replies; 8+ messages in thread From: David Hildenbrand @ 2021-04-19 13:54 UTC (permalink / raw) To: linux-kernel Cc: linux-mm, David Hildenbrand, Andrew Morton, Michal Hocko, Oscar Salvador, Jason Gunthorpe, Peter Xu Let's make the variable names in the function declaration match the variable names used in the definition. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Peter Xu <peterx@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com> --- mm/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/internal.h b/mm/internal.h index cb3c5e0a7799..bbf1c1274983 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -354,7 +354,7 @@ void __vma_unlink_list(struct mm_struct *mm, struct vm_area_struct *vma); #ifdef CONFIG_MMU extern long populate_vma_page_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end, int *nonblocking); + unsigned long start, unsigned long end, int *locked); extern void munlock_vma_pages_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); static inline void munlock_vma_pages_all(struct vm_area_struct *vma) -- 2.30.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/5] MAINTAINERS: add tools/testing/selftests/vm/ to MEMORY MANAGEMENT 2021-04-19 13:54 [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 1/5] mm: make variable names for populate_vma_page_range() consistent David Hildenbrand @ 2021-04-19 13:54 ` David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 4/5] selftests/vm: add protection_keys_32 / protection_keys_64 to gitignore David Hildenbrand ` (2 subsequent siblings) 4 siblings, 0 replies; 8+ messages in thread From: David Hildenbrand @ 2021-04-19 13:54 UTC (permalink / raw) To: linux-kernel Cc: linux-mm, David Hildenbrand, Andrew Morton, Michal Hocko, Oscar Salvador, Jason Gunthorpe, Peter Xu, Shuah Khan, linux-kselftest MEMORY MANAGEMENT seems to be a good fit. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Peter Xu <peterx@redhat.com> Cc: Shuah Khan <shuah@kernel.org> Cc: linux-kselftest@vger.kernel.org Signed-off-by: David Hildenbrand <david@redhat.com> --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9450e052f1b1..cd267d218e08 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11566,6 +11566,7 @@ F: include/linux/mm.h F: include/linux/mmzone.h F: include/linux/vmalloc.h F: mm/ +F: tools/testing/selftests/vm/ MEMORY TECHNOLOGY DEVICES (MTD) M: Miquel Raynal <miquel.raynal@bootlin.com> -- 2.30.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 4/5] selftests/vm: add protection_keys_32 / protection_keys_64 to gitignore 2021-04-19 13:54 [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 1/5] mm: make variable names for populate_vma_page_range() consistent David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 3/5] MAINTAINERS: add tools/testing/selftests/vm/ to MEMORY MANAGEMENT David Hildenbrand @ 2021-04-19 13:54 ` David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 5/5] selftests/vm: add test for MADV_POPULATE_(READ|WRITE) David Hildenbrand 2021-05-10 4:21 ` [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables Andrew Morton 4 siblings, 0 replies; 8+ messages in thread From: David Hildenbrand @ 2021-04-19 13:54 UTC (permalink / raw) To: linux-kernel Cc: linux-mm, David Hildenbrand, Andrew Morton, Michal Hocko, Oscar Salvador, Jason Gunthorpe, Peter Xu, Ram Pai, Shuah Khan, linux-kselftest We missed to add two binaries to gitignore. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Peter Xu <peterx@redhat.com> Cc: Ram Pai <linuxram@us.ibm.com> Cc: Shuah Khan <shuah@kernel.org> Cc: linux-kselftest@vger.kernel.org Signed-off-by: David Hildenbrand <david@redhat.com> --- tools/testing/selftests/vm/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/vm/.gitignore b/tools/testing/selftests/vm/.gitignore index 9a35c3f6a557..b4fc0148360e 100644 --- a/tools/testing/selftests/vm/.gitignore +++ b/tools/testing/selftests/vm/.gitignore @@ -22,3 +22,5 @@ map_fixed_noreplace write_to_hugetlbfs hmm-tests local_config.* +protection_keys_32 +protection_keys_64 -- 2.30.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 5/5] selftests/vm: add test for MADV_POPULATE_(READ|WRITE) 2021-04-19 13:54 [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables David Hildenbrand ` (2 preceding siblings ...) 2021-04-19 13:54 ` [PATCH v2 4/5] selftests/vm: add protection_keys_32 / protection_keys_64 to gitignore David Hildenbrand @ 2021-04-19 13:54 ` David Hildenbrand 2021-05-10 4:21 ` [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables Andrew Morton 4 siblings, 0 replies; 8+ messages in thread From: David Hildenbrand @ 2021-04-19 13:54 UTC (permalink / raw) To: linux-kernel Cc: linux-mm, David Hildenbrand, Andrew Morton, Arnd Bergmann, Michal Hocko, Oscar Salvador, Matthew Wilcox, Andrea Arcangeli, Minchan Kim, Jann Horn, Jason Gunthorpe, Dave Hansen, Hugh Dickins, Rik van Riel, Michael S . Tsirkin, Kirill A . Shutemov, Vlastimil Babka, Richard Henderson, Ivan Kokshaysky, Matt Turner, Thomas Bogendoerfer, James E.J. Bottomley, Helge Deller, Chris Zankel, Max Filippov, Mike Kravetz, Peter Xu, Rolf Eike Beer, Shuah Khan, linux-alpha, linux-mips, linux-parisc, linux-xtensa, linux-arch, linux-kselftest, Linux API Let's add a simple test for MADV_POPULATE_READ and MADV_POPULATE_WRITE, verifying some error handling, that population works, and that softdirty tracking works as expected. For now, limit the test to private anonymous memory. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Michal Hocko <mhocko@suse.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Jann Horn <jannh@google.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Hugh Dickins <hughd@google.com> Cc: Rik van Riel <riel@surriel.com> Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Matt Turner <mattst88@gmail.com> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> Cc: Helge Deller <deller@gmx.de> Cc: Chris Zankel <chris@zankel.net> Cc: Max Filippov <jcmvbkbc@gmail.com> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Peter Xu <peterx@redhat.com> Cc: Rolf Eike Beer <eike-kernel@sf-tec.de> Cc: Shuah Khan <shuah@kernel.org> Cc: linux-alpha@vger.kernel.org Cc: linux-mips@vger.kernel.org Cc: linux-parisc@vger.kernel.org Cc: linux-xtensa@linux-xtensa.org Cc: linux-arch@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: Linux API <linux-api@vger.kernel.org> Signed-off-by: David Hildenbrand <david@redhat.com> --- tools/testing/selftests/vm/.gitignore | 1 + tools/testing/selftests/vm/Makefile | 1 + tools/testing/selftests/vm/madv_populate.c | 342 +++++++++++++++++++++ tools/testing/selftests/vm/run_vmtests.sh | 16 + 4 files changed, 360 insertions(+) create mode 100644 tools/testing/selftests/vm/madv_populate.c diff --git a/tools/testing/selftests/vm/.gitignore b/tools/testing/selftests/vm/.gitignore index b4fc0148360e..c9a5dd1adf7d 100644 --- a/tools/testing/selftests/vm/.gitignore +++ b/tools/testing/selftests/vm/.gitignore @@ -24,3 +24,4 @@ hmm-tests local_config.* protection_keys_32 protection_keys_64 +madv_populate diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index 8b0cd421ebd3..04b6650c1924 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile @@ -42,6 +42,7 @@ TEST_GEN_FILES += on-fault-limit TEST_GEN_FILES += thuge-gen TEST_GEN_FILES += transhuge-stress TEST_GEN_FILES += userfaultfd +TEST_GEN_FILES += madv_populate ifeq ($(MACHINE),x86_64) CAN_BUILD_I386 := $(shell ./../x86/check_cc.sh $(CC) ../x86/trivial_32bit_program.c -m32) diff --git a/tools/testing/selftests/vm/madv_populate.c b/tools/testing/selftests/vm/madv_populate.c new file mode 100644 index 000000000000..b959e4ebdad4 --- /dev/null +++ b/tools/testing/selftests/vm/madv_populate.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * MADV_POPULATE_READ and MADV_POPULATE_WRITE tests + * + * Copyright 2021, Red Hat, Inc. + * + * Author(s): David Hildenbrand <david@redhat.com> + */ +#define _GNU_SOURCE +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> + +#include "../kselftest.h" + +#if defined(MADV_POPULATE_READ) && defined(MADV_POPULATE_WRITE) + +/* + * For now, we're using 2 MiB of private anonymous memory for all tests. + */ +#define SIZE (2 * 1024 * 1024) + +static size_t pagesize; + +static uint64_t pagemap_get_entry(int fd, char *start) +{ + const unsigned long pfn = (unsigned long)start / pagesize; + uint64_t entry; + int ret; + + ret = pread(fd, &entry, sizeof(entry), pfn * sizeof(entry)); + if (ret != sizeof(entry)) + ksft_exit_fail_msg("reading pagemap failed\n"); + return entry; +} + +static bool pagemap_is_populated(int fd, char *start) +{ + uint64_t entry = pagemap_get_entry(fd, start); + + /* Present or swapped. */ + return entry & 0xc000000000000000ull; +} + +static bool pagemap_is_softdirty(int fd, char *start) +{ + uint64_t entry = pagemap_get_entry(fd, start); + + return entry & 0x0080000000000000ull; +} + +static void sense_support(void) +{ + char *addr; + int ret; + + addr = mmap(0, pagesize, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + if (!addr) + ksft_exit_fail_msg("mmap failed\n"); + + ret = madvise(addr, pagesize, MADV_POPULATE_READ); + if (ret) + ksft_exit_skip("MADV_POPULATE_READ is not available\n"); + + ret = madvise(addr, pagesize, MADV_POPULATE_WRITE); + if (ret) + ksft_exit_skip("MADV_POPULATE_WRITE is not available\n"); + + munmap(addr, pagesize); +} + +static void test_prot_read(void) +{ + char *addr; + int ret; + + ksft_print_msg("[RUN] %s\n", __func__); + + addr = mmap(0, SIZE, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap failed\n"); + + ret = madvise(addr, SIZE, MADV_POPULATE_READ); + ksft_test_result(!ret, "MADV_POPULATE_READ with PROT_READ\n"); + + ret = madvise(addr, SIZE, MADV_POPULATE_WRITE); + ksft_test_result(ret == -1 && errno == EINVAL, + "MADV_POPULATE_WRITE with PROT_READ\n"); + + munmap(addr, SIZE); +} + +static void test_prot_write(void) +{ + char *addr; + int ret; + + ksft_print_msg("[RUN] %s\n", __func__); + + addr = mmap(0, SIZE, PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap failed\n"); + + ret = madvise(addr, SIZE, MADV_POPULATE_READ); + ksft_test_result(ret == -1 && errno == EINVAL, + "MADV_POPULATE_READ with PROT_WRITE\n"); + + ret = madvise(addr, SIZE, MADV_POPULATE_WRITE); + ksft_test_result(!ret, "MADV_POPULATE_WRITE with PROT_WRITE\n"); + + munmap(addr, SIZE); +} + +static void test_holes(void) +{ + char *addr; + int ret; + + ksft_print_msg("[RUN] %s\n", __func__); + + addr = mmap(0, SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap failed\n"); + ret = munmap(addr + pagesize, pagesize); + if (ret) + ksft_exit_fail_msg("munmap failed\n"); + + /* Hole in the middle */ + ret = madvise(addr, SIZE, MADV_POPULATE_READ); + ksft_test_result(ret == -1 && errno == ENOMEM, + "MADV_POPULATE_READ with holes in the middle\n"); + ret = madvise(addr, SIZE, MADV_POPULATE_WRITE); + ksft_test_result(ret == -1 && errno == ENOMEM, + "MADV_POPULATE_WRITE with holes in the middle\n"); + + /* Hole at end */ + ret = madvise(addr, 2 * pagesize, MADV_POPULATE_READ); + ksft_test_result(ret == -1 && errno == ENOMEM, + "MADV_POPULATE_READ with holes at the end\n"); + ret = madvise(addr, 2 * pagesize, MADV_POPULATE_WRITE); + ksft_test_result(ret == -1 && errno == ENOMEM, + "MADV_POPULATE_WRITE with holes at the end\n"); + + /* Hole at beginning */ + ret = madvise(addr + pagesize, pagesize, MADV_POPULATE_READ); + ksft_test_result(ret == -1 && errno == ENOMEM, + "MADV_POPULATE_READ with holes at the beginning\n"); + ret = madvise(addr + pagesize, pagesize, MADV_POPULATE_WRITE); + ksft_test_result(ret == -1 && errno == ENOMEM, + "MADV_POPULATE_WRITE with holes at the beginning\n"); + + munmap(addr, SIZE); +} + +static bool range_is_populated(char *start, ssize_t size) +{ + int fd = open("/proc/self/pagemap", O_RDONLY); + bool ret = true; + + if (fd < 0) + ksft_exit_fail_msg("opening pagemap failed\n"); + for (; size > 0 && ret; size -= pagesize, start += pagesize) + if (!pagemap_is_populated(fd, start)) + ret = false; + close(fd); + return ret; +} + +static bool range_is_not_populated(char *start, ssize_t size) +{ + int fd = open("/proc/self/pagemap", O_RDONLY); + bool ret = true; + + if (fd < 0) + ksft_exit_fail_msg("opening pagemap failed\n"); + for (; size > 0 && ret; size -= pagesize, start += pagesize) + if (pagemap_is_populated(fd, start)) + ret = false; + close(fd); + return ret; +} + +static void test_populate_read(void) +{ + char *addr; + int ret; + + ksft_print_msg("[RUN] %s\n", __func__); + + addr = mmap(0, SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap failed\n"); + ksft_test_result(range_is_not_populated(addr, SIZE), + "range initially not populated\n"); + + ret = madvise(addr, SIZE, MADV_POPULATE_READ); + ksft_test_result(!ret, "MADV_POPULATE_READ\n"); + ksft_test_result(range_is_populated(addr, SIZE), + "range is populated\n"); + + munmap(addr, SIZE); +} + +static void test_populate_write(void) +{ + char *addr; + int ret; + + ksft_print_msg("[RUN] %s\n", __func__); + + addr = mmap(0, SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap failed\n"); + ksft_test_result(range_is_not_populated(addr, SIZE), + "range initially not populated\n"); + + ret = madvise(addr, SIZE, MADV_POPULATE_WRITE); + ksft_test_result(!ret, "MADV_POPULATE_WRITE\n"); + ksft_test_result(range_is_populated(addr, SIZE), + "range is populated\n"); + + munmap(addr, SIZE); +} + +static bool range_is_softdirty(char *start, ssize_t size) +{ + int fd = open("/proc/self/pagemap", O_RDONLY); + bool ret = true; + + if (fd < 0) + ksft_exit_fail_msg("opening pagemap failed\n"); + for (; size > 0 && ret; size -= pagesize, start += pagesize) + if (!pagemap_is_softdirty(fd, start)) + ret = false; + close(fd); + return ret; +} + +static bool range_is_not_softdirty(char *start, ssize_t size) +{ + int fd = open("/proc/self/pagemap", O_RDONLY); + bool ret = true; + + if (fd < 0) + ksft_exit_fail_msg("opening pagemap failed\n"); + for (; size > 0 && ret; size -= pagesize, start += pagesize) + if (pagemap_is_softdirty(fd, start)) + ret = false; + close(fd); + return ret; +} + +static void clear_softdirty(void) +{ + int fd = open("/proc/self/clear_refs", O_WRONLY); + const char *ctrl = "4"; + int ret; + + if (fd < 0) + ksft_exit_fail_msg("opening clear_refs failed\n"); + ret = write(fd, ctrl, strlen(ctrl)); + if (ret != strlen(ctrl)) + ksft_exit_fail_msg("writing clear_refs failed\n"); + close(fd); +} + +static void test_softdirty(void) +{ + char *addr; + int ret; + + ksft_print_msg("[RUN] %s\n", __func__); + + addr = mmap(0, SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap failed\n"); + + /* Clear any softdirty bits. */ + clear_softdirty(); + ksft_test_result(range_is_not_softdirty(addr, SIZE), + "range is not softdirty\n"); + + /* Populating READ should set softdirty. */ + ret = madvise(addr, SIZE, MADV_POPULATE_READ); + ksft_test_result(!ret, "MADV_POPULATE_READ\n"); + ksft_test_result(range_is_not_softdirty(addr, SIZE), + "range is not softdirty\n"); + + /* Populating WRITE should set softdirty. */ + ret = madvise(addr, SIZE, MADV_POPULATE_WRITE); + ksft_test_result(!ret, "MADV_POPULATE_WRITE\n"); + ksft_test_result(range_is_softdirty(addr, SIZE), + "range is softdirty\n"); + + munmap(addr, SIZE); +} + +int main(int argc, char **argv) +{ + int err; + + pagesize = getpagesize(); + + ksft_print_header(); + ksft_set_plan(21); + + sense_support(); + test_prot_read(); + test_prot_write(); + test_holes(); + test_populate_read(); + test_populate_write(); + test_softdirty(); + + err = ksft_get_fail_cnt(); + if (err) + ksft_exit_fail_msg("%d out of %d tests failed\n", + err, ksft_test_num()); + return ksft_exit_pass(); +} + +#else /* defined(MADV_POPULATE_READ) && defined(MADV_POPULATE_WRITE) */ + +#warning "missing MADV_POPULATE_READ or MADV_POPULATE_WRITE definition" + +int main(int argc, char **argv) +{ + ksft_print_header(); + ksft_exit_skip("MADV_POPULATE_READ or MADV_POPULATE_WRITE not defined\n"); +} + +#endif /* defined(MADV_POPULATE_READ) && defined(MADV_POPULATE_WRITE) */ diff --git a/tools/testing/selftests/vm/run_vmtests.sh b/tools/testing/selftests/vm/run_vmtests.sh index e953f3cd9664..955782d138ab 100755 --- a/tools/testing/selftests/vm/run_vmtests.sh +++ b/tools/testing/selftests/vm/run_vmtests.sh @@ -346,4 +346,20 @@ else exitcode=1 fi +echo "--------------------------------------------------------" +echo "running MADV_POPULATE_READ and MADV_POPULATE_WRITE tests" +echo "--------------------------------------------------------" +./madv_populate +ret_val=$? + +if [ $ret_val -eq 0 ]; then + echo "[PASS]" +elif [ $ret_val -eq $ksft_skip ]; then + echo "[SKIP]" + exitcode=$ksft_skip +else + echo "[FAIL]" + exitcode=1 +fi + exit $exitcode -- 2.30.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables 2021-04-19 13:54 [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables David Hildenbrand ` (3 preceding siblings ...) 2021-04-19 13:54 ` [PATCH v2 5/5] selftests/vm: add test for MADV_POPULATE_(READ|WRITE) David Hildenbrand @ 2021-05-10 4:21 ` Andrew Morton 2021-05-10 14:52 ` David Hildenbrand 4 siblings, 1 reply; 8+ messages in thread From: Andrew Morton @ 2021-05-10 4:21 UTC (permalink / raw) To: David Hildenbrand Cc: linux-kernel, linux-mm, Andrea Arcangeli, Arnd Bergmann, Chris Zankel, Dave Hansen, Helge Deller, Hugh Dickins, Ivan Kokshaysky, James E.J. Bottomley, Jann Horn, Jason Gunthorpe, Kirill A. Shutemov, Linux API, Matthew Wilcox (Oracle), Matt Turner, Max Filippov, Michael S. Tsirkin, Michal Hocko, Mike Kravetz, Minchan Kim, Oscar Salvador, Peter Xu, Ram Pai, Richard Henderson, Rik van Riel, Rolf Eike Beer, Shuah Khan, Thomas Bogendoerfer, Vlastimil Babka On Mon, 19 Apr 2021 15:54:38 +0200 David Hildenbrand <david@redhat.com> wrote: > Excessive details on MADV_POPULATE_(READ|WRITE) can be found in patch #2. I grabbed the series, but some additional review would help things along here.. Did patch #2 actually make it to linux-mm? It's missing from my archive. https://lkml.kernel.org/r/20210419135443.12822-3-david@redhat.com lands on the linux-api@vger copy. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables 2021-05-10 4:21 ` [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables Andrew Morton @ 2021-05-10 14:52 ` David Hildenbrand 2021-05-11 0:59 ` Andrew Morton 0 siblings, 1 reply; 8+ messages in thread From: David Hildenbrand @ 2021-05-10 14:52 UTC (permalink / raw) To: Andrew Morton Cc: linux-kernel, linux-mm, Andrea Arcangeli, Arnd Bergmann, Chris Zankel, Dave Hansen, Helge Deller, Hugh Dickins, Ivan Kokshaysky, James E.J. Bottomley, Jann Horn, Jason Gunthorpe, Kirill A. Shutemov, Linux API, Matthew Wilcox (Oracle), Matt Turner, Max Filippov, Michael S. Tsirkin, Michal Hocko, Mike Kravetz, Minchan Kim, Oscar Salvador, Peter Xu, Ram Pai, Richard Henderson, Rik van Riel, Rolf Eike Beer, Shuah Khan, Thomas Bogendoerfer, Vlastimil Babka On 10.05.21 06:21, Andrew Morton wrote: > On Mon, 19 Apr 2021 15:54:38 +0200 David Hildenbrand <david@redhat.com> wrote: > >> Excessive details on MADV_POPULATE_(READ|WRITE) can be found in patch #2. > > I grabbed the series, but some additional review would help things > along here.. Thanks -- indeed, while there have been some comments to previous versions that improved the series as a whole, there are no explicit acks or rbs. Fortunately, we still have some time until the next merge window opens :) > > Did patch #2 actually make it to linux-mm? It's missing from my > archive. Ehm, good point. I punch out everything via " git send-email --to linux-kernel@vger.kernel.org --cc "linux-mm@kvack.org" ..." and don't remember any bounces. Doesn't seem to appear on linux-mm: https://lore.kernel.org/linux-mm/20210419135443.12822-1-david@redhat.com/ But it did make it to lkml as well: https://lore.kernel.org/lkml/20210419135443.12822-3-david@redhat.com/ > https://lkml.kernel.org/r/20210419135443.12822-3-david@redhat.com lands > on the linux-api@vger copy. Weird, looks like linux-mm is swallowing mails. I can just resend the series, thoughts? -- Thanks, David / dhildenb ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables 2021-05-10 14:52 ` David Hildenbrand @ 2021-05-11 0:59 ` Andrew Morton 0 siblings, 0 replies; 8+ messages in thread From: Andrew Morton @ 2021-05-11 0:59 UTC (permalink / raw) To: David Hildenbrand Cc: linux-kernel, linux-mm, Andrea Arcangeli, Arnd Bergmann, Chris Zankel, Dave Hansen, Helge Deller, Hugh Dickins, Ivan Kokshaysky, James E.J. Bottomley, Jann Horn, Jason Gunthorpe, Kirill A. Shutemov, Linux API, Matthew Wilcox (Oracle), Matt Turner, Max Filippov, Michael S. Tsirkin, Michal Hocko, Mike Kravetz, Minchan Kim, Oscar Salvador, Peter Xu, Ram Pai, Richard Henderson, Rik van Riel, Rolf Eike Beer, Shuah Khan, Thomas Bogendoerfer, Vlastimil Babka On Mon, 10 May 2021 16:52:33 +0200 David Hildenbrand <david@redhat.com> wrote: > I can just resend the series, thoughts? Sure, that makes it easier on folks. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-05-11 0:59 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-04-19 13:54 [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 1/5] mm: make variable names for populate_vma_page_range() consistent David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 3/5] MAINTAINERS: add tools/testing/selftests/vm/ to MEMORY MANAGEMENT David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 4/5] selftests/vm: add protection_keys_32 / protection_keys_64 to gitignore David Hildenbrand 2021-04-19 13:54 ` [PATCH v2 5/5] selftests/vm: add test for MADV_POPULATE_(READ|WRITE) David Hildenbrand 2021-05-10 4:21 ` [PATCH v2 0/5] mm/madvise: introduce MADV_POPULATE_(READ|WRITE) to prefault page tables Andrew Morton 2021-05-10 14:52 ` David Hildenbrand 2021-05-11 0:59 ` Andrew Morton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).