Dynamically allocated buffers of PMD size for file-backed
THP operations (file_buf1 and file_buf2) were not freed on
the success path and some failure paths. Since the
function is called repeatedly in a loop for each split order,
this can cause significant memory leaks.
On architectures with large PMD sizes, repeated leaks
could exhaust system memory and trigger the OOM killer
during test execution.
Ensure all allocated buffers are freed to maintain
stable repeated test runs.
Fixes: 035a112e5fd5 ("selftests/mm: make file-backed THP split work by writing
PMD size data")
Reviewed-by: Zi Yan <[email protected]>
Tested-by: Venkat Rao Bagalkote <[email protected]>
Signed-off-by: Sayali Patil <[email protected]>
---
.../selftests/mm/split_huge_page_test.c | 22 ++++++++++++++-----
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/mm/split_huge_page_test.c
b/tools/testing/selftests/mm/split_huge_page_test.c
index 02938f38b880..ee256afecd8f 100644
--- a/tools/testing/selftests/mm/split_huge_page_test.c
+++ b/tools/testing/selftests/mm/split_huge_page_test.c
@@ -473,12 +473,15 @@ static void split_file_backed_thp(int order)
unsigned long size = 2 * pmd_pagesize;
char opts[64];
ssize_t num_written, num_read;
- char *file_buf1, *file_buf2;
+ char *file_buf1 = NULL, *file_buf2 = NULL;
uint64_t pgoff_start = 0, pgoff_end = 1024;
int i;
ksft_print_msg("Please enable pr_debug in split_huge_pages_in_file()
for more info.\n");
+ if (!tmpfs_loc)
+ ksft_exit_fail_msg("mkdtemp failed\n");
+
file_buf1 = (char *)malloc(pmd_pagesize);
file_buf2 = (char *)malloc(pmd_pagesize);
@@ -494,8 +497,10 @@ static void split_file_backed_thp(int order)
snprintf(opts, sizeof(opts), "huge=always,size=%lu", size);
status = mount("tmpfs", tmpfs_loc, "tmpfs", 0, opts);
- if (status)
- ksft_exit_fail_msg("Unable to create a tmpfs for testing\n");
+ if (status) {
+ ksft_print_msg("Unable to create a tmpfs for testing\n");
+ goto out;
+ }
status = snprintf(testfile, INPUT_MAX, "%s/thp_file", tmpfs_loc);
if (status >= INPUT_MAX) {
@@ -547,10 +552,13 @@ static void split_file_backed_thp(int order)
status = umount(tmpfs_loc);
if (status) {
- rmdir(tmpfs_loc);
- ksft_exit_fail_msg("Unable to umount %s\n", tmpfs_loc);
+ ksft_print_msg("Unable to umount %s\n", tmpfs_loc);
+ goto out;
}
+ free(file_buf1);
+ free(file_buf2);
+
status = rmdir(tmpfs_loc);
if (status)
ksft_exit_fail_msg("cannot remove tmp dir: %s\n",
strerror(errno));
@@ -563,8 +571,10 @@ static void split_file_backed_thp(int order)
close(fd);
cleanup:
umount(tmpfs_loc);
- rmdir(tmpfs_loc);
out:
+ free(file_buf1);
+ free(file_buf2);
+ rmdir(tmpfs_loc);
ksft_exit_fail_msg("Error occurred\n");
}
--
2.52.0