From patchwork Mon Jan 15 07:32:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muhammad Usama Anjum X-Patchwork-Id: 13519357 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9541663AA; Mon, 15 Jan 2024 07:33:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="GXO9YEPS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1705303984; bh=rRQZLwAtR4o/VCOAcxTzVSxdZ70bLgI9faWJJSJCsAc=; h=From:To:Cc:Subject:Date:From; b=GXO9YEPS9ah8KzQBBmYq2zTQ8EXx61CYFKebrzMonKYCXxDbjWZTjw7hHmB00Irk4 qG4tgLvhIH/RZlwBB/Us60q5DJWpt+EgCDQiD6mj3stX0zVEiIBZPXAXOkz1OebYVi SWvpwFyk+zxxpuufBiddr/mgfEpmFBKEhnhpB5H+LjpQm9rGth+Nqnlsem98XSw+84 edi3gQdsTxJwMcFw71BUCVdkhtPOunql0K3TLyAnOmek8pRNGhSqpvSMW9b6zyC0YA sHvs+MzaU9+NKaVOM/0ZAwvcaaygPhcB24md/WrHWhslctzLv4F51+qv6Iiq8Efqrr 8jtdxvayhgIIA== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: usama.anjum) by madrid.collaboradmins.com (Postfix) with ESMTPSA id DFFA737813DD; Mon, 15 Jan 2024 07:33:02 +0000 (UTC) From: Muhammad Usama Anjum To: Andrew Morton , Shuah Khan Cc: Muhammad Usama Anjum , kernel@collabora.com, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/7] selftests/mm: hugepage-shm: conform test to TAP format output Date: Mon, 15 Jan 2024 12:32:37 +0500 Message-ID: <20240115073247.1280266-1-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Conform the layout, informational and status messages to TAP. No functional change is intended other than the layout of output messages. The "." was being printed inside for loop to indicate the writes progress. This was extraneous and hence removed in the patch. Signed-off-by: Muhammad Usama Anjum --- tools/testing/selftests/mm/hugepage-shm.c | 47 +++++++++++------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/tools/testing/selftests/mm/hugepage-shm.c b/tools/testing/selftests/mm/hugepage-shm.c index 478bb1e989e9..f949dbbc3454 100644 --- a/tools/testing/selftests/mm/hugepage-shm.c +++ b/tools/testing/selftests/mm/hugepage-shm.c @@ -34,11 +34,10 @@ #include #include #include +#include "../kselftest.h" #define LENGTH (256UL*1024*1024) -#define dprintf(x) printf(x) - /* Only ia64 requires this */ #ifdef __ia64__ #define ADDR (void *)(0x8000000000000000UL) @@ -54,44 +53,42 @@ int main(void) unsigned long i; char *shmaddr; + ksft_print_header(); + ksft_set_plan(1); + shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W); - if (shmid < 0) { - perror("shmget"); - exit(1); - } - printf("shmid: 0x%x\n", shmid); + if (shmid < 0) + ksft_exit_fail_msg("shmget: %s\n", strerror(errno)); + + ksft_print_msg("shmid: 0x%x\n", shmid); shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS); if (shmaddr == (char *)-1) { - perror("Shared memory attach failure"); shmctl(shmid, IPC_RMID, NULL); - exit(2); + ksft_exit_fail_msg("Shared memory attach failure: %s\n", strerror(errno)); } - printf("shmaddr: %p\n", shmaddr); - dprintf("Starting the writes:\n"); - for (i = 0; i < LENGTH; i++) { + ksft_print_msg("shmaddr: %p\n", shmaddr); + + ksft_print_msg("Starting the writes:"); + for (i = 0; i < LENGTH; i++) shmaddr[i] = (char)(i); - if (!(i % (1024 * 1024))) - dprintf("."); - } - dprintf("\n"); + ksft_print_msg("Done.\n"); - dprintf("Starting the Check..."); + ksft_print_msg("Starting the Check..."); for (i = 0; i < LENGTH; i++) - if (shmaddr[i] != (char)i) { - printf("\nIndex %lu mismatched\n", i); - exit(3); - } - dprintf("Done.\n"); + if (shmaddr[i] != (char)i) + ksft_exit_fail_msg("\nIndex %lu mismatched\n", i); + ksft_print_msg("Done.\n"); if (shmdt((const void *)shmaddr) != 0) { - perror("Detach failure"); shmctl(shmid, IPC_RMID, NULL); - exit(4); + ksft_exit_fail_msg("Detach failure: %s\n", strerror(errno)); } shmctl(shmid, IPC_RMID, NULL); - return 0; + ksft_test_result_pass("Completed test\n"); + + ksft_finished(); } From patchwork Mon Jan 15 07:32:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muhammad Usama Anjum X-Patchwork-Id: 13519358 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73ABF4401; Mon, 15 Jan 2024 07:33:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="USadmbn7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1705303986; bh=o1IUw1D3iI8Y90Z4hsu7JwinzA97QoWLS2TEa1p944o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=USadmbn7PKHWToYkvjVZ3AC9iI/3+wePMhbl5oyp9VALBYEYxXCLsmpwTUDdZ7qch pK15+SiFt97hasoGzAIIIMuSTPRsKI/c8mB3YgKxiYlaJ6x0JFKwqFUuJ7oS804wgq iwbR39xeZxL6mbejPq19dqYziJSfQPiHUtJQnESxPB1pZpOICzFN5GxlMNiTkgb/AT 3T+VM2viAh8oKC+WjyMZsC+SX2WE/u9a/zm96hYFKMKXUqxVn9maqbdb7IPBFJ7kUy wSq2OwCGeWVhc/TcF3igjZU99k/C1a+8W/wv2CTSA7UjMNocOR/JUSZ74UGeiMe+QD vv/XSvNU81h+Q== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: usama.anjum) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 374EF3781F80; Mon, 15 Jan 2024 07:33:05 +0000 (UTC) From: Muhammad Usama Anjum To: Andrew Morton , Shuah Khan Cc: Muhammad Usama Anjum , kernel@collabora.com, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 2/7] selftests/mm: hugepage-vmemmap: conform test to TAP format output Date: Mon, 15 Jan 2024 12:32:38 +0500 Message-ID: <20240115073247.1280266-2-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240115073247.1280266-1-usama.anjum@collabora.com> References: <20240115073247.1280266-1-usama.anjum@collabora.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Conform the layout, informational and status messages to TAP. No functional change is intended other than the layout of output messages. Signed-off-by: Muhammad Usama Anjum --- tools/testing/selftests/mm/hugepage-vmemmap.c | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/tools/testing/selftests/mm/hugepage-vmemmap.c b/tools/testing/selftests/mm/hugepage-vmemmap.c index 5b354c209e93..125b96a65286 100644 --- a/tools/testing/selftests/mm/hugepage-vmemmap.c +++ b/tools/testing/selftests/mm/hugepage-vmemmap.c @@ -10,6 +10,7 @@ #include #include #include +#include "../kselftest.h" #define MAP_LENGTH (2UL * 1024 * 1024) @@ -77,7 +78,7 @@ static int check_page_flags(unsigned long pfn) read(fd, &pageflags, sizeof(pageflags)); if ((pageflags & HEAD_PAGE_FLAGS) != HEAD_PAGE_FLAGS) { close(fd); - printf("Head page flags (%lx) is invalid\n", pageflags); + ksft_print_msg("Head page flags (%lx) is invalid\n", pageflags); return -1; } @@ -91,7 +92,7 @@ static int check_page_flags(unsigned long pfn) if ((pageflags & TAIL_PAGE_FLAGS) != TAIL_PAGE_FLAGS || (pageflags & HEAD_PAGE_FLAGS) == HEAD_PAGE_FLAGS) { close(fd); - printf("Tail page flags (%lx) is invalid\n", pageflags); + ksft_print_msg("Tail page flags (%lx) is invalid\n", pageflags); return -1; } } @@ -106,11 +107,12 @@ int main(int argc, char **argv) void *addr; unsigned long pfn; + ksft_print_header(); + ksft_set_plan(1); + addr = mmap(MAP_ADDR, MAP_LENGTH, PROT_READ | PROT_WRITE, MAP_FLAGS, -1, 0); - if (addr == MAP_FAILED) { - perror("mmap"); - exit(1); - } + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); /* Trigger allocation of HugeTLB page. */ write_bytes(addr, MAP_LENGTH); @@ -118,23 +120,19 @@ int main(int argc, char **argv) pfn = virt_to_pfn(addr); if (pfn == -1UL) { munmap(addr, MAP_LENGTH); - perror("virt_to_pfn"); - exit(1); + ksft_exit_fail_msg("virt_to_pfn: %s\n", strerror(errno)); + } else if (!pfn && geteuid()) { + ksft_test_result_skip("Unable to read the pfn as non-root user\n"); + ksft_finished(); } - printf("Returned address is %p whose pfn is %lx\n", addr, pfn); + ksft_print_msg("Returned address is %p whose pfn is %lx\n", addr, pfn); - if (check_page_flags(pfn) < 0) { - munmap(addr, MAP_LENGTH); - perror("check_page_flags"); - exit(1); - } + ksft_test_result(!check_page_flags(pfn), "Check page flags\n"); /* munmap() length of MAP_HUGETLB memory must be hugepage aligned */ - if (munmap(addr, MAP_LENGTH)) { - perror("munmap"); - exit(1); - } + if (munmap(addr, MAP_LENGTH)) + ksft_exit_fail_msg("munmap: %s\n", strerror(errno)); - return 0; + ksft_finished(); } From patchwork Mon Jan 15 07:32:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muhammad Usama Anjum X-Patchwork-Id: 13519359 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFFFB63CD; Mon, 15 Jan 2024 07:33:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="bEEgo7HG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1705303989; bh=COa40clGVU4MtL/28A+nBi1NMczqiOUny8LpI5UZWfU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bEEgo7HGnMtriol9Cd1RJNxtLlrNO61myA2FuEQXp1QrZaHHwOlJwKdRf0woPTJrQ EzOMqOV0/DiLwbYUjcch0Sn33IF1C9PXgFuZTBSklaWYzJ3SVAskbc6RPU1//jBIHl D7ZkMqsFNknuVt8UwGpgEIrfnXX0c9nfqfwWqa8lpSNLToehXX1ctahdM1BXuukhhQ llmc3tjHgK4Xh45GAltOdyOOZ4a3JRdkk1+dPNeTOcmAJg1ocKp4K/MpL6ZJpXpOu5 Y8/19GDVFw4g7eMS43kbqMTqLk9wf8Z1bfGFm/OekYLSAtGRBkJsy4QT/zQ1GFwu03 mLliwihyi1rVw== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: usama.anjum) by madrid.collaboradmins.com (Postfix) with ESMTPSA id BD6BE3781FFD; Mon, 15 Jan 2024 07:33:07 +0000 (UTC) From: Muhammad Usama Anjum To: Andrew Morton , Shuah Khan Cc: Muhammad Usama Anjum , kernel@collabora.com, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/7] selftests/mm: hugetlb-madvise: conform test to TAP format output Date: Mon, 15 Jan 2024 12:32:39 +0500 Message-ID: <20240115073247.1280266-3-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240115073247.1280266-1-usama.anjum@collabora.com> References: <20240115073247.1280266-1-usama.anjum@collabora.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Conform the layout, informational and status messages to TAP. No functional change is intended other than the layout of output messages. Signed-off-by: Muhammad Usama Anjum --- tools/testing/selftests/mm/hugetlb-madvise.c | 209 +++++++------------ 1 file changed, 81 insertions(+), 128 deletions(-) diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c index f32d99565c5e..4848200f801f 100644 --- a/tools/testing/selftests/mm/hugetlb-madvise.c +++ b/tools/testing/selftests/mm/hugetlb-madvise.c @@ -19,19 +19,14 @@ #include #include #include "vm_util.h" +#include "../kselftest.h" #define MIN_FREE_PAGES 20 #define NR_HUGE_PAGES 10 /* common number of pages to map/allocate */ -#define validate_free_pages(exp_free) \ - do { \ - int fhp = get_free_hugepages(); \ - if (fhp != (exp_free)) { \ - printf("Unexpected number of free huge " \ - "pages line %d\n", __LINE__); \ - exit(1); \ - } \ - } while (0) +#define validate_free_pages(exp_free) \ + ksft_test_result(get_free_hugepages() == (exp_free), \ + "Validation of free pages (%d)\n", __LINE__) unsigned long huge_page_size; unsigned long base_page_size; @@ -64,28 +59,27 @@ int main(int argc, char **argv) int fd; int ret; + ksft_print_header(); + huge_page_size = default_huge_page_size(); - if (!huge_page_size) { - printf("Unable to determine huge page size, exiting!\n"); - exit(1); - } + if (!huge_page_size) + ksft_exit_fail_msg("Unable to determine huge page size, exiting!\n"); + base_page_size = sysconf(_SC_PAGE_SIZE); - if (!huge_page_size) { - printf("Unable to determine base page size, exiting!\n"); - exit(1); - } + if (!huge_page_size) + ksft_exit_fail_msg("Unable to determine base page size, exiting!\n"); free_hugepages = get_free_hugepages(); if (free_hugepages < MIN_FREE_PAGES) { - printf("Not enough free huge pages to test, exiting!\n"); - exit(1); + ksft_print_msg("Not enough free huge pages to test, exiting!\n"); + ksft_finished(); } fd = memfd_create(argv[0], MFD_HUGETLB); - if (fd < 0) { - perror("memfd_create() failed"); - exit(1); - } + if (fd < 0) + ksft_exit_fail_msg("memfd_create() failed\n"); + + ksft_set_plan(37); /* * Test validity of MADV_DONTNEED addr and length arguments. mmap @@ -97,16 +91,13 @@ int main(int argc, char **argv) PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); - if (addr == MAP_FAILED) { - perror("mmap"); - exit(1); - } + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); + if (munmap(addr, huge_page_size) || - munmap(addr + (NR_HUGE_PAGES + 1) * huge_page_size, - huge_page_size)) { - perror("munmap"); - exit(1); - } + munmap(addr + (NR_HUGE_PAGES + 1) * huge_page_size, huge_page_size)) + ksft_exit_fail_msg("munmap: %s\n", strerror(errno)); + addr = addr + huge_page_size; write_fault_pages(addr, NR_HUGE_PAGES); @@ -114,21 +105,13 @@ int main(int argc, char **argv) /* addr before mapping should fail */ ret = madvise(addr - base_page_size, NR_HUGE_PAGES * huge_page_size, - MADV_DONTNEED); - if (!ret) { - printf("Unexpected success of madvise call with invalid addr line %d\n", - __LINE__); - exit(1); - } + MADV_DONTNEED); + ksft_test_result(ret, "The madvise call with invalid address\n"); /* addr + length after mapping should fail */ ret = madvise(addr, (NR_HUGE_PAGES * huge_page_size) + base_page_size, - MADV_DONTNEED); - if (!ret) { - printf("Unexpected success of madvise call with invalid length line %d\n", - __LINE__); - exit(1); - } + MADV_DONTNEED); + ksft_test_result(ret, "The madvise call with invalid address\n"); (void)munmap(addr, NR_HUGE_PAGES * huge_page_size); @@ -139,10 +122,9 @@ int main(int argc, char **argv) PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); - if (addr == MAP_FAILED) { - perror("mmap"); - exit(1); - } + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); + write_fault_pages(addr, NR_HUGE_PAGES); validate_free_pages(free_hugepages - NR_HUGE_PAGES); @@ -150,19 +132,12 @@ int main(int argc, char **argv) ret = madvise(addr + base_page_size, NR_HUGE_PAGES * huge_page_size - base_page_size, MADV_DONTNEED); - if (!ret) { - printf("Unexpected success of madvise call with unaligned start address %d\n", - __LINE__); - exit(1); - } + ksft_test_result(ret, "The madvise call with unaligned start address\n"); /* addr + length should be aligned down to huge page size */ - if (madvise(addr, - ((NR_HUGE_PAGES - 1) * huge_page_size) + base_page_size, - MADV_DONTNEED)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr, ((NR_HUGE_PAGES - 1) * huge_page_size) + base_page_size, + MADV_DONTNEED); + ksft_test_result(!ret, "The madvise call with aligned start address\n"); /* should free all but last page in mapping */ validate_free_pages(free_hugepages - 1); @@ -177,17 +152,14 @@ int main(int argc, char **argv) PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); - if (addr == MAP_FAILED) { - perror("mmap"); - exit(1); - } + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); + write_fault_pages(addr, NR_HUGE_PAGES); validate_free_pages(free_hugepages - NR_HUGE_PAGES); - if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED); + ksft_test_result(!ret, "The madvise MADV_DONTNEED on anonymous private mapping\n"); /* should free all pages in mapping */ validate_free_pages(free_hugepages); @@ -197,29 +169,25 @@ int main(int argc, char **argv) /* * Test MADV_DONTNEED on private mapping of hugetlb file */ - if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) { - perror("fallocate"); - exit(1); - } + if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) + ksft_exit_fail_msg("fallocate: %s\n", strerror(errno)); + validate_free_pages(free_hugepages - NR_HUGE_PAGES); addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (addr == MAP_FAILED) { - perror("mmap"); - exit(1); - } + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); /* read should not consume any pages */ read_fault_pages(addr, NR_HUGE_PAGES); validate_free_pages(free_hugepages - NR_HUGE_PAGES); /* madvise should not free any pages */ - if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED); + ksft_test_result(!ret, "The madvise MADV_DONTNEED on private mapping of file\n"); + validate_free_pages(free_hugepages - NR_HUGE_PAGES); /* writes should allocate private pages */ @@ -227,10 +195,9 @@ int main(int argc, char **argv) validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES)); /* madvise should free private pages */ - if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED); + ksft_test_result(!ret, "The madvise MADV_DONTNEED on private mapping of file\n"); + validate_free_pages(free_hugepages - NR_HUGE_PAGES); /* writes should allocate private pages */ @@ -245,10 +212,9 @@ int main(int argc, char **argv) * implementation. */ if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, - 0, NR_HUGE_PAGES * huge_page_size)) { - perror("fallocate"); - exit(1); - } + 0, NR_HUGE_PAGES * huge_page_size)) + ksft_exit_fail_msg("fallocate: %s\n", strerror(errno)); + validate_free_pages(free_hugepages); (void)munmap(addr, NR_HUGE_PAGES * huge_page_size); @@ -256,29 +222,25 @@ int main(int argc, char **argv) /* * Test MADV_DONTNEED on shared mapping of hugetlb file */ - if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) { - perror("fallocate"); - exit(1); - } + if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) + ksft_exit_fail_msg("fallocate: %s\n", strerror(errno)); + validate_free_pages(free_hugepages - NR_HUGE_PAGES); addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (addr == MAP_FAILED) { - perror("mmap"); - exit(1); - } + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); /* write should not consume any pages */ write_fault_pages(addr, NR_HUGE_PAGES); validate_free_pages(free_hugepages - NR_HUGE_PAGES); /* madvise should not free any pages */ - if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED); + ksft_test_result(!ret, "The madvise MADV_DONTNEED on shared mapping of file\n"); + validate_free_pages(free_hugepages - NR_HUGE_PAGES); /* @@ -286,29 +248,25 @@ int main(int argc, char **argv) * * madvise is same as hole punch and should free all pages. */ - if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE); + ksft_test_result(!ret, "The madvise MADV_REMOVE on shared mapping of file\n"); + validate_free_pages(free_hugepages); (void)munmap(addr, NR_HUGE_PAGES * huge_page_size); /* * Test MADV_REMOVE on shared and private mapping of hugetlb file */ - if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) { - perror("fallocate"); - exit(1); - } + if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) + ksft_exit_fail_msg("fallocate: %s\n", strerror(errno)); + validate_free_pages(free_hugepages - NR_HUGE_PAGES); addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (addr == MAP_FAILED) { - perror("mmap"); - exit(1); - } + if (addr == MAP_FAILED) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); /* shared write should not consume any additional pages */ write_fault_pages(addr, NR_HUGE_PAGES); @@ -317,10 +275,8 @@ int main(int argc, char **argv) addr2 = mmap(NULL, NR_HUGE_PAGES * huge_page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (addr2 == MAP_FAILED) { - perror("mmap"); - exit(1); - } + if (addr2 == MAP_FAILED) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); /* private read should not consume any pages */ read_fault_pages(addr2, NR_HUGE_PAGES); @@ -331,17 +287,15 @@ int main(int argc, char **argv) validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES)); /* madvise of shared mapping should not free any pages */ - if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED); + ksft_test_result(!ret, "The madvise MADV_REMOVE on shared mapping of file\n"); + validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES)); /* madvise of private mapping should free private pages */ - if (madvise(addr2, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr2, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED); + ksft_test_result(!ret, "The madvise MADV_REMOVE on shared mapping of file\n"); + validate_free_pages(free_hugepages - NR_HUGE_PAGES); /* private write should consume additional pages again */ @@ -353,15 +307,14 @@ int main(int argc, char **argv) * not correct. private pages should not be freed, but this is * expected. See comment associated with FALLOC_FL_PUNCH_HOLE call. */ - if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE)) { - perror("madvise"); - exit(1); - } + ret = madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE); + ksft_test_result(!ret, "The madvise MADV_REMOVE on shared mapping of file\n"); + validate_free_pages(free_hugepages); (void)munmap(addr, NR_HUGE_PAGES * huge_page_size); (void)munmap(addr2, NR_HUGE_PAGES * huge_page_size); close(fd); - return 0; + ksft_finished(); } From patchwork Mon Jan 15 07:32:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muhammad Usama Anjum X-Patchwork-Id: 13519360 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A20F6FCB; Mon, 15 Jan 2024 07:33:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="FJ1N931l" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1705303992; bh=x95njlqcj7Ctu5rRRl6h+bq3s3A6UrpoFAMvZnhMMTE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FJ1N931l4/P+j5HXVCBERxU+E15a2xZhXob5wQ9MpxOyk0aRB1DNbvHqCYt+eTh52 38JGemZsNb+pWaE3Dg39ORyQ2Gf4StE1lC7O38G1G6ihwFWzJdaiMFoKEq5KdWoRSC U1ZoYC6b+Gr+PkHsiT+UYY/mzVUaOLDBI0Fm03heFrVKy+IU8cZnntRafjo9mPgK2E WrS2qKzDIQMm2AHTswSSyY4BPgIdlSEX577MxmjwRXMuCWi0Uh8dDnbv4IwwpbnWkE lZxOSwr5OTX1aZhcLkp3IewWpUgPJm3yaHukMV7fqlUgXA/rUQJY+DiYdmu4lr4JLe uVd4CiNmJMmuw== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: usama.anjum) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 6336337813DD; Mon, 15 Jan 2024 07:33:10 +0000 (UTC) From: Muhammad Usama Anjum To: Andrew Morton , Shuah Khan Cc: Muhammad Usama Anjum , kernel@collabora.com, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 4/7] selftests/mm: khugepaged: conform test to TAP format output Date: Mon, 15 Jan 2024 12:32:40 +0500 Message-ID: <20240115073247.1280266-4-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240115073247.1280266-1-usama.anjum@collabora.com> References: <20240115073247.1280266-1-usama.anjum@collabora.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Conform the layout, informational and status messages to TAP. No functional change is intended other than the layout of output messages. Signed-off-by: Muhammad Usama Anjum --- Changes since v1: - Remove commented out lines of code --- tools/testing/selftests/mm/khugepaged.c | 381 ++++++++++-------------- 1 file changed, 159 insertions(+), 222 deletions(-) diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c index 829320a519e7..ec8b5cf36ad3 100644 --- a/tools/testing/selftests/mm/khugepaged.c +++ b/tools/testing/selftests/mm/khugepaged.c @@ -23,6 +23,7 @@ #include "vm_util.h" #include "thp_settings.h" +#include "../kselftest.h" #define BASE_ADDR ((void *)(1UL << 30)) static unsigned long hpage_pmd_size; @@ -73,22 +74,20 @@ struct file_info { static struct file_info finfo; static bool skip_settings_restore; -static int exit_status; static void success(const char *msg) { - printf(" \e[32m%s\e[0m\n", msg); + ksft_test_result_pass("%s\n", msg); } static void fail(const char *msg) { - printf(" \e[31m%s\e[0m\n", msg); - exit_status++; + ksft_test_result_fail("%s\n", msg); } static void skip(const char *msg) { - printf(" \e[33m%s\e[0m\n", msg); + ksft_test_result_skip("\e%s\n", msg); } static void restore_settings_atexit(void) @@ -96,9 +95,8 @@ static void restore_settings_atexit(void) if (skip_settings_restore) return; - printf("Restore THP and khugepaged settings..."); thp_restore_settings(); - success("OK"); + ksft_print_msg("Restored THP and khugepaged settings...\n"); skip_settings_restore = true; } @@ -106,12 +104,12 @@ static void restore_settings_atexit(void) static void restore_settings(int sig) { /* exit() will invoke the restore_settings_atexit handler. */ - exit(sig ? EXIT_FAILURE : exit_status); + ksft_finished(); } static void save_settings(void) { - printf("Save THP and khugepaged settings..."); + ksft_print_msg("Save THP and khugepaged settings...\n"); if (file_ops && finfo.type == VMA_FILE) thp_set_read_ahead_path(finfo.dev_queue_read_ahead_path); thp_save_settings(); @@ -135,60 +133,50 @@ static void get_finfo(const char *dir) finfo.dir = dir; stat(finfo.dir, &path_stat); - if (!S_ISDIR(path_stat.st_mode)) { - printf("%s: Not a directory (%s)\n", __func__, finfo.dir); - exit(EXIT_FAILURE); - } + if (!S_ISDIR(path_stat.st_mode)) + ksft_exit_fail_msg("%s: Not a directory (%s)\n", __func__, finfo.dir); + if (snprintf(finfo.path, sizeof(finfo.path), "%s/" TEST_FILE, - finfo.dir) >= sizeof(finfo.path)) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } - if (statfs(finfo.dir, &fs)) { - perror("statfs()"); - exit(EXIT_FAILURE); - } + finfo.dir) >= sizeof(finfo.path)) + ksft_exit_fail_msg("%s: Pathname is too long\n", __func__); + + if (statfs(finfo.dir, &fs)) + ksft_exit_fail_msg("statfs(): %s\n", strerror(errno)); + finfo.type = fs.f_type == TMPFS_MAGIC ? VMA_SHMEM : VMA_FILE; if (finfo.type == VMA_SHMEM) return; /* Find owning device's queue/read_ahead_kb control */ if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/uevent", - major(path_stat.st_dev), minor(path_stat.st_dev)) - >= sizeof(path)) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } - if (read_file(path, buf, sizeof(buf)) < 0) { - perror("read_file(read_num)"); - exit(EXIT_FAILURE); - } + major(path_stat.st_dev), minor(path_stat.st_dev)) >= sizeof(path)) + ksft_exit_fail_msg("%s: Pathname is too long\n", __func__); + + if (read_file(path, buf, sizeof(buf)) < 0) + ksft_exit_fail_msg("read_file(read_num): %s\n", strerror(errno)); + if (strstr(buf, "DEVTYPE=disk")) { /* Found it */ if (snprintf(finfo.dev_queue_read_ahead_path, sizeof(finfo.dev_queue_read_ahead_path), "/sys/dev/block/%d:%d/queue/read_ahead_kb", major(path_stat.st_dev), minor(path_stat.st_dev)) - >= sizeof(finfo.dev_queue_read_ahead_path)) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } + >= sizeof(finfo.dev_queue_read_ahead_path)) + ksft_exit_fail_msg("%s: Pathname is too long: %s\n", __func__, + strerror(errno)); return; } - if (!strstr(buf, "DEVTYPE=partition")) { - printf("%s: Unknown device type: %s\n", __func__, path); - exit(EXIT_FAILURE); - } + if (!strstr(buf, "DEVTYPE=partition")) + ksft_exit_fail_msg("%s: Unknown device type: %s\n", __func__, path); /* * Partition of block device - need to find actual device. * Using naming convention that devnameN is partition of * device devname. */ str = strstr(buf, "DEVNAME="); - if (!str) { - printf("%s: Could not read: %s", __func__, path); - exit(EXIT_FAILURE); - } + if (!str) + ksft_exit_fail_msg("%s: Could not read: %s", __func__, path); + str += 8; end = str; while (*end) { @@ -197,16 +185,14 @@ static void get_finfo(const char *dir) if (snprintf(finfo.dev_queue_read_ahead_path, sizeof(finfo.dev_queue_read_ahead_path), "/sys/block/%s/queue/read_ahead_kb", - str) >= sizeof(finfo.dev_queue_read_ahead_path)) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } + str) >= sizeof(finfo.dev_queue_read_ahead_path)) + ksft_exit_fail_msg("%s: Pathname is too long\n", __func__); + return; } ++end; } - printf("%s: Could not read: %s\n", __func__, path); - exit(EXIT_FAILURE); + ksft_exit_fail_msg("%s: Could not read: %s\n", __func__, path); } static bool check_swap(void *addr, unsigned long size) @@ -219,26 +205,21 @@ static bool check_swap(void *addr, unsigned long size) ret = snprintf(addr_pattern, MAX_LINE_LENGTH, "%08lx-", (unsigned long) addr); - if (ret >= MAX_LINE_LENGTH) { - printf("%s: Pattern is too long\n", __func__); - exit(EXIT_FAILURE); - } - + if (ret >= MAX_LINE_LENGTH) + ksft_exit_fail_msg("%s: Pattern is too long\n", __func__); fp = fopen(PID_SMAPS, "r"); - if (!fp) { - printf("%s: Failed to open file %s\n", __func__, PID_SMAPS); - exit(EXIT_FAILURE); - } + if (!fp) + ksft_exit_fail_msg("%s: Failed to open file %s\n", __func__, PID_SMAPS); + if (!check_for_pattern(fp, addr_pattern, buffer, sizeof(buffer))) goto err_out; ret = snprintf(addr_pattern, MAX_LINE_LENGTH, "Swap:%19ld kB", size >> 10); - if (ret >= MAX_LINE_LENGTH) { - printf("%s: Pattern is too long\n", __func__); - exit(EXIT_FAILURE); - } + if (ret >= MAX_LINE_LENGTH) + ksft_exit_fail_msg("%s: Pattern is too long\n", __func__); + /* * Fetch the Swap: in the same block and check whether it got * the expected number of hugeepages next. @@ -261,10 +242,8 @@ static void *alloc_mapping(int nr) p = mmap(BASE_ADDR, nr * hpage_pmd_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (p != BASE_ADDR) { - printf("Failed to allocate VMA at %p\n", BASE_ADDR); - exit(EXIT_FAILURE); - } + if (p != BASE_ADDR) + ksft_exit_fail_msg("Failed to allocate VMA at %p\n", BASE_ADDR); return p; } @@ -314,19 +293,16 @@ static void *alloc_hpage(struct mem_ops *ops) * khugepaged on low-load system (like a test machine), which * would cause MADV_COLLAPSE to fail with EAGAIN. */ - printf("Allocate huge page..."); - if (madvise_collapse_retry(p, hpage_pmd_size)) { - perror("madvise(MADV_COLLAPSE)"); - exit(EXIT_FAILURE); - } - if (!ops->check_huge(p, 1)) { - perror("madvise(MADV_COLLAPSE)"); - exit(EXIT_FAILURE); - } - if (madvise(p, hpage_pmd_size, MADV_HUGEPAGE)) { - perror("madvise(MADV_HUGEPAGE)"); - exit(EXIT_FAILURE); - } + ksft_print_msg("Allocate huge page...\n"); + if (madvise_collapse_retry(p, hpage_pmd_size)) + ksft_exit_fail_msg("madvise(MADV_COLLAPSE): %s\n", strerror(errno)); + + if (!ops->check_huge(p, 1)) + ksft_exit_fail_msg("madvise(MADV_COLLAPSE): %s\n", strerror(errno)); + + if (madvise(p, hpage_pmd_size, MADV_HUGEPAGE)) + ksft_exit_fail_msg("madvise(MADV_HUGEPAGE): %s\n", strerror(errno)); + success("OK"); return p; } @@ -335,13 +311,12 @@ static void validate_memory(int *p, unsigned long start, unsigned long end) { int i; - for (i = start / page_size; i < end / page_size; i++) { - if (p[i * page_size / sizeof(*p)] != i + 0xdead0000) { - printf("Page %d is corrupted: %#x\n", - i, p[i * page_size / sizeof(*p)]); - exit(EXIT_FAILURE); - } - } + for (i = start / page_size; i < end / page_size; i++) + if (p[i * page_size / sizeof(*p)] != i + 0xdead0000) + ksft_print_msg("Page %d is corrupted: %#x\n", + i, p[i * page_size / sizeof(*p)]); + + ksft_test_result(i == end/page_size, "Validated memory\n"); } static void *anon_setup_area(int nr_hpages) @@ -371,14 +346,12 @@ static void *file_setup_area(int nr_hpages) unsigned long size; unlink(finfo.path); /* Cleanup from previous failed tests */ - printf("Creating %s for collapse%s...", finfo.path, - finfo.type == VMA_SHMEM ? " (tmpfs)" : ""); + ksft_print_msg("Creating %s for collapse%s...\n", finfo.path, + finfo.type == VMA_SHMEM ? " (tmpfs)" : ""); fd = open(finfo.path, O_DSYNC | O_CREAT | O_RDWR | O_TRUNC | O_EXCL, 777); - if (fd < 0) { - perror("open()"); - exit(EXIT_FAILURE); - } + if (fd < 0) + ksft_exit_fail_msg("open(): %s\n", strerror(errno)); size = nr_hpages * hpage_pmd_size; p = alloc_mapping(nr_hpages); @@ -388,18 +361,15 @@ static void *file_setup_area(int nr_hpages) munmap(p, size); success("OK"); - printf("Opening %s read only for collapse...", finfo.path); + ksft_print_msg("Opening %s read only for collapse...\n", finfo.path); finfo.fd = open(finfo.path, O_RDONLY, 777); - if (finfo.fd < 0) { - perror("open()"); - exit(EXIT_FAILURE); - } + if (finfo.fd < 0) + ksft_exit_fail_msg("open(): %s\n", strerror(errno)); + p = mmap(BASE_ADDR, size, PROT_READ | PROT_EXEC, MAP_PRIVATE, finfo.fd, 0); - if (p == MAP_FAILED || p != BASE_ADDR) { - perror("mmap()"); - exit(EXIT_FAILURE); - } + if (p == MAP_FAILED || p != BASE_ADDR) + ksft_exit_fail_msg("mmap(): %s\n", strerror(errno)); /* Drop page cache */ write_file("/proc/sys/vm/drop_caches", "3", 2); @@ -416,10 +386,8 @@ static void file_cleanup_area(void *p, unsigned long size) static void file_fault(void *p, unsigned long start, unsigned long end) { - if (madvise(((char *)p) + start, end - start, MADV_POPULATE_READ)) { - perror("madvise(MADV_POPULATE_READ"); - exit(EXIT_FAILURE); - } + if (madvise(((char *)p) + start, end - start, MADV_POPULATE_READ)) + ksft_exit_fail_msg("madvise(MADV_POPULATE_READ: %s\n", strerror(errno)); } static bool file_check_huge(void *addr, int nr_hpages) @@ -430,7 +398,7 @@ static bool file_check_huge(void *addr, int nr_hpages) case VMA_SHMEM: return check_huge_shmem(addr, nr_hpages, hpage_pmd_size); default: - exit(EXIT_FAILURE); + ksft_exit_fail_msg("Wrong type\n"); return false; } } @@ -441,20 +409,16 @@ static void *shmem_setup_area(int nr_hpages) unsigned long size = nr_hpages * hpage_pmd_size; finfo.fd = memfd_create("khugepaged-selftest-collapse-shmem", 0); - if (finfo.fd < 0) { - perror("memfd_create()"); - exit(EXIT_FAILURE); - } - if (ftruncate(finfo.fd, size)) { - perror("ftruncate()"); - exit(EXIT_FAILURE); - } - p = mmap(BASE_ADDR, size, PROT_READ | PROT_WRITE, MAP_SHARED, finfo.fd, - 0); - if (p != BASE_ADDR) { - perror("mmap()"); - exit(EXIT_FAILURE); - } + if (finfo.fd < 0) + ksft_exit_fail_msg("memfd_create(): %s\n", strerror(errno)); + + if (ftruncate(finfo.fd, size)) + ksft_exit_fail_msg("ftruncate(): %s\n", strerror(errno)); + + p = mmap(BASE_ADDR, size, PROT_READ | PROT_WRITE, MAP_SHARED, finfo.fd, 0); + if (p != BASE_ADDR) + ksft_exit_fail_msg("mmap(): %s\n", strerror(errno)); + return p; } @@ -499,7 +463,7 @@ static void __madvise_collapse(const char *msg, char *p, int nr_hpages, int ret; struct thp_settings settings = *thp_current_settings(); - printf("%s...", msg); + ksft_print_msg("%s...\n", msg); /* * Prevent khugepaged interference and tests that MADV_COLLAPSE @@ -526,10 +490,9 @@ static void madvise_collapse(const char *msg, char *p, int nr_hpages, struct mem_ops *ops, bool expect) { /* Sanity check */ - if (!ops->check_huge(p, 0)) { - printf("Unexpected huge page\n"); - exit(EXIT_FAILURE); - } + if (!ops->check_huge(p, 0)) + ksft_exit_fail_msg("Unexpected huge page\n"); + __madvise_collapse(msg, p, nr_hpages, ops, expect); } @@ -541,23 +504,20 @@ static bool wait_for_scan(const char *msg, char *p, int nr_hpages, int timeout = 6; /* 3 seconds */ /* Sanity check */ - if (!ops->check_huge(p, 0)) { - printf("Unexpected huge page\n"); - exit(EXIT_FAILURE); - } + if (!ops->check_huge(p, 0)) + ksft_exit_fail_msg("Unexpected huge page\n"); madvise(p, nr_hpages * hpage_pmd_size, MADV_HUGEPAGE); /* Wait until the second full_scan completed */ full_scans = thp_read_num("khugepaged/full_scans") + 2; - printf("%s...", msg); + ksft_print_msg("%s...\n", msg); while (timeout--) { if (ops->check_huge(p, nr_hpages)) break; if (thp_read_num("khugepaged/full_scans") >= full_scans) break; - printf("."); usleep(TICK); } @@ -623,7 +583,7 @@ static void alloc_at_fault(void) p = alloc_mapping(1); *p = 1; - printf("Allocate huge page on fault..."); + ksft_print_msg("Allocate huge page on fault...\n"); if (check_huge_anon(p, 1, hpage_pmd_size)) success("OK"); else @@ -632,7 +592,7 @@ static void alloc_at_fault(void) thp_pop_settings(); madvise(p, page_size, MADV_DONTNEED); - printf("Split huge PMD on MADV_DONTNEED..."); + ksft_print_msg("Split huge PMD on MADV_DONTNEED...\n"); if (check_huge_anon(p, 0, hpage_pmd_size)) success("OK"); else @@ -688,7 +648,7 @@ static void collapse_max_ptes_none(struct collapse_context *c, struct mem_ops *o if (is_tmpfs(ops)) { /* shmem pages always in the page cache */ - printf("tmpfs..."); + ksft_print_msg("tmpfs...\n"); skip("Skip"); goto skip; } @@ -717,11 +677,10 @@ static void collapse_swapin_single_pte(struct collapse_context *c, struct mem_op p = ops->setup_area(1); ops->fault(p, 0, hpage_pmd_size); - printf("Swapout one page..."); - if (madvise(p, page_size, MADV_PAGEOUT)) { - perror("madvise(MADV_PAGEOUT)"); - exit(EXIT_FAILURE); - } + ksft_print_msg("Swapout one page...\n"); + if (madvise(p, page_size, MADV_PAGEOUT)) + ksft_exit_fail_msg("madvise(MADV_PAGEOUT): %s\n", strerror(errno)); + if (check_swap(p, page_size)) { success("OK"); } else { @@ -744,11 +703,10 @@ static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *o p = ops->setup_area(1); ops->fault(p, 0, hpage_pmd_size); - printf("Swapout %d of %d pages...", max_ptes_swap + 1, hpage_pmd_nr); - if (madvise(p, (max_ptes_swap + 1) * page_size, MADV_PAGEOUT)) { - perror("madvise(MADV_PAGEOUT)"); - exit(EXIT_FAILURE); - } + ksft_print_msg("Swapout %d of %d pages...\n", max_ptes_swap + 1, hpage_pmd_nr); + if (madvise(p, (max_ptes_swap + 1) * page_size, MADV_PAGEOUT)) + ksft_exit_fail_msg("madvise(MADV_PAGEOUT): %s\n", strerror(errno)); + if (check_swap(p, (max_ptes_swap + 1) * page_size)) { success("OK"); } else { @@ -762,12 +720,11 @@ static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *o if (c->enforce_pte_scan_limits) { ops->fault(p, 0, hpage_pmd_size); - printf("Swapout %d of %d pages...", max_ptes_swap, + ksft_print_msg("Swapout %d of %d pages...\n", max_ptes_swap, hpage_pmd_nr); - if (madvise(p, max_ptes_swap * page_size, MADV_PAGEOUT)) { - perror("madvise(MADV_PAGEOUT)"); - exit(EXIT_FAILURE); - } + if (madvise(p, max_ptes_swap * page_size, MADV_PAGEOUT)) + ksft_exit_fail_msg("madvise(MADV_PAGEOUT): %s\n", strerror(errno)); + if (check_swap(p, max_ptes_swap * page_size)) { success("OK"); } else { @@ -791,13 +748,13 @@ static void collapse_single_pte_entry_compound(struct collapse_context *c, struc if (is_tmpfs(ops)) { /* MADV_DONTNEED won't evict tmpfs pages */ - printf("tmpfs..."); + ksft_print_msg("tmpfs...\n"); skip("Skip"); goto skip; } madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE); - printf("Split huge page leaving single PTE mapping compound page..."); + ksft_print_msg("Split huge page leaving single PTE mapping compound page...\n"); madvise(p + page_size, hpage_pmd_size - page_size, MADV_DONTNEED); if (ops->check_huge(p, 0)) success("OK"); @@ -816,7 +773,7 @@ static void collapse_full_of_compound(struct collapse_context *c, struct mem_ops void *p; p = alloc_hpage(ops); - printf("Split huge page leaving single PTE page table full of compound pages..."); + ksft_print_msg("Split huge page leaving single PTE page table full of compound pages...\n"); madvise(p, page_size, MADV_NOHUGEPAGE); madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE); if (ops->check_huge(p, 0)) @@ -837,15 +794,14 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops p = ops->setup_area(1); for (i = 0; i < hpage_pmd_nr; i++) { - printf("\rConstruct PTE page table full of different PTE-mapped compound pages %3d/%d...", - i + 1, hpage_pmd_nr); + ksft_print_msg("\rConstruct PTE page table full of different PTE-mapped " + "compound pages %3d/%d...", i + 1, hpage_pmd_nr); madvise(BASE_ADDR, hpage_pmd_size, MADV_HUGEPAGE); ops->fault(BASE_ADDR, 0, hpage_pmd_size); - if (!ops->check_huge(BASE_ADDR, 1)) { - printf("Failed to allocate huge page\n"); - exit(EXIT_FAILURE); - } + if (!ops->check_huge(BASE_ADDR, 1)) + ksft_exit_fail_msg("Failed to allocate huge page\n"); + madvise(BASE_ADDR, hpage_pmd_size, MADV_NOHUGEPAGE); p = mremap(BASE_ADDR - i * page_size, @@ -853,22 +809,20 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops (i + 1) * page_size, MREMAP_MAYMOVE | MREMAP_FIXED, BASE_ADDR + 2 * hpage_pmd_size); - if (p == MAP_FAILED) { - perror("mremap+unmap"); - exit(EXIT_FAILURE); - } + if (p == MAP_FAILED) + ksft_exit_fail_msg("mremap+unmap: %s\n", strerror(errno)); p = mremap(BASE_ADDR + 2 * hpage_pmd_size, (i + 1) * page_size, (i + 1) * page_size + hpage_pmd_size, MREMAP_MAYMOVE | MREMAP_FIXED, BASE_ADDR - (i + 1) * page_size); - if (p == MAP_FAILED) { - perror("mremap+alloc"); - exit(EXIT_FAILURE); - } + if (p == MAP_FAILED) + ksft_exit_fail_msg("mremap+alloc: %s\n", strerror(errno)); } + ksft_print_msg("\n"); + ops->cleanup_area(BASE_ADDR, hpage_pmd_size); ops->fault(p, 0, hpage_pmd_size); if (!ops->check_huge(p, 1)) @@ -890,23 +844,19 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) p = ops->setup_area(1); - printf("Allocate small page..."); + ksft_print_msg("Allocate small page...\n"); ops->fault(p, 0, page_size); if (ops->check_huge(p, 0)) success("OK"); else fail("Fail"); - printf("Share small page over fork()..."); + ksft_print_msg("Share small page over fork()...\n"); if (!fork()) { /* Do not touch settings on child exit */ skip_settings_restore = true; - exit_status = 0; - if (ops->check_huge(p, 0)) - success("OK"); - else - fail("Fail"); + ksft_test_result(ops->check_huge(p, 0), "%s: child\n", __func__); ops->fault(p, page_size, 2 * page_size); c->collapse("Collapse PTE table with single page shared with parent process", @@ -914,13 +864,12 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) validate_memory(p, 0, page_size); ops->cleanup_area(p, hpage_pmd_size); - exit(exit_status); + exit(0); } wait(&wstatus); - exit_status += WEXITSTATUS(wstatus); - printf("Check if parent still has small page..."); + ksft_print_msg("Check if parent still has small page...\n"); if (ops->check_huge(p, 0)) success("OK"); else @@ -931,22 +880,17 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *ops) { - int wstatus; void *p; p = alloc_hpage(ops); - printf("Share huge page over fork()..."); + ksft_print_msg("Share huge page over fork()...\n"); if (!fork()) { /* Do not touch settings on child exit */ skip_settings_restore = true; - exit_status = 0; - if (ops->check_huge(p, 1)) - success("OK"); - else - fail("Fail"); + ksft_test_result(ops->check_huge(p, 1), "%s: child\n", __func__); - printf("Split huge page PMD in child process..."); + ksft_print_msg("Split huge page PMD in child process...\n"); madvise(p, page_size, MADV_NOHUGEPAGE); madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE); if (ops->check_huge(p, 0)) @@ -963,13 +907,12 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o validate_memory(p, 0, hpage_pmd_size); ops->cleanup_area(p, hpage_pmd_size); - exit(exit_status); + exit(0); } - wait(&wstatus); - exit_status += WEXITSTATUS(wstatus); + wait(NULL); - printf("Check if parent still has huge page..."); + ksft_print_msg("Check if parent still has huge page...\n"); if (ops->check_huge(p, 1)) success("OK"); else @@ -981,23 +924,18 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops *ops) { int max_ptes_shared = thp_read_num("khugepaged/max_ptes_shared"); - int wstatus; void *p; p = alloc_hpage(ops); - printf("Share huge page over fork()..."); + ksft_print_msg("Share huge page over fork()...\n"); if (!fork()) { /* Do not touch settings on child exit */ skip_settings_restore = true; - exit_status = 0; - if (ops->check_huge(p, 1)) - success("OK"); - else - fail("Fail"); + ksft_test_result(ops->check_huge(p, 1), "%s: child\n", __func__); - printf("Trigger CoW on page %d of %d...", - hpage_pmd_nr - max_ptes_shared - 1, hpage_pmd_nr); + ksft_print_msg("Trigger CoW on page %d of %d...\n", + hpage_pmd_nr - max_ptes_shared - 1, hpage_pmd_nr); ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared - 1) * page_size); if (ops->check_huge(p, 0)) success("OK"); @@ -1008,8 +946,8 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops 1, ops, !c->enforce_pte_scan_limits); if (c->enforce_pte_scan_limits) { - printf("Trigger CoW on page %d of %d...", - hpage_pmd_nr - max_ptes_shared, hpage_pmd_nr); + ksft_print_msg("Trigger CoW on page %d of %d...\n", + hpage_pmd_nr - max_ptes_shared, hpage_pmd_nr); ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared) * page_size); if (ops->check_huge(p, 0)) @@ -1023,13 +961,12 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops validate_memory(p, 0, hpage_pmd_size); ops->cleanup_area(p, hpage_pmd_size); - exit(exit_status); + exit(0); } - wait(&wstatus); - exit_status += WEXITSTATUS(wstatus); + wait(NULL); - printf("Check if parent still has huge page..."); + ksft_print_msg("Check if parent still has huge page...\n"); if (ops->check_huge(p, 1)) success("OK"); else @@ -1083,20 +1020,19 @@ static void madvise_retracted_page_tables(struct collapse_context *c, static void usage(void) { - fprintf(stderr, "\nUsage: ./khugepaged [OPTIONS] [dir]\n\n"); - fprintf(stderr, "\t\t: :\n"); - fprintf(stderr, "\t\t: [all|khugepaged|madvise]\n"); - fprintf(stderr, "\t\t: [all|anon|file|shmem]\n"); - fprintf(stderr, "\n\t\"file,all\" mem_type requires [dir] argument\n"); - fprintf(stderr, "\n\t\"file,all\" mem_type requires kernel built with\n"); - fprintf(stderr, "\tCONFIG_READ_ONLY_THP_FOR_FS=y\n"); - fprintf(stderr, "\n\tif [dir] is a (sub)directory of a tmpfs mount, tmpfs must be\n"); - fprintf(stderr, "\tmounted with huge=madvise option for khugepaged tests to work\n"); - fprintf(stderr, "\n\tSupported Options:\n"); - fprintf(stderr, "\t\t-h: This help message.\n"); - fprintf(stderr, "\t\t-s: mTHP size, expressed as page order.\n"); - fprintf(stderr, "\t\t Defaults to 0. Use this size for anon allocations.\n"); - exit(1); + ksft_print_msg("\nUsage: ./khugepaged [OPTIONS] [dir]\n\n"); + ksft_print_msg("\t\t: :\n"); + ksft_print_msg("\t\t: [all|khugepaged|madvise]\n"); + ksft_print_msg("\t\t: [all|anon|file|shmem]\n"); + ksft_print_msg("\n\t\"file,all\" mem_type requires [dir] argument\n"); + ksft_print_msg("\n\t\"file,all\" mem_type requires kernel built with\n"); + ksft_print_msg("\tCONFIG_READ_ONLY_THP_FOR_FS=y\n"); + ksft_print_msg("\n\tif [dir] is a (sub)directory of a tmpfs mount, tmpfs must be\n"); + ksft_print_msg("\tmounted with huge=madvise option for khugepaged tests to work\n"); + ksft_print_msg("\n\tSupported Options:\n"); + ksft_print_msg("\t\t-h: This help message.\n"); + ksft_print_msg("\t\t-s: mTHP size, expressed as page order.\n"); + ksft_exit_fail_msg("\t\t Defaults to 0. Use this size for anon allocations.\n"); } static void parse_test_type(int argc, char **argv) @@ -1190,16 +1126,17 @@ int main(int argc, char **argv) .read_ahead_kb = 0, }; + ksft_print_header(); + ksft_set_plan(65); + parse_test_type(argc, argv); setbuf(stdout, NULL); page_size = getpagesize(); hpage_pmd_size = read_pmd_pagesize(); - if (!hpage_pmd_size) { - printf("Reading PMD pagesize failed"); - exit(EXIT_FAILURE); - } + if (!hpage_pmd_size) + ksft_exit_fail_msg("Reading PMD pagesize failed\n"); hpage_pmd_nr = hpage_pmd_size / page_size; hpage_pmd_order = __builtin_ctz(hpage_pmd_nr); @@ -1217,7 +1154,7 @@ int main(int argc, char **argv) #define TEST(t, c, o) do { \ if (c && o) { \ - printf("\nRun test: " #t " (%s:%s)\n", c->name, o->name); \ + ksft_print_msg("Run test: " #t " (%s:%s)\n", c->name, o->name); \ t(c, o); \ } \ } while (0) @@ -1281,5 +1218,5 @@ int main(int argc, char **argv) TEST(madvise_retracted_page_tables, madvise_context, file_ops); TEST(madvise_retracted_page_tables, madvise_context, shmem_ops); - restore_settings(0); + ksft_finished(); } From patchwork Mon Jan 15 07:32:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muhammad Usama Anjum X-Patchwork-Id: 13519361 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4193B4401; Mon, 15 Jan 2024 07:33:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="UJUhNeQk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1705303994; bh=msYTdYSBLgcNB9Pwi9Sv9tDsr6IJ72WoG34TW93BI1Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UJUhNeQkyC7Ebkc3pFt7p01Xk/7PFHg5FBEns8H05Dd0K80Kb/n+KbvzLg99xQ/fr QF60mReOOE2DW+zEesgI+RLd4oELswj9b997YK0WauQOmKio0/r4Er2QaRAUAGjhQy XRwFzDM17zAVXftavQQuYbJMB85p5CbO/CGvsCrLzFy/5yHG9rnNu1itvdNueknnaw dL/TlVljeeXacf/UN6+XtNTKS61dzfYS5oFE+iGzB3iC8paz/IrLY+Bn3JReI9z/gB N05C21HN8PkqTGZi19xYVfWbN2IpCX5PkFgHila8eDRGMB5lC6uP87uV7iInAN/2IN ke/zANdj9UbOQ== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: usama.anjum) by madrid.collaboradmins.com (Postfix) with ESMTPSA id EC8753781F80; Mon, 15 Jan 2024 07:33:12 +0000 (UTC) From: Muhammad Usama Anjum To: Andrew Morton , Shuah Khan Cc: Muhammad Usama Anjum , kernel@collabora.com, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 5/7] selftests/mm: hugetlb-read-hwpoison: conform test to TAP format output Date: Mon, 15 Jan 2024 12:32:41 +0500 Message-ID: <20240115073247.1280266-5-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240115073247.1280266-1-usama.anjum@collabora.com> References: <20240115073247.1280266-1-usama.anjum@collabora.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Conform the layout, informational and status messages to TAP. No functional change is intended other than the layout of output messages. Signed-off-by: Muhammad Usama Anjum Reviewed-by: Jiaqi Yan --- Changes in v3: - Use ksft_perror as short hand instead of missing strerror(errno) at one place Tested this by reverting the patch a08c7193e4f18dc8508f2d07d0de2c5b94cb39a3 ("mm/filemap: remove hugetlb special casing in filemap.c") as it has broken the test. The bug report can be found at [1]. Tested with proposed fix as well [2]. [1] https://lore.kernel.org/all/079335ab-190f-41f7-b832-6ffe7528fd8b@collabora.com [2] https://lore.kernel.org/all/a20e7bdb-7344-306d-e8f5-5ee69af7d5ea@oracle.com --- .../selftests/mm/hugetlb-read-hwpoison.c | 116 ++++++++---------- 1 file changed, 54 insertions(+), 62 deletions(-) diff --git a/tools/testing/selftests/mm/hugetlb-read-hwpoison.c b/tools/testing/selftests/mm/hugetlb-read-hwpoison.c index ba6cc6f9cabc..23b41b88c6af 100644 --- a/tools/testing/selftests/mm/hugetlb-read-hwpoison.c +++ b/tools/testing/selftests/mm/hugetlb-read-hwpoison.c @@ -58,8 +58,8 @@ static bool verify_chunk(char *buf, size_t len, char val) for (i = 0; i < len; ++i) { if (buf[i] != val) { - printf(PREFIX ERROR_PREFIX "check fail: buf[%lu] = %u != %u\n", - i, buf[i], val); + ksft_print_msg(PREFIX ERROR_PREFIX "check fail: buf[%lu] = %u != %u\n", + i, buf[i], val); return false; } } @@ -75,21 +75,21 @@ static bool seek_read_hugepage_filemap(int fd, size_t len, size_t wr_chunk_size, ssize_t total_ret_count = 0; char val = offset / wr_chunk_size + offset % wr_chunk_size; - printf(PREFIX PREFIX "init val=%u with offset=0x%lx\n", val, offset); - printf(PREFIX PREFIX "expect to read 0x%lx bytes of data in total\n", - expected); + ksft_print_msg(PREFIX PREFIX "init val=%u with offset=0x%lx\n", val, offset); + ksft_print_msg(PREFIX PREFIX "expect to read 0x%lx bytes of data in total\n", + expected); if (lseek(fd, offset, SEEK_SET) < 0) { - perror(PREFIX ERROR_PREFIX "seek failed"); + ksft_perror(PREFIX ERROR_PREFIX "seek failed"); return false; } while (offset + total_ret_count < len) { ret_count = read(fd, buf, wr_chunk_size); if (ret_count == 0) { - printf(PREFIX PREFIX "read reach end of the file\n"); + ksft_print_msg(PREFIX PREFIX "read reach end of the file\n"); break; } else if (ret_count < 0) { - perror(PREFIX ERROR_PREFIX "read failed"); + ksft_perror(PREFIX ERROR_PREFIX "read failed"); break; } ++val; @@ -98,8 +98,8 @@ static bool seek_read_hugepage_filemap(int fd, size_t len, size_t wr_chunk_size, total_ret_count += ret_count; } - printf(PREFIX PREFIX "actually read 0x%lx bytes of data in total\n", - total_ret_count); + ksft_print_msg(PREFIX PREFIX "actually read 0x%lx bytes of data in total\n", + total_ret_count); return total_ret_count == expected; } @@ -112,15 +112,15 @@ static bool read_hugepage_filemap(int fd, size_t len, ssize_t total_ret_count = 0; char val = 0; - printf(PREFIX PREFIX "expect to read 0x%lx bytes of data in total\n", - expected); + ksft_print_msg(PREFIX PREFIX "expect to read 0x%lx bytes of data in total\n", + expected); while (total_ret_count < len) { ret_count = read(fd, buf, wr_chunk_size); if (ret_count == 0) { - printf(PREFIX PREFIX "read reach end of the file\n"); + ksft_print_msg(PREFIX PREFIX "read reach end of the file\n"); break; } else if (ret_count < 0) { - perror(PREFIX ERROR_PREFIX "read failed"); + ksft_perror(PREFIX ERROR_PREFIX "read failed"); break; } ++val; @@ -129,8 +129,8 @@ static bool read_hugepage_filemap(int fd, size_t len, total_ret_count += ret_count; } - printf(PREFIX PREFIX "actually read 0x%lx bytes of data in total\n", - total_ret_count); + ksft_print_msg(PREFIX PREFIX "actually read 0x%lx bytes of data in total\n", + total_ret_count); return total_ret_count == expected; } @@ -142,14 +142,14 @@ test_hugetlb_read(int fd, size_t len, size_t wr_chunk_size) char *filemap = NULL; if (ftruncate(fd, len) < 0) { - perror(PREFIX ERROR_PREFIX "ftruncate failed"); + ksft_perror(PREFIX ERROR_PREFIX "ftruncate failed"); return status; } filemap = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0); if (filemap == MAP_FAILED) { - perror(PREFIX ERROR_PREFIX "mmap for primary mapping failed"); + ksft_perror(PREFIX ERROR_PREFIX "mmap for primary mapping failed"); goto done; } @@ -162,7 +162,7 @@ test_hugetlb_read(int fd, size_t len, size_t wr_chunk_size) munmap(filemap, len); done: if (ftruncate(fd, 0) < 0) { - perror(PREFIX ERROR_PREFIX "ftruncate back to 0 failed"); + ksft_perror(PREFIX ERROR_PREFIX "ftruncate back to 0 failed"); status = TEST_FAILED; } @@ -179,14 +179,14 @@ test_hugetlb_read_hwpoison(int fd, size_t len, size_t wr_chunk_size, const unsigned long pagesize = getpagesize(); if (ftruncate(fd, len) < 0) { - perror(PREFIX ERROR_PREFIX "ftruncate failed"); + ksft_perror(PREFIX ERROR_PREFIX "ftruncate failed"); return status; } filemap = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0); if (filemap == MAP_FAILED) { - perror(PREFIX ERROR_PREFIX "mmap for primary mapping failed"); + ksft_perror(PREFIX ERROR_PREFIX "mmap for primary mapping failed"); goto done; } @@ -201,7 +201,7 @@ test_hugetlb_read_hwpoison(int fd, size_t len, size_t wr_chunk_size, */ hwp_addr = filemap + len / 2 + pagesize; if (madvise(hwp_addr, pagesize, MADV_HWPOISON) < 0) { - perror(PREFIX ERROR_PREFIX "MADV_HWPOISON failed"); + ksft_perror(PREFIX ERROR_PREFIX "MADV_HWPOISON failed"); goto unmap; } @@ -228,7 +228,7 @@ test_hugetlb_read_hwpoison(int fd, size_t len, size_t wr_chunk_size, munmap(filemap, len); done: if (ftruncate(fd, 0) < 0) { - perror(PREFIX ERROR_PREFIX "ftruncate back to 0 failed"); + ksft_perror(PREFIX ERROR_PREFIX "ftruncate back to 0 failed"); status = TEST_FAILED; } @@ -240,27 +240,32 @@ static int create_hugetlbfs_file(struct statfs *file_stat) int fd; fd = memfd_create("hugetlb_tmp", MFD_HUGETLB); - if (fd < 0) { - perror(PREFIX ERROR_PREFIX "could not open hugetlbfs file"); - return -1; - } + if (fd < 0) + ksft_exit_fail_msg(PREFIX ERROR_PREFIX "could not open hugetlbfs file: %s\n", + strerror(errno)); memset(file_stat, 0, sizeof(*file_stat)); + if (fstatfs(fd, file_stat)) { - perror(PREFIX ERROR_PREFIX "fstatfs failed"); - goto close; + close(fd); + ksft_exit_fail_msg(PREFIX ERROR_PREFIX "fstatfs failed: %s\n", strerror(errno)); } if (file_stat->f_type != HUGETLBFS_MAGIC) { - printf(PREFIX ERROR_PREFIX "not hugetlbfs file\n"); - goto close; + close(fd); + ksft_exit_fail_msg(PREFIX ERROR_PREFIX "not hugetlbfs file\n"); } return fd; -close: - close(fd); - return -1; } +#define KSFT_PRINT_MSG(status, fmt, ...) \ + do { \ + if (status == TEST_SKIPPED) \ + ksft_test_result_skip(fmt, __VA_ARGS__); \ + else \ + ksft_test_result(status == TEST_PASSED, fmt, __VA_ARGS__); \ + } while (0) + int main(void) { int fd; @@ -273,50 +278,37 @@ int main(void) }; size_t i; + ksft_print_header(); + ksft_set_plan(12); + for (i = 0; i < ARRAY_SIZE(wr_chunk_sizes); ++i) { - printf("Write/read chunk size=0x%lx\n", - wr_chunk_sizes[i]); + ksft_print_msg("Write/read chunk size=0x%lx\n", + wr_chunk_sizes[i]); fd = create_hugetlbfs_file(&file_stat); - if (fd < 0) - goto create_failure; - printf(PREFIX "HugeTLB read regression test...\n"); + ksft_print_msg(PREFIX "HugeTLB read regression test...\n"); status = test_hugetlb_read(fd, file_stat.f_bsize, wr_chunk_sizes[i]); - printf(PREFIX "HugeTLB read regression test...%s\n", - status_to_str(status)); + KSFT_PRINT_MSG(status, PREFIX "HugeTLB read regression test...%s\n", + status_to_str(status)); close(fd); - if (status == TEST_FAILED) - return -1; fd = create_hugetlbfs_file(&file_stat); - if (fd < 0) - goto create_failure; - printf(PREFIX "HugeTLB read HWPOISON test...\n"); + ksft_print_msg(PREFIX "HugeTLB read HWPOISON test...\n"); status = test_hugetlb_read_hwpoison(fd, file_stat.f_bsize, wr_chunk_sizes[i], false); - printf(PREFIX "HugeTLB read HWPOISON test...%s\n", - status_to_str(status)); + KSFT_PRINT_MSG(status, PREFIX "HugeTLB read HWPOISON test...%s\n", + status_to_str(status)); close(fd); - if (status == TEST_FAILED) - return -1; fd = create_hugetlbfs_file(&file_stat); - if (fd < 0) - goto create_failure; - printf(PREFIX "HugeTLB seek then read HWPOISON test...\n"); + ksft_print_msg(PREFIX "HugeTLB seek then read HWPOISON test...\n"); status = test_hugetlb_read_hwpoison(fd, file_stat.f_bsize, wr_chunk_sizes[i], true); - printf(PREFIX "HugeTLB seek then read HWPOISON test...%s\n", - status_to_str(status)); + KSFT_PRINT_MSG(status, PREFIX "HugeTLB seek then read HWPOISON test...%s\n", + status_to_str(status)); close(fd); - if (status == TEST_FAILED) - return -1; } - return 0; - -create_failure: - printf(ERROR_PREFIX "Abort test: failed to create hugetlbfs file\n"); - return -1; + ksft_finished(); } From patchwork Mon Jan 15 07:32:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muhammad Usama Anjum X-Patchwork-Id: 13519362 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 600DB79F5; Mon, 15 Jan 2024 07:33:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="g5XPzRbX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1705303997; bh=TMVRXrb1tG3+I18SJgfvyHfjDUNm4khJlToJ4CS96e8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g5XPzRbXWNZe21+nvELlTQFtYYN13Ery6jC4EhmoKJt4UTfUASSzy/tJ0g6IWjggQ CPg89oPwoNodzqzYQO/yrjsIjzaGH2troOpnwgagxzprV9zgKjzM5MtLw1jJTRnPZM vlAiyVNJO3yDPKY3rWDn8AL9ghhAfVA6wqakF8reBQwTgbnpmm4oq9Iw7CvCdSk48d Ioczzkc5XEz1Q2QxexaNnKNQlxeu9ptfk891xGtK404GSLCenTKFwPmmyUgGr6WU8x re0WQ0yaApiVX8CBGO8ZKURGHMBvpIo/fw0JEc3kgT92Xibfzb8dU+hhmOn+ODNaiC ZSrnjkL71NX3w== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: usama.anjum) by madrid.collaboradmins.com (Postfix) with ESMTPSA id D69BA3781FFD; Mon, 15 Jan 2024 07:33:15 +0000 (UTC) From: Muhammad Usama Anjum To: Andrew Morton , Shuah Khan Cc: Muhammad Usama Anjum , kernel@collabora.com, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 6/7] selftests/mm: ksm_tests: conform test to TAP format output Date: Mon, 15 Jan 2024 12:32:42 +0500 Message-ID: <20240115073247.1280266-6-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240115073247.1280266-1-usama.anjum@collabora.com> References: <20240115073247.1280266-1-usama.anjum@collabora.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Conform the layout, informational and status messages to TAP. No functional change is intended other than the layout of output messages. Signed-off-by: Muhammad Usama Anjum --- tools/testing/selftests/mm/ksm_tests.c | 682 ++++++++++--------------- 1 file changed, 276 insertions(+), 406 deletions(-) diff --git a/tools/testing/selftests/mm/ksm_tests.c b/tools/testing/selftests/mm/ksm_tests.c index 380b691d3eb9..c5c5e909cc5e 100644 --- a/tools/testing/selftests/mm/ksm_tests.c +++ b/tools/testing/selftests/mm/ksm_tests.c @@ -56,42 +56,34 @@ enum ksm_test_name { int debug; -static int ksm_write_sysfs(const char *file_path, unsigned long val) +static void ksm_write_sysfs(const char *file_path, unsigned long val) { FILE *f = fopen(file_path, "w"); - if (!f) { - fprintf(stderr, "f %s\n", file_path); - perror("fopen"); - return 1; - } + if (!f) + ksft_exit_fail_msg("fopen %s: %s\n", file_path, strerror(errno)); + if (fprintf(f, "%lu", val) < 0) { - perror("fprintf"); fclose(f); - return 1; + ksft_exit_fail_msg("fprintf: %s\n", strerror(errno)); } - fclose(f); - return 0; + fclose(f); } -static int ksm_read_sysfs(const char *file_path, unsigned long *val) +static void ksm_read_sysfs(const char *file_path, unsigned long *val) { FILE *f = fopen(file_path, "r"); - if (!f) { - fprintf(stderr, "f %s\n", file_path); - perror("fopen"); - return 1; - } + if (!f) + ksft_exit_fail_msg("fopen %s: %s\n", file_path, strerror(errno)); + if (fscanf(f, "%lu", val) != 1) { - perror("fscanf"); fclose(f); - return 1; + ksft_exit_fail_msg("fscanf: %s\n", strerror(errno)); } - fclose(f); - return 0; + fclose(f); } static void ksm_print_sysfs(void) @@ -101,26 +93,25 @@ static void ksm_print_sysfs(void) unsigned long stable_node_chains, stable_node_dups; long general_profit; - if (ksm_read_sysfs(KSM_FP("pages_shared"), &pages_shared) || - ksm_read_sysfs(KSM_FP("pages_sharing"), &pages_sharing) || - ksm_read_sysfs(KSM_FP("max_page_sharing"), &max_page_sharing) || - ksm_read_sysfs(KSM_FP("full_scans"), &full_scans) || - ksm_read_sysfs(KSM_FP("pages_unshared"), &pages_unshared) || - ksm_read_sysfs(KSM_FP("pages_volatile"), &pages_volatile) || - ksm_read_sysfs(KSM_FP("stable_node_chains"), &stable_node_chains) || - ksm_read_sysfs(KSM_FP("stable_node_dups"), &stable_node_dups) || - ksm_read_sysfs(KSM_FP("general_profit"), (unsigned long *)&general_profit)) - return; - - printf("pages_shared : %lu\n", pages_shared); - printf("pages_sharing : %lu\n", pages_sharing); - printf("max_page_sharing : %lu\n", max_page_sharing); - printf("full_scans : %lu\n", full_scans); - printf("pages_unshared : %lu\n", pages_unshared); - printf("pages_volatile : %lu\n", pages_volatile); - printf("stable_node_chains: %lu\n", stable_node_chains); - printf("stable_node_dups : %lu\n", stable_node_dups); - printf("general_profit : %ld\n", general_profit); + ksm_read_sysfs(KSM_FP("pages_shared"), &pages_shared); + ksm_read_sysfs(KSM_FP("pages_sharing"), &pages_sharing); + ksm_read_sysfs(KSM_FP("max_page_sharing"), &max_page_sharing); + ksm_read_sysfs(KSM_FP("full_scans"), &full_scans); + ksm_read_sysfs(KSM_FP("pages_unshared"), &pages_unshared); + ksm_read_sysfs(KSM_FP("pages_volatile"), &pages_volatile); + ksm_read_sysfs(KSM_FP("stable_node_chains"), &stable_node_chains); + ksm_read_sysfs(KSM_FP("stable_node_dups"), &stable_node_dups); + ksm_read_sysfs(KSM_FP("general_profit"), (unsigned long *)&general_profit); + + ksft_print_msg("pages_shared : %lu\n", pages_shared); + ksft_print_msg("pages_sharing : %lu\n", pages_sharing); + ksft_print_msg("max_page_sharing : %lu\n", max_page_sharing); + ksft_print_msg("full_scans : %lu\n", full_scans); + ksft_print_msg("pages_unshared : %lu\n", pages_unshared); + ksft_print_msg("pages_volatile : %lu\n", pages_volatile); + ksft_print_msg("stable_node_chains: %lu\n", stable_node_chains); + ksft_print_msg("stable_node_dups : %lu\n", stable_node_dups); + ksft_print_msg("general_profit : %ld\n", general_profit); } static void ksm_print_procfs(void) @@ -129,14 +120,11 @@ static void ksm_print_procfs(void) char buffer[512]; FILE *f = fopen(file_name, "r"); - if (!f) { - fprintf(stderr, "f %s\n", file_name); - perror("fopen"); - return; - } + if (!f) + ksft_exit_fail_msg("fopen %s: %s\n", file_name, strerror(errno)); while (fgets(buffer, sizeof(buffer), f)) - printf("%s", buffer); + ksft_exit_fail_msg("%s", buffer); fclose(f); } @@ -157,132 +145,111 @@ static int str_to_prot(char *prot_str) static void print_help(void) { - printf("usage: ksm_tests [-h] [-a prot] [-p page_count] [-l timeout]\n" - "[-z use_zero_pages] [-m merge_across_nodes] [-s size]\n"); - - printf("Supported :\n" - " -M (page merging)\n" - " -Z (zero pages merging)\n" - " -N (merging of pages in different NUMA nodes)\n" - " -U (page unmerging)\n" - " -P evaluate merging time and speed.\n" - " For this test, the size of duplicated memory area (in MiB)\n" - " must be provided using -s option\n" - " -H evaluate merging time and speed of area allocated mostly with huge pages\n" - " For this test, the size of duplicated memory area (in MiB)\n" - " must be provided using -s option\n" - " -D evaluate unmerging time and speed when disabling KSM.\n" - " For this test, the size of duplicated memory area (in MiB)\n" - " must be provided using -s option\n" - " -C evaluate the time required to break COW of merged pages.\n\n"); - - printf(" -a: specify the access protections of pages.\n" - " must be of the form [rwx].\n" - " Default: %s\n", KSM_PROT_STR_DEFAULT); - printf(" -p: specify the number of pages to test.\n" - " Default: %ld\n", KSM_PAGE_COUNT_DEFAULT); - printf(" -l: limit the maximum running time (in seconds) for a test.\n" - " Default: %d seconds\n", KSM_SCAN_LIMIT_SEC_DEFAULT); - printf(" -z: change use_zero_pages tunable\n" - " Default: %d\n", KSM_USE_ZERO_PAGES_DEFAULT); - printf(" -m: change merge_across_nodes tunable\n" - " Default: %d\n", KSM_MERGE_ACROSS_NODES_DEFAULT); - printf(" -d: turn debugging output on\n"); - printf(" -s: the size of duplicated memory area (in MiB)\n"); - printf(" -t: KSM merge type\n" - " Default: 0\n" - " 0: madvise merging\n" - " 1: prctl merging\n"); - - exit(0); + ksft_print_msg("usage: ksm_tests [-h] [-a prot] [-p page_count] [-l timeout]\n" + "[-z use_zero_pages] [-m merge_across_nodes] [-s size]\n"); + + ksft_print_msg("Supported :\n" + " -M (page merging)\n" + " -Z (zero pages merging)\n" + " -N (merging of pages in different NUMA nodes)\n" + " -U (page unmerging)\n" + " -P evaluate merging time and speed.\n" + " For this test, the size of duplicated memory area (in MiB)\n" + " must be provided using -s option\n" + " -H evaluate merging time and speed of area allocated mostly with huge pages\n" + " For this test, the size of duplicated memory area (in MiB)\n" + " must be provided using -s option\n" + " -D evaluate unmerging time and speed when disabling KSM.\n" + " For this test, the size of duplicated memory area (in MiB)\n" + " must be provided using -s option\n" + " -C evaluate the time required to break COW of merged pages.\n\n"); + + ksft_print_msg(" -a: specify the access protections of pages.\n" + " must be of the form [rwx].\n" + " Default: %s\n", KSM_PROT_STR_DEFAULT); + ksft_print_msg(" -p: specify the number of pages to test.\n" + " Default: %ld\n", KSM_PAGE_COUNT_DEFAULT); + ksft_print_msg(" -l: limit the maximum running time (in seconds) for a test.\n" + " Default: %d seconds\n", KSM_SCAN_LIMIT_SEC_DEFAULT); + ksft_print_msg(" -z: change use_zero_pages tunable\n" + " Default: %d\n", KSM_USE_ZERO_PAGES_DEFAULT); + ksft_print_msg(" -m: change merge_across_nodes tunable\n" + " Default: %d\n", KSM_MERGE_ACROSS_NODES_DEFAULT); + ksft_print_msg(" -d: turn debugging output on\n"); + ksft_print_msg(" -s: the size of duplicated memory area (in MiB)\n"); + ksft_exit_fail_msg(" -t: KSM merge type\n" + " Default: 0\n" + " 0: madvise merging\n" + " 1: prctl merging\n"); } -static void *allocate_memory(void *ptr, int prot, int mapping, char data, size_t map_size) +static void *allocate_memory(void *ptr, int prot, int mapping, char data, size_t map_size) { void *map_ptr = mmap(ptr, map_size, PROT_WRITE, mapping, -1, 0); - if (!map_ptr) { - perror("mmap"); - return NULL; - } + if (!map_ptr) + ksft_exit_fail_msg("mmap: %s\n", strerror(errno)); + memset(map_ptr, data, map_size); if (mprotect(map_ptr, map_size, prot)) { - perror("mprotect"); munmap(map_ptr, map_size); - return NULL; + ksft_exit_fail_msg("mprotect: %s\n", strerror(errno)); } return map_ptr; } -static int ksm_do_scan(int scan_count, struct timespec start_time, int timeout) +static void ksm_do_scan(int scan_count, struct timespec start_time, int timeout) { struct timespec cur_time; unsigned long cur_scan, init_scan; - if (ksm_read_sysfs(KSM_FP("full_scans"), &init_scan)) - return 1; + ksm_read_sysfs(KSM_FP("full_scans"), &init_scan); + cur_scan = init_scan; while (cur_scan < init_scan + scan_count) { - if (ksm_read_sysfs(KSM_FP("full_scans"), &cur_scan)) - return 1; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &cur_time)) { - perror("clock_gettime"); - return 1; - } - if ((cur_time.tv_sec - start_time.tv_sec) > timeout) { - printf("Scan time limit exceeded\n"); - return 1; - } - } + ksm_read_sysfs(KSM_FP("full_scans"), &cur_scan); + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &cur_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); - return 0; + if ((cur_time.tv_sec - start_time.tv_sec) > timeout) + ksft_exit_fail_msg("Scan time limit exceeded\n"); + } } -static int ksm_merge_pages(int merge_type, void *addr, size_t size, - struct timespec start_time, int timeout) +static void ksm_merge_pages(int merge_type, void *addr, size_t size, + struct timespec start_time, int timeout) { if (merge_type == KSM_MERGE_MADVISE) { - if (madvise(addr, size, MADV_MERGEABLE)) { - perror("madvise"); - return 1; - } + if (madvise(addr, size, MADV_MERGEABLE)) + ksft_exit_fail_msg("madvise: %s", strerror(errno)); } else if (merge_type == KSM_MERGE_PRCTL) { - if (prctl(PR_SET_MEMORY_MERGE, 1, 0, 0, 0)) { - perror("prctl"); - return 1; - } + if (prctl(PR_SET_MEMORY_MERGE, 1, 0, 0, 0)) + ksft_exit_fail_msg("prctl: %s\n", strerror(errno)); } - if (ksm_write_sysfs(KSM_FP("run"), 1)) - return 1; + ksm_write_sysfs(KSM_FP("run"), 1); /* Since merging occurs only after 2 scans, make sure to get at least 2 full scans */ - if (ksm_do_scan(2, start_time, timeout)) - return 1; - - return 0; + ksm_do_scan(2, start_time, timeout); } -static int ksm_unmerge_pages(void *addr, size_t size, - struct timespec start_time, int timeout) +static void ksm_unmerge_pages(void *addr, size_t size, + struct timespec start_time, int timeout) { - if (madvise(addr, size, MADV_UNMERGEABLE)) { - perror("madvise"); - return 1; - } - return 0; + if (madvise(addr, size, MADV_UNMERGEABLE)) + ksft_exit_fail_msg("madvise: %s\n", strerror(errno)); } static bool assert_ksm_pages_count(long dupl_page_count) { unsigned long max_page_sharing, pages_sharing, pages_shared; - if (ksm_read_sysfs(KSM_FP("pages_shared"), &pages_shared) || - ksm_read_sysfs(KSM_FP("pages_sharing"), &pages_sharing) || - ksm_read_sysfs(KSM_FP("max_page_sharing"), &max_page_sharing)) - return false; + ksm_read_sysfs(KSM_FP("pages_shared"), &pages_shared); + ksm_read_sysfs(KSM_FP("pages_sharing"), &pages_sharing); + ksm_read_sysfs(KSM_FP("max_page_sharing"), &max_page_sharing); if (debug) { ksm_print_sysfs(); @@ -312,133 +279,96 @@ static bool assert_ksm_pages_count(long dupl_page_count) return false; } -static int ksm_save_def(struct ksm_sysfs *ksm_sysfs) +static void ksm_save_def(struct ksm_sysfs *ksm_sysfs) { - if (ksm_read_sysfs(KSM_FP("max_page_sharing"), &ksm_sysfs->max_page_sharing) || - numa_available() ? 0 : - ksm_read_sysfs(KSM_FP("merge_across_nodes"), &ksm_sysfs->merge_across_nodes) || - ksm_read_sysfs(KSM_FP("sleep_millisecs"), &ksm_sysfs->sleep_millisecs) || - ksm_read_sysfs(KSM_FP("pages_to_scan"), &ksm_sysfs->pages_to_scan) || - ksm_read_sysfs(KSM_FP("run"), &ksm_sysfs->run) || - ksm_read_sysfs(KSM_FP("stable_node_chains_prune_millisecs"), - &ksm_sysfs->stable_node_chains_prune_millisecs) || - ksm_read_sysfs(KSM_FP("use_zero_pages"), &ksm_sysfs->use_zero_pages)) - return 1; - - return 0; + ksm_read_sysfs(KSM_FP("max_page_sharing"), &ksm_sysfs->max_page_sharing); + if (numa_available()) + ksm_read_sysfs(KSM_FP("merge_across_nodes"), &ksm_sysfs->merge_across_nodes); + ksm_read_sysfs(KSM_FP("sleep_millisecs"), &ksm_sysfs->sleep_millisecs); + ksm_read_sysfs(KSM_FP("pages_to_scan"), &ksm_sysfs->pages_to_scan); + ksm_read_sysfs(KSM_FP("run"), &ksm_sysfs->run); + ksm_read_sysfs(KSM_FP("stable_node_chains_prune_millisecs"), + &ksm_sysfs->stable_node_chains_prune_millisecs); + ksm_read_sysfs(KSM_FP("use_zero_pages"), &ksm_sysfs->use_zero_pages); } -static int ksm_restore(struct ksm_sysfs *ksm_sysfs) +static void ksm_restore(struct ksm_sysfs *ksm_sysfs) { - if (ksm_write_sysfs(KSM_FP("max_page_sharing"), ksm_sysfs->max_page_sharing) || - numa_available() ? 0 : - ksm_write_sysfs(KSM_FP("merge_across_nodes"), ksm_sysfs->merge_across_nodes) || - ksm_write_sysfs(KSM_FP("pages_to_scan"), ksm_sysfs->pages_to_scan) || - ksm_write_sysfs(KSM_FP("run"), ksm_sysfs->run) || - ksm_write_sysfs(KSM_FP("sleep_millisecs"), ksm_sysfs->sleep_millisecs) || - ksm_write_sysfs(KSM_FP("stable_node_chains_prune_millisecs"), - ksm_sysfs->stable_node_chains_prune_millisecs) || - ksm_write_sysfs(KSM_FP("use_zero_pages"), ksm_sysfs->use_zero_pages)) - return 1; - - return 0; + ksm_write_sysfs(KSM_FP("max_page_sharing"), ksm_sysfs->max_page_sharing); + if (numa_available()) + ksm_write_sysfs(KSM_FP("merge_across_nodes"), ksm_sysfs->merge_across_nodes); + + ksm_write_sysfs(KSM_FP("pages_to_scan"), ksm_sysfs->pages_to_scan); + ksm_write_sysfs(KSM_FP("run"), ksm_sysfs->run); + ksm_write_sysfs(KSM_FP("sleep_millisecs"), ksm_sysfs->sleep_millisecs); + ksm_write_sysfs(KSM_FP("stable_node_chains_prune_millisecs"), + ksm_sysfs->stable_node_chains_prune_millisecs); + ksm_write_sysfs(KSM_FP("use_zero_pages"), ksm_sysfs->use_zero_pages); } -static int check_ksm_merge(int merge_type, int mapping, int prot, - long page_count, int timeout, size_t page_size) +static void check_ksm_merge(int merge_type, int mapping, int prot, + long page_count, int timeout, size_t page_size) { void *map_ptr; struct timespec start_time; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - return KSFT_FAIL; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); /* fill pages with the same data and merge them */ map_ptr = allocate_memory(NULL, prot, mapping, '*', page_size * page_count); - if (!map_ptr) - return KSFT_FAIL; - if (ksm_merge_pages(merge_type, map_ptr, page_size * page_count, start_time, timeout)) - goto err_out; + ksm_merge_pages(merge_type, map_ptr, page_size * page_count, start_time, timeout); /* verify that the right number of pages are merged */ - if (assert_ksm_pages_count(page_count)) { - printf("OK\n"); - munmap(map_ptr, page_size * page_count); - if (merge_type == KSM_MERGE_PRCTL) - prctl(PR_SET_MEMORY_MERGE, 0, 0, 0, 0); - return KSFT_PASS; - } - -err_out: - printf("Not OK\n"); + ksft_test_result(assert_ksm_pages_count(page_count), "%s\n", __func__); munmap(map_ptr, page_size * page_count); - return KSFT_FAIL; + if (merge_type == KSM_MERGE_PRCTL) + prctl(PR_SET_MEMORY_MERGE, 0, 0, 0, 0); } -static int check_ksm_unmerge(int merge_type, int mapping, int prot, int timeout, size_t page_size) +static void check_ksm_unmerge(int merge_type, int mapping, int prot, int timeout, size_t page_size) { void *map_ptr; struct timespec start_time; int page_count = 2; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - return KSFT_FAIL; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); /* fill pages with the same data and merge them */ map_ptr = allocate_memory(NULL, prot, mapping, '*', page_size * page_count); - if (!map_ptr) - return KSFT_FAIL; - if (ksm_merge_pages(merge_type, map_ptr, page_size * page_count, start_time, timeout)) - goto err_out; + ksm_merge_pages(merge_type, map_ptr, page_size * page_count, start_time, timeout); /* change 1 byte in each of the 2 pages -- KSM must automatically unmerge them */ memset(map_ptr, '-', 1); memset(map_ptr + page_size, '+', 1); /* get at least 1 scan, so KSM can detect that the pages were modified */ - if (ksm_do_scan(1, start_time, timeout)) - goto err_out; + ksm_do_scan(1, start_time, timeout); /* check that unmerging was successful and 0 pages are currently merged */ - if (assert_ksm_pages_count(0)) { - printf("OK\n"); - munmap(map_ptr, page_size * page_count); - return KSFT_PASS; - } - -err_out: - printf("Not OK\n"); + ksft_test_result(assert_ksm_pages_count(0), "%s\n", __func__); munmap(map_ptr, page_size * page_count); - return KSFT_FAIL; } -static int check_ksm_zero_page_merge(int merge_type, int mapping, int prot, long page_count, - int timeout, bool use_zero_pages, size_t page_size) +static void check_ksm_zero_page_merge(int merge_type, int mapping, int prot, long page_count, + int timeout, bool use_zero_pages, size_t page_size) { void *map_ptr; struct timespec start_time; + bool passed = true; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - return KSFT_FAIL; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); - if (ksm_write_sysfs(KSM_FP("use_zero_pages"), use_zero_pages)) - return KSFT_FAIL; + ksm_write_sysfs(KSM_FP("use_zero_pages"), use_zero_pages); /* fill pages with zero and try to merge them */ map_ptr = allocate_memory(NULL, prot, mapping, 0, page_size * page_count); - if (!map_ptr) - return KSFT_FAIL; - if (ksm_merge_pages(merge_type, map_ptr, page_size * page_count, start_time, timeout)) - goto err_out; + ksm_merge_pages(merge_type, map_ptr, page_size * page_count, start_time, timeout); /* * verify that the right number of pages are merged: @@ -448,18 +378,12 @@ static int check_ksm_zero_page_merge(int merge_type, int mapping, int prot, long * and merged as usual. */ if (use_zero_pages && !assert_ksm_pages_count(0)) - goto err_out; + passed = false; else if (!use_zero_pages && !assert_ksm_pages_count(page_count)) - goto err_out; - - printf("OK\n"); - munmap(map_ptr, page_size * page_count); - return KSFT_PASS; + passed = false; -err_out: - printf("Not OK\n"); + ksft_test_result(passed, "%s\n", __func__); munmap(map_ptr, page_size * page_count); - return KSFT_FAIL; } static int get_next_mem_node(int node) @@ -483,46 +407,44 @@ static int get_first_mem_node(void) return get_next_mem_node(numa_max_node()); } -static int check_ksm_numa_merge(int merge_type, int mapping, int prot, int timeout, - bool merge_across_nodes, size_t page_size) +static void check_ksm_numa_merge(int merge_type, int mapping, int prot, int timeout, + bool merge_across_nodes, size_t page_size) { void *numa1_map_ptr, *numa2_map_ptr; struct timespec start_time; int page_count = 2; + bool passed = true; int first_node; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - return KSFT_FAIL; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); if (numa_available() < 0) { - perror("NUMA support not enabled"); - return KSFT_SKIP; + ksft_test_result_skip("NUMA support not enabled: %s\n", strerror(errno)); + return; } + if (numa_num_configured_nodes() <= 1) { - printf("At least 2 NUMA nodes must be available\n"); - return KSFT_SKIP; + ksft_test_result_skip("At least 2 NUMA nodes must be available\n"); + return; } - if (ksm_write_sysfs(KSM_FP("merge_across_nodes"), merge_across_nodes)) - return KSFT_FAIL; + ksm_write_sysfs(KSM_FP("merge_across_nodes"), merge_across_nodes); /* allocate 2 pages in 2 different NUMA nodes and fill them with the same data */ first_node = get_first_mem_node(); numa1_map_ptr = numa_alloc_onnode(page_size, first_node); numa2_map_ptr = numa_alloc_onnode(page_size, get_next_mem_node(first_node)); if (!numa1_map_ptr || !numa2_map_ptr) { - perror("numa_alloc_onnode"); - return KSFT_FAIL; + ksft_test_result_fail("numa_alloc_onnode: %s\n", strerror(errno)); + return; } memset(numa1_map_ptr, '*', page_size); memset(numa2_map_ptr, '*', page_size); /* try to merge the pages */ - if (ksm_merge_pages(merge_type, numa1_map_ptr, page_size, start_time, timeout) || - ksm_merge_pages(merge_type, numa2_map_ptr, page_size, start_time, timeout)) - goto err_out; + ksm_merge_pages(merge_type, numa1_map_ptr, page_size, start_time, timeout); + ksm_merge_pages(merge_type, numa2_map_ptr, page_size, start_time, timeout); /* * verify that the right number of pages are merged: @@ -531,24 +453,18 @@ static int check_ksm_numa_merge(int merge_type, int mapping, int prot, int timeo * only 1 unique page in each node and they can't be shared. */ if (merge_across_nodes && !assert_ksm_pages_count(page_count)) - goto err_out; + passed = false; else if (!merge_across_nodes && !assert_ksm_pages_count(0)) - goto err_out; + passed = false; numa_free(numa1_map_ptr, page_size); numa_free(numa2_map_ptr, page_size); - printf("OK\n"); - return KSFT_PASS; -err_out: - numa_free(numa1_map_ptr, page_size); - numa_free(numa2_map_ptr, page_size); - printf("Not OK\n"); - return KSFT_FAIL; + ksft_test_result(passed, "%s\n", __func__); } -static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot, - int timeout, size_t map_size) +static void ksm_merge_hugepages_time(int merge_type, int mapping, int prot, + int timeout, size_t map_size) { void *map_ptr, *map_ptr_orig; struct timespec start_time, end_time; @@ -564,14 +480,14 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot, map_ptr = map_ptr_orig + HPAGE_SIZE - (uintptr_t)map_ptr_orig % HPAGE_SIZE; if (map_ptr_orig == MAP_FAILED) - err(2, "initial mmap"); + ksft_exit_fail_msg("initial mmap: %s\n", strerror(errno)); if (madvise(map_ptr, len + HPAGE_SIZE, MADV_HUGEPAGE)) - err(2, "MADV_HUGEPAGE"); + ksft_exit_fail_msg("MADV_HUGEPAGE: %s\n", strerror(errno)); pagemap_fd = open("/proc/self/pagemap", O_RDONLY); if (pagemap_fd < 0) - err(2, "open pagemap"); + ksft_exit_fail_msg("open pagemap: %s\n", strerror(errno)); n_normal_pages = 0; n_huge_pages = 0; @@ -581,41 +497,33 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot, else n_huge_pages++; } - printf("Number of normal pages: %d\n", n_normal_pages); - printf("Number of huge pages: %d\n", n_huge_pages); + ksft_print_msg("Number of normal pages: %d\n", n_normal_pages); + ksft_print_msg("Number of huge pages: %d\n", n_huge_pages); memset(map_ptr, '*', len); - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - goto err_out; - } - if (ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout)) - goto err_out; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) { - perror("clock_gettime"); - goto err_out; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); + + ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout); + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); scan_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC + (end_time.tv_nsec - start_time.tv_nsec); - printf("Total size: %lu MiB\n", map_size / MB); - printf("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC, - scan_time_ns % NSEC_PER_SEC); - printf("Average speed: %.3f MiB/s\n", (map_size / MB) / - ((double)scan_time_ns / NSEC_PER_SEC)); - - munmap(map_ptr_orig, len + HPAGE_SIZE); - return KSFT_PASS; + ksft_print_msg("Total size: %lu MiB\n", map_size / MB); + ksft_print_msg("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC, + scan_time_ns % NSEC_PER_SEC); + ksft_print_msg("Average speed: %.3f MiB/s\n", (map_size / MB) / + ((double)scan_time_ns / NSEC_PER_SEC)); -err_out: - printf("Not OK\n"); + ksft_test_result_pass("%s\n", __func__); munmap(map_ptr_orig, len + HPAGE_SIZE); - return KSFT_FAIL; } -static int ksm_merge_time(int merge_type, int mapping, int prot, int timeout, size_t map_size) +static void ksm_merge_time(int merge_type, int mapping, int prot, int timeout, size_t map_size) { void *map_ptr; struct timespec start_time, end_time; @@ -624,39 +532,29 @@ static int ksm_merge_time(int merge_type, int mapping, int prot, int timeout, si map_size *= MB; map_ptr = allocate_memory(NULL, prot, mapping, '*', map_size); - if (!map_ptr) - return KSFT_FAIL; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - goto err_out; - } - if (ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout)) - goto err_out; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) { - perror("clock_gettime"); - goto err_out; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); + + ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout); + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); scan_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC + (end_time.tv_nsec - start_time.tv_nsec); - printf("Total size: %lu MiB\n", map_size / MB); - printf("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC, - scan_time_ns % NSEC_PER_SEC); - printf("Average speed: %.3f MiB/s\n", (map_size / MB) / - ((double)scan_time_ns / NSEC_PER_SEC)); + ksft_print_msg("Total size: %lu MiB\n", map_size / MB); + ksft_print_msg("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC, + scan_time_ns % NSEC_PER_SEC); + ksft_print_msg("Average speed: %.3f MiB/s\n", (map_size / MB) / + ((double)scan_time_ns / NSEC_PER_SEC)); + ksft_test_result_pass("%s\n", __func__); munmap(map_ptr, map_size); - return KSFT_PASS; - -err_out: - printf("Not OK\n"); - munmap(map_ptr, map_size); - return KSFT_FAIL; } -static int ksm_unmerge_time(int merge_type, int mapping, int prot, int timeout, size_t map_size) +static void ksm_unmerge_time(int merge_type, int mapping, int prot, int timeout, size_t map_size) { void *map_ptr; struct timespec start_time, end_time; @@ -665,45 +563,34 @@ static int ksm_unmerge_time(int merge_type, int mapping, int prot, int timeout, map_size *= MB; map_ptr = allocate_memory(NULL, prot, mapping, '*', map_size); - if (!map_ptr) - return KSFT_FAIL; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - goto err_out; - } - if (ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout)) - goto err_out; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - goto err_out; - } - if (ksm_unmerge_pages(map_ptr, map_size, start_time, timeout)) - goto err_out; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) { - perror("clock_gettime"); - goto err_out; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); + + ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout); + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); + + ksm_unmerge_pages(map_ptr, map_size, start_time, timeout); + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); scan_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC + (end_time.tv_nsec - start_time.tv_nsec); - printf("Total size: %lu MiB\n", map_size / MB); - printf("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC, - scan_time_ns % NSEC_PER_SEC); - printf("Average speed: %.3f MiB/s\n", (map_size / MB) / - ((double)scan_time_ns / NSEC_PER_SEC)); + ksft_print_msg("Total size: %lu MiB\n", map_size / MB); + ksft_print_msg("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC, + scan_time_ns % NSEC_PER_SEC); + ksft_print_msg("Average speed: %.3f MiB/s\n", (map_size / MB) / + ((double)scan_time_ns / NSEC_PER_SEC)); + ksft_test_result_pass("%s\n", __func__); munmap(map_ptr, map_size); - return KSFT_PASS; - -err_out: - printf("Not OK\n"); - munmap(map_ptr, map_size); - return KSFT_FAIL; } -static int ksm_cow_time(int merge_type, int mapping, int prot, int timeout, size_t page_size) +static void ksm_cow_time(int merge_type, int mapping, int prot, int timeout, size_t page_size) { void *map_ptr; struct timespec start_time, end_time; @@ -713,70 +600,57 @@ static int ksm_cow_time(int merge_type, int mapping, int prot, int timeout, size size_t page_count = 4000; map_ptr = allocate_memory(NULL, prot, mapping, '*', page_size * page_count); - if (!map_ptr) - return KSFT_FAIL; - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - return KSFT_FAIL; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); + for (size_t i = 0; i < page_count - 1; i = i + 2) memset(map_ptr + page_size * i, '-', 1); - if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) { - perror("clock_gettime"); - return KSFT_FAIL; - } + if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); cow_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC + (end_time.tv_nsec - start_time.tv_nsec); - printf("Total size: %lu MiB\n\n", (page_size * page_count) / MB); - printf("Not merged pages:\n"); - printf("Total time: %ld.%09ld s\n", cow_time_ns / NSEC_PER_SEC, - cow_time_ns % NSEC_PER_SEC); - printf("Average speed: %.3f MiB/s\n\n", ((page_size * (page_count / 2)) / MB) / - ((double)cow_time_ns / NSEC_PER_SEC)); + ksft_print_msg("Total size: %lu MiB\n\n", (page_size * page_count) / MB); + ksft_print_msg("Not merged pages:\n"); + ksft_print_msg("Total time: %ld.%09ld s\n", cow_time_ns / NSEC_PER_SEC, + cow_time_ns % NSEC_PER_SEC); + ksft_print_msg("Average speed: %.3f MiB/s\n\n", ((page_size * (page_count / 2)) / MB) / + ((double)cow_time_ns / NSEC_PER_SEC)); /* Create 2000 pairs of duplicate pages */ for (size_t i = 0; i < page_count - 1; i = i + 2) { memset(map_ptr + page_size * i, '+', i / 2 + 1); memset(map_ptr + page_size * (i + 1), '+', i / 2 + 1); } - if (ksm_merge_pages(merge_type, map_ptr, page_size * page_count, start_time, timeout)) - goto err_out; + ksm_merge_pages(merge_type, map_ptr, page_size * page_count, start_time, timeout); + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); - if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { - perror("clock_gettime"); - goto err_out; - } for (size_t i = 0; i < page_count - 1; i = i + 2) memset(map_ptr + page_size * i, '-', 1); - if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) { - perror("clock_gettime"); - goto err_out; - } + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) + ksft_exit_fail_msg("clock_gettime: %s\n", strerror(errno)); cow_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC + (end_time.tv_nsec - start_time.tv_nsec); - printf("Merged pages:\n"); - printf("Total time: %ld.%09ld s\n", cow_time_ns / NSEC_PER_SEC, - cow_time_ns % NSEC_PER_SEC); - printf("Average speed: %.3f MiB/s\n", ((page_size * (page_count / 2)) / MB) / - ((double)cow_time_ns / NSEC_PER_SEC)); - - munmap(map_ptr, page_size * page_count); - return KSFT_PASS; + ksft_print_msg("Merged pages:\n"); + ksft_print_msg("Total time: %ld.%09ld s\n", cow_time_ns / NSEC_PER_SEC, + cow_time_ns % NSEC_PER_SEC); + ksft_print_msg("Average speed: %.3f MiB/s\n", ((page_size * (page_count / 2)) / MB) / + ((double)cow_time_ns / NSEC_PER_SEC)); -err_out: - printf("Not OK\n"); + ksft_test_result_pass("%s\n", __func__); munmap(map_ptr, page_size * page_count); - return KSFT_FAIL; } int main(int argc, char *argv[]) { - int ret, opt; + int opt; int prot = 0; int ksm_scan_limit_sec = KSM_SCAN_LIMIT_SEC_DEFAULT; int merge_type = KSM_MERGE_TYPE_DEFAULT; @@ -788,6 +662,9 @@ int main(int argc, char *argv[]) bool merge_across_nodes = KSM_MERGE_ACROSS_NODES_DEFAULT; long size_MB = 0; + ksft_print_header(); + ksft_set_plan(1); + while ((opt = getopt(argc, argv, "dha:p:l:z:m:s:t:MUZNPCHD")) != -1) { switch (opt) { case 'a': @@ -879,70 +756,63 @@ int main(int argc, char *argv[]) return KSFT_SKIP; } - if (ksm_save_def(&ksm_sysfs_old)) { - printf("Cannot save default tunables\n"); - return KSFT_FAIL; - } + ksm_save_def(&ksm_sysfs_old); - if (ksm_write_sysfs(KSM_FP("run"), 2) || - ksm_write_sysfs(KSM_FP("sleep_millisecs"), 0) || - numa_available() ? 0 : - ksm_write_sysfs(KSM_FP("merge_across_nodes"), 1) || - ksm_write_sysfs(KSM_FP("pages_to_scan"), page_count)) - return KSFT_FAIL; + ksm_write_sysfs(KSM_FP("run"), 2); + ksm_write_sysfs(KSM_FP("sleep_millisecs"), 0); + if (numa_available()) + ksm_write_sysfs(KSM_FP("merge_across_nodes"), 1); + ksm_write_sysfs(KSM_FP("pages_to_scan"), page_count); switch (test_name) { case CHECK_KSM_MERGE: - ret = check_ksm_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, page_count, - ksm_scan_limit_sec, page_size); + check_ksm_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, page_count, + ksm_scan_limit_sec, page_size); break; case CHECK_KSM_UNMERGE: - ret = check_ksm_unmerge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, - ksm_scan_limit_sec, page_size); + check_ksm_unmerge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, + ksm_scan_limit_sec, page_size); break; case CHECK_KSM_ZERO_PAGE_MERGE: - ret = check_ksm_zero_page_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, - page_count, ksm_scan_limit_sec, use_zero_pages, - page_size); + check_ksm_zero_page_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, + page_count, ksm_scan_limit_sec, use_zero_pages, + page_size); break; case CHECK_KSM_NUMA_MERGE: - ret = check_ksm_numa_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, - ksm_scan_limit_sec, merge_across_nodes, page_size); + check_ksm_numa_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, + ksm_scan_limit_sec, merge_across_nodes, page_size); break; case KSM_MERGE_TIME: if (size_MB == 0) { - printf("Option '-s' is required.\n"); - return KSFT_FAIL; + ksft_test_result_skip("Option '-s' is required.\n"); + break; } - ret = ksm_merge_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, - ksm_scan_limit_sec, size_MB); + ksm_merge_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, + ksm_scan_limit_sec, size_MB); break; case KSM_MERGE_TIME_HUGE_PAGES: if (size_MB == 0) { - printf("Option '-s' is required.\n"); - return KSFT_FAIL; + ksft_test_result_skip("Option '-s' is required.\n"); + break; } - ret = ksm_merge_hugepages_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, - ksm_scan_limit_sec, size_MB); + ksm_merge_hugepages_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, + ksm_scan_limit_sec, size_MB); break; case KSM_UNMERGE_TIME: if (size_MB == 0) { - printf("Option '-s' is required.\n"); - return KSFT_FAIL; + ksft_test_result_skip("Option '-s' is required.\n"); + break; } - ret = ksm_unmerge_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, - ksm_scan_limit_sec, size_MB); + ksm_unmerge_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, + ksm_scan_limit_sec, size_MB); break; case KSM_COW_TIME: - ret = ksm_cow_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, - ksm_scan_limit_sec, page_size); + ksm_cow_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, + ksm_scan_limit_sec, page_size); break; } - if (ksm_restore(&ksm_sysfs_old)) { - printf("Cannot restore default tunables\n"); - return KSFT_FAIL; - } + ksm_restore(&ksm_sysfs_old); - return ret; + ksft_finished(); } From patchwork Mon Jan 15 07:32:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muhammad Usama Anjum X-Patchwork-Id: 13519363 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E9D38838; Mon, 15 Jan 2024 07:33:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="ilurDMY5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1705304000; bh=QBJld2GpTQR5BTBjcyDUEA5vStcxynZ+NNL+dIDUE1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ilurDMY55dNu+IPznIrJtRSBmJ9oU92YD3v1v5MzFV6U/QFwm7Zk6/rVuKGJZ650g ejf0dbWxs0F2zvXhunqQiPSBBZqwcrKX8KCzdESCNYegLqsitab83WV2gvZZnXf/XH 8s7cXDzXICTjyHseKcpqh9igWAhWI30TFWgJNNZjXd4r1q4JTStgIcjiZz/CbTKB0k RAB82h9ZvdqLe+hSNTlfT9sLFCPg+qYv1NvvvRf3dwVK9GpWgKLsFYJljn01k2DI4N e8pcP4Z1WDXgHZZr6QEHsJVBe03F4qJisJkQILrgE7N0h5iQ60YCmYrm/yhC5UU4lW WE0zZ6lo6+2Zg== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: usama.anjum) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 77B4A37813DD; Mon, 15 Jan 2024 07:33:18 +0000 (UTC) From: Muhammad Usama Anjum To: Andrew Morton , Shuah Khan Cc: Muhammad Usama Anjum , kernel@collabora.com, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 7/7] selftests/mm: config: add missing configs Date: Mon, 15 Jan 2024 12:32:43 +0500 Message-ID: <20240115073247.1280266-7-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240115073247.1280266-1-usama.anjum@collabora.com> References: <20240115073247.1280266-1-usama.anjum@collabora.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add configurations which are needed for - hugetlb-read-hwpoison - ksm_functional_test and ksm_test Signed-off-by: Muhammad Usama Anjum --- tools/testing/selftests/mm/config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/selftests/mm/config b/tools/testing/selftests/mm/config index 4309916f629e..d16a72036eb7 100644 --- a/tools/testing/selftests/mm/config +++ b/tools/testing/selftests/mm/config @@ -7,3 +7,6 @@ CONFIG_TEST_HMM=m CONFIG_GUP_TEST=y CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_MEM_SOFT_DIRTY=y +CONFIG_MEMORY_FAILURE=y +CONFIG_HWPOISON_INJECT=y +CONFIG_KSM=y