The patch titled Subject: hmm-tests: fix migrate_dirty_page test has been added to the -mm mm-unstable branch. Its filename is selftests-hmm-tests-add-test-for-dirty-bits-fix.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/selftests-hmm-tests-add-test-for-dirty-bits-fix.patch This patch will later appear in the mm-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there every 2-3 working days ------------------------------------------------------ From: Alistair Popple <apopple@xxxxxxxxxx> Subject: hmm-tests: fix migrate_dirty_page test Date: Wed, 14 Sep 2022 19:12:05 +1000 As noted by John Hubbard the original test relied on side effects of the implementation of migrate_vma_setup() to detect if pages had been swapped to disk or not. This is subject to change in future so explicitly check for swap entries via pagemap instead. Fix a spelling mistake while we're at it. Link: https://lkml.kernel.org/r/20220914091205.557676-1-apopple@xxxxxxxxxx Fixes: 5cc88e844e87 ("selftests/hmm-tests: add test for dirty bits") Signed-off-by: Alistair Popple <apopple@xxxxxxxxxx> Reviewed-by: Mika Penttilä <mpenttil@xxxxxxxxxx> Cc: Peter Xu <peterx@xxxxxxxxxx> Cc: Alex Sierra <alex.sierra@xxxxxxx> Cc: David Hildenbrand <david@xxxxxxxxxx> Cc: Jason Gunthorpe <jgg@xxxxxxxxxx> Cc: John Hubbard <jhubbard@xxxxxxxxxx> Cc: Logan Gunthorpe <logang@xxxxxxxxxxxx> Cc: Ralph Campbell <rcampbell@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- tools/testing/selftests/vm/Makefile | 1 tools/testing/selftests/vm/hmm-tests.c | 28 +++++++++++++++++++---- tools/testing/selftests/vm/vm_util.c | 22 ++++++++++++++++++ tools/testing/selftests/vm/vm_util.h | 2 + 4 files changed, 49 insertions(+), 4 deletions(-) --- a/tools/testing/selftests/vm/hmm-tests.c~selftests-hmm-tests-add-test-for-dirty-bits-fix +++ a/tools/testing/selftests/vm/hmm-tests.c @@ -33,6 +33,7 @@ */ #include "../../../../lib/test_hmm_uapi.h" #include "../../../../mm/gup_test.h" +#include "vm_util.h" struct hmm_buffer { void *ptr; @@ -1301,9 +1302,24 @@ static int destroy_cgroup(void) return 0; } +/* Returns true if at least one page in the range is on swap */ +static bool pages_swapped(void *ptr, size_t size) +{ + int fd = open("/proc/self/pagemap", O_RDONLY); + bool ret; + + if (fd < 0) + return false; + + ret = pagemap_range_some_swapped(fd, ptr, size); + close(fd); + + return ret; +} + /* * Try and migrate a dirty page that has previously been swapped to disk. This - * checks that we don't loose dirty bits. + * checks that we don't lose dirty bits. */ TEST_F(hmm, migrate_dirty_page) { @@ -1340,6 +1356,10 @@ TEST_F(hmm, migrate_dirty_page) ASSERT_FALSE(write_cgroup_param(cgroup, "memory.reclaim", 1UL<<30)); + /* Make sure at least some pages got paged to disk. */ + if (!pages_swapped(buffer->ptr, size)) + SKIP(return, "Pages weren't swapped when they should have been"); + /* Fault pages back in from swap as clean pages */ for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i) tmp += ptr[i]; @@ -1349,10 +1369,10 @@ TEST_F(hmm, migrate_dirty_page) ptr[i] = i; /* - * Attempt to migrate memory to device, which should fail because - * hopefully some pages are backed by swap storage. + * Attempt to migrate memory to device. This might fail if some pages + * are/were backed by swap but that's ok. */ - ASSERT_TRUE(hmm_migrate_sys_to_dev(self->fd, buffer, npages)); + hmm_migrate_sys_to_dev(self->fd, buffer, npages); ASSERT_FALSE(write_cgroup_param(cgroup, "memory.reclaim", 1UL<<30)); --- a/tools/testing/selftests/vm/Makefile~selftests-hmm-tests-add-test-for-dirty-bits-fix +++ a/tools/testing/selftests/vm/Makefile @@ -98,6 +98,7 @@ include ../lib.mk $(OUTPUT)/madv_populate: vm_util.c $(OUTPUT)/soft-dirty: vm_util.c $(OUTPUT)/split_huge_page_test: vm_util.c +$(OUTPUT)/hmm-tests: vm_util.c ifeq ($(MACHINE),x86_64) BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32)) --- a/tools/testing/selftests/vm/vm_util.c~selftests-hmm-tests-add-test-for-dirty-bits-fix +++ a/tools/testing/selftests/vm/vm_util.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include <unistd.h> #include <string.h> #include <fcntl.h> #include "../kselftest.h" @@ -20,6 +21,14 @@ uint64_t pagemap_get_entry(int fd, char return entry; } +bool pagemap_is_swapped(int fd, char *start) +{ + uint64_t entry = pagemap_get_entry(fd, start); + + // Check if swap entry bit (62nd bit) is set + return entry & 0x4000000000000000ull; +} + bool pagemap_is_softdirty(int fd, char *start) { uint64_t entry = pagemap_get_entry(fd, start); @@ -28,6 +37,19 @@ bool pagemap_is_softdirty(int fd, char * return entry & 0x0080000000000000ull; } +/* Returns true if at least one page in the range is in swap */ +bool pagemap_range_some_swapped(int fd, char *start, size_t len) +{ + unsigned long i; + unsigned long npages = len / getpagesize(); + + for (i = 0; i < npages; i++) + if (pagemap_is_swapped(fd, start + i * getpagesize())) + return true; + + return false; +} + void clear_softdirty(void) { int ret; --- a/tools/testing/selftests/vm/vm_util.h~selftests-hmm-tests-add-test-for-dirty-bits-fix +++ a/tools/testing/selftests/vm/vm_util.h @@ -4,6 +4,8 @@ uint64_t pagemap_get_entry(int fd, char *start); bool pagemap_is_softdirty(int fd, char *start); +bool pagemap_is_swapped(int fd, char *start); +bool pagemap_range_some_swapped(int fd, char *start, size_t len); void clear_softdirty(void); uint64_t read_pmd_pagesize(void); uint64_t check_huge(void *addr); _ Patches currently in -mm which might be from apopple@xxxxxxxxxx are selftests-hmm-tests-add-test-for-dirty-bits.patch selftests-hmm-tests-add-test-for-dirty-bits-fix.patch