There are some general ksm operations could be used by other related test case. Put them into vm_util for common use.
This is a preparation patch for later use.
Signed-off-by: Wei Yang richard.weiyang@gmail.com Suggested-by: David Hildenbrand david@redhat.com Cc: David Hildenbrand david@redhat.com Cc: Lorenzo Stoakes lorenzo.stoakes@oracle.com Cc: Rik van Riel riel@surriel.com Cc: Liam R. Howlett Liam.Howlett@oracle.com Cc: Vlastimil Babka vbabka@suse.cz Cc: Harry Yoo harry.yoo@oracle.com --- .../selftests/mm/ksm_functional_tests.c | 76 +++---------------- tools/testing/selftests/mm/vm_util.c | 71 +++++++++++++++++ tools/testing/selftests/mm/vm_util.h | 7 ++ 3 files changed, 88 insertions(+), 66 deletions(-)
diff --git a/tools/testing/selftests/mm/ksm_functional_tests.c b/tools/testing/selftests/mm/ksm_functional_tests.c index b61803e36d1c..9fb79f6bf86d 100644 --- a/tools/testing/selftests/mm/ksm_functional_tests.c +++ b/tools/testing/selftests/mm/ksm_functional_tests.c @@ -73,74 +73,18 @@ static bool range_maps_duplicates(char *addr, unsigned long size) return false; }
-static long get_my_ksm_zero_pages(void) -{ - char buf[200]; - char *substr_ksm_zero; - size_t value_pos; - ssize_t read_size; - unsigned long my_ksm_zero_pages; - - if (!proc_self_ksm_stat_fd) - return 0; - - read_size = pread(proc_self_ksm_stat_fd, buf, sizeof(buf) - 1, 0); - if (read_size < 0) - return -errno; - - buf[read_size] = 0; - - substr_ksm_zero = strstr(buf, "ksm_zero_pages"); - if (!substr_ksm_zero) - return 0; - - value_pos = strcspn(substr_ksm_zero, "0123456789"); - my_ksm_zero_pages = strtol(substr_ksm_zero + value_pos, NULL, 10); - - return my_ksm_zero_pages; -} - -static long get_my_merging_pages(void) -{ - char buf[10]; - ssize_t ret; - - if (proc_self_ksm_merging_pages_fd < 0) - return proc_self_ksm_merging_pages_fd; - - ret = pread(proc_self_ksm_merging_pages_fd, buf, sizeof(buf) - 1, 0); - if (ret <= 0) - return -errno; - buf[ret] = 0; - - return strtol(buf, NULL, 10); -} - -static long ksm_get_full_scans(void) -{ - char buf[10]; - ssize_t ret; - - ret = pread(ksm_full_scans_fd, buf, sizeof(buf) - 1, 0); - if (ret <= 0) - return -errno; - buf[ret] = 0; - - return strtol(buf, NULL, 10); -} - static int ksm_merge(void) { long start_scans, end_scans;
/* Wait for two full scans such that any possible merging happened. */ - start_scans = ksm_get_full_scans(); + start_scans = ksm_get_full_scans(ksm_full_scans_fd); if (start_scans < 0) return start_scans; - if (write(ksm_fd, "1", 1) != 1) + if (ksm_start_and_merge(ksm_fd) != 1) return -errno; do { - end_scans = ksm_get_full_scans(); + end_scans = ksm_get_full_scans(ksm_full_scans_fd); if (end_scans < 0) return end_scans; } while (end_scans < start_scans + 2); @@ -150,7 +94,7 @@ static int ksm_merge(void)
static int ksm_unmerge(void) { - if (write(ksm_fd, "2", 1) != 1) + if (ksm_stop_and_unmerge(ksm_fd) != 1) return -errno; return 0; } @@ -168,7 +112,7 @@ static char *__mmap_and_merge_range(char val, unsigned long size, int prot, return err_map; }
- if (get_my_merging_pages() > 0) { + if (ksm_get_self_merging_pages(proc_self_ksm_merging_pages_fd) > 0) { ksft_print_msg("Still pages merged\n"); return err_map; } @@ -227,7 +171,7 @@ static char *__mmap_and_merge_range(char val, unsigned long size, int prot, * Check if anything was merged at all. Ignore the zero page that is * accounted differently (depending on kernel support). */ - if (val && !get_my_merging_pages()) { + if (val && !ksm_get_self_merging_pages(proc_self_ksm_merging_pages_fd)) { ksft_print_msg("No pages got merged\n"); goto unmap; } @@ -294,7 +238,7 @@ static void test_unmerge_zero_pages(void) ksft_test_result_skip("open "/sys/kernel/mm/ksm/use_zero_pages" failed\n"); return; } - if (write(ksm_use_zero_pages_fd, "1", 1) != 1) { + if (ksm_use_zero_pages(ksm_use_zero_pages_fd) != 1) { ksft_test_result_skip("write "/sys/kernel/mm/ksm/use_zero_pages" failed\n"); return; } @@ -306,7 +250,7 @@ static void test_unmerge_zero_pages(void)
/* Check if ksm_zero_pages is updated correctly after KSM merging */ pages_expected = size / pagesize; - if (pages_expected != get_my_ksm_zero_pages()) { + if (pages_expected != ksm_get_self_zero_pages(proc_self_ksm_stat_fd)) { ksft_test_result_fail("'ksm_zero_pages' updated after merging\n"); goto unmap; } @@ -319,7 +263,7 @@ static void test_unmerge_zero_pages(void)
/* Check if ksm_zero_pages is updated correctly after unmerging */ pages_expected /= 2; - if (pages_expected != get_my_ksm_zero_pages()) { + if (pages_expected != ksm_get_self_zero_pages(proc_self_ksm_stat_fd)) { ksft_test_result_fail("'ksm_zero_pages' updated after unmerging\n"); goto unmap; } @@ -329,7 +273,7 @@ static void test_unmerge_zero_pages(void) *((unsigned int *)&map[offs]) = offs;
/* Now we should have no zeropages remaining. */ - if (get_my_ksm_zero_pages()) { + if (ksm_get_self_zero_pages(proc_self_ksm_stat_fd)) { ksft_test_result_fail("'ksm_zero_pages' updated after write fault\n"); goto unmap; } diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c index 1357e2d6a7b6..115422e9eb68 100644 --- a/tools/testing/selftests/mm/vm_util.c +++ b/tools/testing/selftests/mm/vm_util.c @@ -486,3 +486,74 @@ int close_procmap(struct procmap_fd *procmap) { return close(procmap->fd); } + +int ksm_use_zero_pages(int ksm_use_zero_pages_fd) +{ + return write(ksm_use_zero_pages_fd, "1", 1); +} + +int ksm_start_and_merge(int ksm_fd) +{ + return write(ksm_fd, "1", 1); +} + +int ksm_stop_and_unmerge(int ksm_fd) +{ + return write(ksm_fd, "2", 1); +} + +long ksm_get_full_scans(int ksm_full_scans_fd) +{ + char buf[10]; + ssize_t ret; + + ret = pread(ksm_full_scans_fd, buf, sizeof(buf) - 1, 0); + if (ret <= 0) + return -errno; + buf[ret] = 0; + + return strtol(buf, NULL, 10); +} + +long ksm_get_self_merging_pages(int proc_self_ksm_merging_pages_fd) +{ + char buf[10]; + ssize_t ret; + + if (proc_self_ksm_merging_pages_fd < 0) + return proc_self_ksm_merging_pages_fd; + + ret = pread(proc_self_ksm_merging_pages_fd, buf, sizeof(buf) - 1, 0); + if (ret <= 0) + return -errno; + buf[ret] = 0; + + return strtol(buf, NULL, 10); +} + +long ksm_get_self_zero_pages(int proc_self_ksm_stat_fd) +{ + char buf[200]; + char *substr_ksm_zero; + size_t value_pos; + ssize_t read_size; + unsigned long my_ksm_zero_pages; + + if (!proc_self_ksm_stat_fd) + return 0; + + read_size = pread(proc_self_ksm_stat_fd, buf, sizeof(buf) - 1, 0); + if (read_size < 0) + return -errno; + + buf[read_size] = 0; + + substr_ksm_zero = strstr(buf, "ksm_zero_pages"); + if (!substr_ksm_zero) + return 0; + + value_pos = strcspn(substr_ksm_zero, "0123456789"); + my_ksm_zero_pages = strtol(substr_ksm_zero + value_pos, NULL, 10); + + return my_ksm_zero_pages; +} diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h index 9211ba640d9c..99c1b1aa1813 100644 --- a/tools/testing/selftests/mm/vm_util.h +++ b/tools/testing/selftests/mm/vm_util.h @@ -95,6 +95,13 @@ static inline int open_self_procmap(struct procmap_fd *procmap_out) return open_procmap(pid, procmap_out); }
+int ksm_use_zero_pages(int ksm_use_zero_pages_fd); +int ksm_start_and_merge(int ksm_fd); +int ksm_stop_and_unmerge(int ksm_fd); +long ksm_get_full_scans(int ksm_full_scans_fd); +long ksm_get_self_merging_pages(int proc_self_ksm_merging_pages_fd); +long ksm_get_self_zero_pages(int proc_self_ksm_stat_fd); + /* * On ppc64 this will only work with radix 2M hugepage size */