summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/vm/soft-dirty.c
diff options
context:
space:
mode:
authorSeongJae Park <sj@kernel.org>2023-01-03 18:07:53 +0000
committerAndrew Morton <akpm@linux-foundation.org>2023-01-18 17:12:56 -0800
commitbaa489fabd01596d5426d6e112b34ba5fb59ab82 (patch)
tree4647b2962ac3eee6a6bec6d9ed75a03df169ef68 /tools/testing/selftests/vm/soft-dirty.c
parent799fb82aa132fa3a3886b7872997a5a84e820062 (diff)
selftests/vm: rename selftests/vm to selftests/mm
Rename selftets/vm to selftests/mm for being more consistent with the code, documentation, and tools directories, and won't be confused with virtual machines. [sj@kernel.org: convert missing vm->mm changes] Link: https://lkml.kernel.org/r/20230107230643.252273-1-sj@kernel.org Link: https://lkml.kernel.org/r/20230103180754.129637-5-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Shuah Khan <shuah@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'tools/testing/selftests/vm/soft-dirty.c')
-rw-r--r--tools/testing/selftests/vm/soft-dirty.c210
1 files changed, 0 insertions, 210 deletions
diff --git a/tools/testing/selftests/vm/soft-dirty.c b/tools/testing/selftests/vm/soft-dirty.c
deleted file mode 100644
index 21d8830c5f24..000000000000
--- a/tools/testing/selftests/vm/soft-dirty.c
+++ /dev/null
@@ -1,210 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <malloc.h>
-#include <sys/mman.h>
-#include "../kselftest.h"
-#include "vm_util.h"
-
-#define PAGEMAP_FILE_PATH "/proc/self/pagemap"
-#define TEST_ITERATIONS 10000
-
-static void test_simple(int pagemap_fd, int pagesize)
-{
- int i;
- char *map;
-
- map = aligned_alloc(pagesize, pagesize);
- if (!map)
- ksft_exit_fail_msg("mmap failed\n");
-
- clear_softdirty();
-
- for (i = 0 ; i < TEST_ITERATIONS; i++) {
- if (pagemap_is_softdirty(pagemap_fd, map) == 1) {
- ksft_print_msg("dirty bit was 1, but should be 0 (i=%d)\n", i);
- break;
- }
-
- clear_softdirty();
- // Write something to the page to get the dirty bit enabled on the page
- map[0]++;
-
- if (pagemap_is_softdirty(pagemap_fd, map) == 0) {
- ksft_print_msg("dirty bit was 0, but should be 1 (i=%d)\n", i);
- break;
- }
-
- clear_softdirty();
- }
- free(map);
-
- ksft_test_result(i == TEST_ITERATIONS, "Test %s\n", __func__);
-}
-
-static void test_vma_reuse(int pagemap_fd, int pagesize)
-{
- char *map, *map2;
-
- map = mmap(NULL, pagesize, (PROT_READ | PROT_WRITE), (MAP_PRIVATE | MAP_ANON), -1, 0);
- if (map == MAP_FAILED)
- ksft_exit_fail_msg("mmap failed");
-
- // The kernel always marks new regions as soft dirty
- ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 1,
- "Test %s dirty bit of allocated page\n", __func__);
-
- clear_softdirty();
- munmap(map, pagesize);
-
- map2 = mmap(NULL, pagesize, (PROT_READ | PROT_WRITE), (MAP_PRIVATE | MAP_ANON), -1, 0);
- if (map2 == MAP_FAILED)
- ksft_exit_fail_msg("mmap failed");
-
- // Dirty bit is set for new regions even if they are reused
- if (map == map2)
- ksft_test_result(pagemap_is_softdirty(pagemap_fd, map2) == 1,
- "Test %s dirty bit of reused address page\n", __func__);
- else
- ksft_test_result_skip("Test %s dirty bit of reused address page\n", __func__);
-
- munmap(map2, pagesize);
-}
-
-static void test_hugepage(int pagemap_fd, int pagesize)
-{
- char *map;
- int i, ret;
- size_t hpage_len = read_pmd_pagesize();
-
- map = memalign(hpage_len, hpage_len);
- if (!map)
- ksft_exit_fail_msg("memalign failed\n");
-
- ret = madvise(map, hpage_len, MADV_HUGEPAGE);
- if (ret)
- ksft_exit_fail_msg("madvise failed %d\n", ret);
-
- for (i = 0; i < hpage_len; i++)
- map[i] = (char)i;
-
- if (check_huge_anon(map, 1, hpage_len)) {
- ksft_test_result_pass("Test %s huge page allocation\n", __func__);
-
- clear_softdirty();
- for (i = 0 ; i < TEST_ITERATIONS ; i++) {
- if (pagemap_is_softdirty(pagemap_fd, map) == 1) {
- ksft_print_msg("dirty bit was 1, but should be 0 (i=%d)\n", i);
- break;
- }
-
- clear_softdirty();
- // Write something to the page to get the dirty bit enabled on the page
- map[0]++;
-
- if (pagemap_is_softdirty(pagemap_fd, map) == 0) {
- ksft_print_msg("dirty bit was 0, but should be 1 (i=%d)\n", i);
- break;
- }
- clear_softdirty();
- }
-
- ksft_test_result(i == TEST_ITERATIONS, "Test %s huge page dirty bit\n", __func__);
- } else {
- // hugepage allocation failed. skip these tests
- ksft_test_result_skip("Test %s huge page allocation\n", __func__);
- ksft_test_result_skip("Test %s huge page dirty bit\n", __func__);
- }
- free(map);
-}
-
-static void test_mprotect(int pagemap_fd, int pagesize, bool anon)
-{
- const char *type[] = {"file", "anon"};
- const char *fname = "./soft-dirty-test-file";
- int test_fd;
- char *map;
-
- if (anon) {
- map = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
- MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
- if (!map)
- ksft_exit_fail_msg("anon mmap failed\n");
- } else {
- test_fd = open(fname, O_RDWR | O_CREAT);
- if (test_fd < 0) {
- ksft_test_result_skip("Test %s open() file failed\n", __func__);
- return;
- }
- unlink(fname);
- ftruncate(test_fd, pagesize);
- map = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
- MAP_SHARED, test_fd, 0);
- if (!map)
- ksft_exit_fail_msg("file mmap failed\n");
- }
-
- *map = 1;
- ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 1,
- "Test %s-%s dirty bit of new written page\n",
- __func__, type[anon]);
- clear_softdirty();
- ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 0,
- "Test %s-%s soft-dirty clear after clear_refs\n",
- __func__, type[anon]);
- mprotect(map, pagesize, PROT_READ);
- ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 0,
- "Test %s-%s soft-dirty clear after marking RO\n",
- __func__, type[anon]);
- mprotect(map, pagesize, PROT_READ|PROT_WRITE);
- ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 0,
- "Test %s-%s soft-dirty clear after marking RW\n",
- __func__, type[anon]);
- *map = 2;
- ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 1,
- "Test %s-%s soft-dirty after rewritten\n",
- __func__, type[anon]);
-
- munmap(map, pagesize);
-
- if (!anon)
- close(test_fd);
-}
-
-static void test_mprotect_anon(int pagemap_fd, int pagesize)
-{
- test_mprotect(pagemap_fd, pagesize, true);
-}
-
-static void test_mprotect_file(int pagemap_fd, int pagesize)
-{
- test_mprotect(pagemap_fd, pagesize, false);
-}
-
-int main(int argc, char **argv)
-{
- int pagemap_fd;
- int pagesize;
-
- ksft_print_header();
- ksft_set_plan(15);
-
- pagemap_fd = open(PAGEMAP_FILE_PATH, O_RDONLY);
- if (pagemap_fd < 0)
- ksft_exit_fail_msg("Failed to open %s\n", PAGEMAP_FILE_PATH);
-
- pagesize = getpagesize();
-
- test_simple(pagemap_fd, pagesize);
- test_vma_reuse(pagemap_fd, pagesize);
- test_hugepage(pagemap_fd, pagesize);
- test_mprotect_anon(pagemap_fd, pagesize);
- test_mprotect_file(pagemap_fd, pagesize);
-
- close(pagemap_fd);
-
- return ksft_exit_pass();
-}