blob: defa92ee42fc2b19891e8d3b09cd455ba814960c [file] [log] [blame]
From: xu xin <xu.xin16@zte.com.cn>
Subject: selftest-add-testing-unsharing-and-counting-ksm-zero-page-v6
Date: Fri, 10 Feb 2023 09:21:57 +0800 (CST)
v5->v6:
According to David's suggestions, the following changes are made:
1) Rename check_ksm_zero_pages_count() -> ksm_get_zero_pages(), and do the
comparison outside.
2) Open all global fd from main() rather than the test case.
3) Remove COW-related test codes and focus on explicit unmerging here.
4) Add some coments to explain why wait_two_full_scans is required.
5) Clean up some unneed changes.
Link: https://lkml.kernel.org/r/202302100921574141612@zte.com.cn
Signed-off-by: xu xin <xu.xin16@zte.com.cn>
Reviewed-by: Xiaokai Ran <ran.xiaokai@zte.com.cn>
Reviewed-by: Yang Yang <yang.yang29@zte.com.cn>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Xuexin Jiang <jiang.xuexin@zte.com.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
tools/testing/selftests/mm/ksm_functional_tests.c | 47 +++++-------
1 file changed, 20 insertions(+), 27 deletions(-)
--- a/tools/testing/selftests/mm/ksm_functional_tests.c~selftest-add-testing-unsharing-and-counting-ksm-zero-page-v6
+++ a/tools/testing/selftests/mm/ksm_functional_tests.c
@@ -24,6 +24,7 @@
#define KiB 1024u
#define MiB (1024 * KiB)
+#define PageSize (4 * KiB)
static int ksm_fd;
static int ksm_full_scans_fd;
@@ -59,9 +60,8 @@ static bool range_maps_duplicates(char *
return false;
}
-static bool check_ksm_zero_pages_count(unsigned long zero_size)
+static long ksm_get_zero_pages(void)
{
- unsigned long pages_expected = zero_size / (4 * KiB);
char buf[20];
ssize_t read_size;
unsigned long ksm_zero_pages;
@@ -72,7 +72,7 @@ static bool check_ksm_zero_pages_count(u
buf[read_size] = 0;
ksm_zero_pages = strtol(buf, NULL, 10);
- return ksm_zero_pages == pages_expected;
+ return ksm_zero_pages;
}
static long ksm_get_full_scans(void)
@@ -109,13 +109,7 @@ static inline int ksm_merge(void)
/* Wait for two full scans such that any possible merging happened. */
if (write(ksm_fd, "1", 1) != 1)
return -errno;
- return wait_two_full_scans();
-}
-static inline int make_cow(char *map, char val, unsigned long size)
-{
-
- memset(map, val, size);
return wait_two_full_scans();
}
@@ -129,6 +123,12 @@ static int unmerge_zero_page(char *start
return ret;
}
+ /*
+ * Wait for two full scans such that any possible unmerging of zero
+ * pages happened. Why? Because the unmerge action of zero pages is not
+ * done in the context of madvise(), but in the context of
+ * unshare_zero_pages() of the ksmd thread.
+ */
return wait_two_full_scans();
}
@@ -193,16 +193,15 @@ static void test_unmerge_zero_pages(void
{
const unsigned int size = 2 * MiB;
char *map;
+ unsigned long pages_expected;
ksft_print_msg("[RUN] %s\n", __func__);
/* Confirm the interfaces*/
- ksm_zero_pages_fd = open("/sys/kernel/mm/ksm/zero_pages_sharing", O_RDONLY);
if (ksm_zero_pages_fd < 0) {
ksft_test_result_skip("open(\"/sys/kernel/mm/ksm/zero_pages_sharing\") failed\n");
return;
}
- ksm_use_zero_pages_fd = open("/sys/kernel/mm/ksm/use_zero_pages", O_RDWR);
if (ksm_use_zero_pages_fd < 0) {
ksft_test_result_skip("open \"/sys/kernel/mm/ksm/use_zero_pages\" failed\n");
return;
@@ -214,27 +213,20 @@ static void test_unmerge_zero_pages(void
/* Mmap zero pages*/
map = mmap_and_merge_range(0x00, size);
+ if (map == MAP_FAILED)
+ return;
- /* Case 1: make Writing on ksm zero pages (COW) */
- if (make_cow(map, 0xcf, size / 2)) {
- ksft_test_result_fail("COW failed\n");
+ if (unmerge_zero_page(map + size / 2, size / 2))
goto unmap;
- }
- ksft_test_result(check_ksm_zero_pages_count(size / 2),
- "zero page count react to cow\n");
- /* Case 2: Call madvise(xxx, MADV_UNMERGEABLE)*/
- if (unmerge_zero_page(map + size / 2, size / 4)) {
- ksft_test_result_fail("unmerge_zero_page failed\n");
- goto unmap;
- }
- ksft_test_result(check_ksm_zero_pages_count(size / 4),
+ /* Check if zero_pages_sharing can be update correctly when unmerge */
+ pages_expected = (size / 2) / PageSize;
+ ksft_test_result(pages_expected == ksm_get_zero_pages(),
"zero page count react to unmerge\n");
- /*Check if ksm pages are really unmerged */
- ksft_test_result(!range_maps_duplicates(map + size / 2, size / 4),
+ /* Check if ksm zero pages are really unmerged */
+ ksft_test_result(!range_maps_duplicates(map + size / 2, size / 2),
"KSM zero pages were unmerged\n");
-
unmap:
munmap(map, size);
}
@@ -354,10 +346,11 @@ int main(int argc, char **argv)
ksm_full_scans_fd = open("/sys/kernel/mm/ksm/full_scans", O_RDONLY);
if (ksm_full_scans_fd < 0)
ksft_exit_skip("open(\"/sys/kernel/mm/ksm/full_scans\") failed\n");
-
pagemap_fd = open("/proc/self/pagemap", O_RDONLY);
if (pagemap_fd < 0)
ksft_exit_skip("open(\"/proc/self/pagemap\") failed\n");
+ ksm_zero_pages_fd = open("/sys/kernel/mm/ksm/zero_pages_sharing", O_RDONLY);
+ ksm_use_zero_pages_fd = open("/sys/kernel/mm/ksm/use_zero_pages", O_RDWR);
test_unmerge();
test_unmerge_zero_pages();
_