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. Signed-off-by: Alistair Popple <apopple@xxxxxxxxxx> Fixes: 5cc88e844e87 ("selftests/hmm-tests: add test for dirty bits") --- tools/testing/selftests/vm/hmm-tests.c | 50 +++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/vm/hmm-tests.c b/tools/testing/selftests/vm/hmm-tests.c index 70fdb49b59ed..b5f6a7dc1f12 100644 --- a/tools/testing/selftests/vm/hmm-tests.c +++ b/tools/testing/selftests/vm/hmm-tests.c @@ -1261,9 +1261,47 @@ static int destroy_cgroup(void) return 0; } +static uint64_t get_pfn(int fd, uint64_t ptr) +{ + uint64_t pfn; + int ret; + + ret = pread(fd, &pfn, sizeof(ptr), + (uint64_t) ptr / getpagesize() * sizeof(ptr)); + if (ret != sizeof(ptr)) + return 0; + + return pfn; +} + +#define PAGEMAP_SWAPPED (1ULL << 62) + +/* Returns true if at least one page in the range is on swap */ +static bool pages_swapped(void *ptr, unsigned long pages) +{ + uint64_t pfn; + int fd = open("/proc/self/pagemap", O_RDONLY); + unsigned long i; + + if (fd < 0) + return false; + + for (i = 0; i < pages; i++) { + pfn = get_pfn(fd, (uint64_t) ptr + i * getpagesize()); + + if (pfn & PAGEMAP_SWAPPED) { + close(fd); + return true; + } + } + + close(fd); + return false; +} + /* * 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) { @@ -1300,6 +1338,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, npages)) + 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]; @@ -1309,10 +1351,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)); -- 2.35.1