// SPDX-License-Identifier: GPL-2.0 /* * A test of splitting PMD THPs and PTE-mapped THPs from a specified virtual * address range in a process via <debugfs>/split_huge_pages interface.
*/
if (!check_huge_anon(one_page, 4, pmd_pagesize))
ksft_exit_fail_msg("No THP is allocated\n");
/* remap the first pagesize of first THP */
pte_mapped = mremap(one_page, pagesize, pagesize, MREMAP_MAYMOVE);
/* remap the Nth pagesize of Nth THP */ for (i = 1; i < 4; i++) {
pte_mapped2 = mremap(one_page + pmd_pagesize * i + pagesize * i,
pagesize, pagesize,
MREMAP_MAYMOVE|MREMAP_FIXED,
pte_mapped + pagesize * i); if (pte_mapped2 == MAP_FAILED)
ksft_exit_fail_msg("mremap failed: %s\n", strerror(errno));
}
/* smap does not show THPs after mremap, use kpageflags instead */
thp_size = 0; for (i = 0; i < pagesize * 4; i++) if (i % pagesize == 0 &&
is_backed_by_thp(&pte_mapped[i], pagemap_fd, kpageflags_fd))
thp_size++;
if (thp_size != 4)
ksft_exit_fail_msg("Some THPs are missing during mremap\n");
/* smap does not show THPs after mremap, use kpageflags instead */
thp_size = 0; for (i = 0; i < pagesize * 4; i++) { if (pte_mapped[i] != (char)i)
ksft_exit_fail_msg("%ld byte corrupted\n", i);
if (i % pagesize == 0 &&
is_backed_by_thp(&pte_mapped[i], pagemap_fd, kpageflags_fd))
thp_size++;
}
if (thp_size)
ksft_exit_fail_msg("Still %ld THPs not split\n", thp_size);
if (!*thp_fs_loc)
ksft_exit_fail_msg("cannot create temp folder\n");
returntrue;
}
void cleanup_thp_fs(constchar *thp_fs_loc, bool created_tmp)
{ int status;
if (!created_tmp) return;
status = rmdir(thp_fs_loc); if (status)
ksft_exit_fail_msg("cannot remove tmp dir: %s\n",
strerror(errno));
}
int create_pagecache_thp_and_fd(constchar *testfile, size_t fd_size, int *fd, char **addr)
{
size_t i; unsignedchar buf[1024];
srand(time(NULL));
*fd = open(testfile, O_CREAT | O_RDWR, 0664); if (*fd == -1)
ksft_exit_fail_msg("Failed to create a file at %s\n", testfile);
assert(fd_size % sizeof(buf) == 0); for (i = 0; i < sizeof(buf); i++)
buf[i] = (unsignedchar)i; for (i = 0; i < fd_size; i += sizeof(buf))
write(*fd, buf, sizeof(buf));
close(*fd);
sync();
*fd = open("/proc/sys/vm/drop_caches", O_WRONLY); if (*fd == -1) {
ksft_perror("open drop_caches"); goto err_out_unlink;
} if (write(*fd, "3", 1) != 1) {
ksft_perror("write to drop_caches"); goto err_out_unlink;
}
close(*fd);
*fd = open(testfile, O_RDWR); if (*fd == -1) {
ksft_perror("Failed to open testfile\n"); goto err_out_unlink;
}
for (i = 0; i < fd_size; i++) if (*(addr + i) != (char)i) {
ksft_print_msg("%lu byte corrupted in the file\n", i);
err = EXIT_FAILURE; goto out;
}
if (!check_huge_file(addr, 0, pmd_pagesize)) {
ksft_print_msg("Still FilePmdMapped not split\n");
err = EXIT_FAILURE; goto out;
}
out:
munmap(addr, fd_size);
close(fd);
unlink(testfile); if (offset == -1) { if (err)
ksft_exit_fail_msg("Split PMD-mapped pagecache folio to order %d failed\n", order);
ksft_test_result_pass("Split PMD-mapped pagecache folio to order %d passed\n", order);
} else { if (err)
ksft_exit_fail_msg("Split PMD-mapped pagecache folio to order %d at in-folio offset %d failed\n", order, offset);
ksft_test_result_pass("Split PMD-mapped pagecache folio to order %d at in-folio offset %d passed\n", order, offset);
}
}
int main(int argc, char **argv)
{ int i;
size_t fd_size; char *optional_xfs_path = NULL; char fs_loc_template[] = "/tmp/thp_fs_XXXXXX"; constchar *fs_loc; bool created_tmp; int offset;
ksft_print_header();
if (geteuid() != 0) {
ksft_print_msg("Please run the benchmark as root\n");
ksft_finished();
}
for (i = 0; i < 9; i++) if (i != 1)
split_pmd_thp_to_order(i);
split_pte_mapped_thp(); for (i = 0; i < 9; i++)
split_file_backed_thp(i);
created_tmp = prepare_thp_fs(optional_xfs_path, fs_loc_template,
&fs_loc); for (i = 8; i >= 0; i--)
split_thp_in_pagecache_to_order_at(fd_size, fs_loc, i, -1);
for (i = 0; i < 9; i++) for (offset = 0;
offset < pmd_pagesize / pagesize;
offset += MAX(pmd_pagesize / pagesize / 4, 1 << i))
split_thp_in_pagecache_to_order_at(fd_size, fs_loc, i, offset);
cleanup_thp_fs(fs_loc, created_tmp);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.