From patchwork Thu Jan 11 11:56:30 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: 762598 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 24C9F154AC; Thu, 11 Jan 2024 11:57:36 +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="ZSa9qy7T" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1704974255; bh=rRQZLwAtR4o/VCOAcxTzVSxdZ70bLgI9faWJJSJCsAc=; h=From:To:Cc:Subject:Date:From; b=ZSa9qy7Tl9zR64Qk9SDK6NPPOQBrzuuwsbhm3ASkRxLSEX697ewBw5gAVzlmlRKPT GOysylcxC/VF0/iodKdVsdSwxKl10VbKYgjyh95ntez4wUTALdQgndOCTgoo8MX2Wy 7mEHqSeuw59iX+8bFLDK6Meh50irC3QYn5AaPZVbMXs5Ey1+/LWwHQ66snbhCZgLA5 VBzcW08jGuJFn0SjoUXr/T3OMXil63gF9e0K2dNOg7LgLs8ik2OBVww6D/G+Mnn3XC figD78k9CAo2SC4FXRj5LNOotc1bojTHrP5AutXeI2mLokdmkKD2xWyTo5zIpOWylE wCDITlgc9Bp6w== 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 A519A3781182; Thu, 11 Jan 2024 11:57:32 +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 1/7] selftests/mm: hugepage-shm: conform test to TAP format output Date: Thu, 11 Jan 2024 16:56:30 +0500 Message-ID: <20240111115639.3981970-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 Thu Jan 11 11:56:31 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: 762069 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 7D7F4156DD; Thu, 11 Jan 2024 11:57:40 +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="YyH92dge" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1704974258; bh=o1IUw1D3iI8Y90Z4hsu7JwinzA97QoWLS2TEa1p944o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YyH92dgeAon6MwJA8uNb6o5qO2XLK/X0xqX53PQOwHgbvmzvZEA/ZHU0gFtlOCL+9 fLPPOgRMZsNaVXjBs7X3OUFc9fexxdlEVBkUQkJcGBGk6Msly8uNdz1yMydkeHFBqp jMYJD+Dh8fGRJjCP2r9YNXQXb4viVw53YPVi1oNhbTnzgNXucKPlmIbmcUHwD/sieO hkya9Sc2SIzVDYnP2d964GmUZRCEsptHsiL4dZVaqqStTT29LhCOw5fqEBKPbnECBr +n4eP+O2zQ/YZpCzgHR5r1O15fX/cPgJkiWj9GDRvEbScZpzEm5XVyPh6c3UcYj6dD Yx/zQuE4K/Bog== 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 263693781184; Thu, 11 Jan 2024 11:57:35 +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 2/7] selftests/mm: hugepage-vmemmap: conform test to TAP format output Date: Thu, 11 Jan 2024 16:56:31 +0500 Message-ID: <20240111115639.3981970-2-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240111115639.3981970-1-usama.anjum@collabora.com> References: <20240111115639.3981970-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 Thu Jan 11 11:56:32 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: 762597 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 99FBC15AC2; Thu, 11 Jan 2024 11:57:43 +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="NM1NCQeB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1704974262; bh=COa40clGVU4MtL/28A+nBi1NMczqiOUny8LpI5UZWfU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NM1NCQeBuxL9M0KRJ52VGVvirZJhfvb8GqVEDvYAF+Ir6bS2e6PNztvIcNPhghvcw lQ0Wgqjh/M96ncq3zrwvx2qeTJSLSQnhEBi20DhWNOZ3szD6++1hVtd2wDKDo2OYZ5 m+o8EB8bjo1G6Ida9vejFVwaWtiki9Yqq6jZqBpTwrMQoKXwkXpW52wTpIFRBIescf dtg7IWfcxfvf2kq7OQmI7pGZK/a9ziPmiq/lHbkvnnL95P7dsdcPNQ+KmJqZ5mMrwK 8M6jO+ooX1/Sz4b5deZxhb0JkZbHcPXLIBWJO56ofw7q0V1gUiVxxsY3j0/xU6Bzpg JyMvDTS/VpZ/g== 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 D0B603781FCF; Thu, 11 Jan 2024 11:57:39 +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 3/7] selftests/mm: hugetlb-madvise: conform test to TAP format output Date: Thu, 11 Jan 2024 16:56:32 +0500 Message-ID: <20240111115639.3981970-3-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240111115639.3981970-1-usama.anjum@collabora.com> References: <20240111115639.3981970-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 Thu Jan 11 11:56:33 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: 762068 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 25B8315AD4; Thu, 11 Jan 2024 11:57:46 +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="XmJFNTfT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1704974265; bh=WarJsqa996nSABnuJbtC8OtcSiQsXtPuWG8VJhsvO5U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XmJFNTfTuaaTqpZ6+Jz6EDi75kFwwZsfz1nDnKrfPy6lPNUqWSTntjOWpY/5+CHCm w5ZI7ub7DZbLZf2EgBIQqOq98ANIPP4EZG6ya8ErlH51PpdG8UhUdW0PkeZjtWhx7b AXD/dnOtahSl6F5/Y3JLXZ6IO4oV07cKBsHXuoNzlBGhAC1uSSydrlpg8oArTA8nfu GDhN8pk0RSN4C7b2ufR2GrZX0EBvGU4IRtyCrStqUaHGh0MaKeR2Fa90akt2xe2VPU RtXrltFwJf6STKWWQvrp5a2EkfQ8UzSE9lf2QjUFC7Ptj7gFtarN4zVIKh+bh5JYAW twEpYHnykw1Og== 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 4F5193781FE5; Thu, 11 Jan 2024 11:57:43 +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 4/7] selftests/mm: khugepaged: conform test to TAP format output Date: Thu, 11 Jan 2024 16:56:33 +0500 Message-ID: <20240111115639.3981970-4-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240111115639.3981970-1-usama.anjum@collabora.com> References: <20240111115639.3981970-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/khugepaged.c | 378 ++++++++++-------------- 1 file changed, 160 insertions(+), 218 deletions(-) diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c index 829320a519e7..0ed82b8b31fa 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,13 @@ 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); +// 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 @@ -935,18 +885,14 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o 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 +909,13 @@ 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); +// exit_status += WEXITSTATUS(wstatus); - 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 @@ -985,19 +931,15 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops 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 +950,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 +965,13 @@ 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); +// exit_status += WEXITSTATUS(wstatus); - 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 +1025,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 +1131,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 +1159,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 +1223,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 Thu Jan 11 11:56:34 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: 762596 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 57F5415AE9; Thu, 11 Jan 2024 11:57:50 +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="jZICOv3N" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1704974268; bh=Q7PZrTRFHS+3g0cEby4tiM7SrNkkljeZa5WEc+ropxk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jZICOv3NfHOcHk3L3ibVa54fHzEWaWpmrqw+OyALrfVwpJj3fowlpm5FmA8OXilTm JuDXPWf8FHZXfLDkvSSk93BJu/AKKILDz4KV0TZ2HEi5QjPJ1lYv1ONbc805TNP4HP u9wu844LHzBJmWLdsWUHY3mZ7pdYSM0sbMagYCFIPfWHJyl4vwuJtVrUn5hDmLdjoL J4wUG9UoS4HwH9EzVPcf7WDmTTX7zPYLcTN9YHraKMqz9pF+WwLh47Erf7YbGXkGLd OS2b7ovLFrwMruYwuRnH1TVTxsWC4AtmQQ77SD5/dULWgCpswfCo4sJYmf83OwfWTu pfngapfwOvPdQ== 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 62B213781FCD; Thu, 11 Jan 2024 11:57:46 +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 5/7] selftests/mm: hugetlb-read-hwpoison: conform test to TAP format output Date: Thu, 11 Jan 2024 16:56:34 +0500 Message-ID: <20240111115639.3981970-5-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240111115639.3981970-1-usama.anjum@collabora.com> References: <20240111115639.3981970-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 --- 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, 56 insertions(+), 60 deletions(-) diff --git a/tools/testing/selftests/mm/hugetlb-read-hwpoison.c b/tools/testing/selftests/mm/hugetlb-read-hwpoison.c index ba6cc6f9cabc..193ad7275df5 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,9 +75,9 @@ 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"); return false; @@ -86,7 +86,7 @@ static bool seek_read_hugepage_filemap(int fd, size_t len, size_t wr_chunk_size, 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"); @@ -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_print_msg(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,15 @@ 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_print_msg(PREFIX ERROR_PREFIX "ftruncate failed: %s\n", strerror(errno)); 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_print_msg(PREFIX ERROR_PREFIX "mmap for primary mapping failed: %s\n", + strerror(errno)); goto done; } @@ -162,7 +163,8 @@ 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_print_msg(PREFIX ERROR_PREFIX "ftruncate back to 0 failed : %s\n", + strerror(errno)); status = TEST_FAILED; } @@ -179,14 +181,15 @@ 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_print_msg(PREFIX ERROR_PREFIX "ftruncate failed: %s\n", strerror(errno)); 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_print_msg(PREFIX ERROR_PREFIX "mmap for primary mapping failed: %s\n", + strerror(errno)); goto done; } @@ -201,7 +204,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_print_msg(PREFIX ERROR_PREFIX "MADV_HWPOISON failed: %s\n", strerror(errno)); goto unmap; } @@ -228,7 +231,8 @@ 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_print_msg(PREFIX ERROR_PREFIX "ftruncate back to 0 failed: %s\n", + strerror(errno)); status = TEST_FAILED; } @@ -240,27 +244,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 +282,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 Thu Jan 11 11:56:35 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: 762067 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 E4D2615E89; Thu, 11 Jan 2024 11:57:53 +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="CeNOj0Ou" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1704974272; bh=TMVRXrb1tG3+I18SJgfvyHfjDUNm4khJlToJ4CS96e8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CeNOj0Ou83o8PjgWUj5t1B4zOUJFH4e4+MsO3TjXL+hGObn6Pe2AIqM8XU2/UN1nb VCZywtb4RmMmHveApixvo7BaanL36vdpwP1dnkN7hVLviBzjF5W+Iv0elZpGxjE30B hyB/F7GdUI8qo/9uQSNDfL+jYRZwYVTlhd17jzoaO2sm1iWmGPH8F1w8J/WjkQ6hpa ihV9b6YkkZTuD5jWU6YW77odEFElc+wyeVdf/nXd8g1L/zmlrDteFYEkicsQuTkVmA tDJj/2IGXEo1r9JFZyfLLcUEOU+4NDCLpCei7PvCyAtiYLfNIxnI2AXGDQVqqAQQFg 5cO7B82yW+drw== 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 141B63781182; Thu, 11 Jan 2024 11:57:49 +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 6/7] selftests/mm: ksm_tests: conform test to TAP format output Date: Thu, 11 Jan 2024 16:56:35 +0500 Message-ID: <20240111115639.3981970-6-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240111115639.3981970-1-usama.anjum@collabora.com> References: <20240111115639.3981970-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 Thu Jan 11 11:56:36 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: 762595 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 DBACE156EF; Thu, 11 Jan 2024 11:57:56 +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="HcZQm++z" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1704974275; bh=QBJld2GpTQR5BTBjcyDUEA5vStcxynZ+NNL+dIDUE1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HcZQm++zxBAqODVkQcQzlRQWtRXmGhe2GZU51NnFX9OC1eg3kH0GlyjwugmTqUPsa 4/rqzyX5ysXYXj7JLExPcHTYFM92F40hQat6YSPbufJIhA3pyWMhlrVPuCiH5mZd6J b1WfJUddarkgH8MG0zZZzSJrCwcbOT6Haln+FMYK1d6VsjppnrKYW9xBYFMNqmgTIi dA5/zUFwfT2q5NdvdpRQmszuVLonTC3C2HiTfUAJhnvzCgCGcmcb5ZrUHRairkSsAX Xe3BHVupOc1dOeXEVF2urrLIUa0D5wIAcj2ocq6Wx++dp54UdQ7Uft6Jn381x6jBRW X0aHU0hiO+jWA== 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 0CF333781184; Thu, 11 Jan 2024 11:57:52 +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 7/7] selftests/mm: config: add missing configs Date: Thu, 11 Jan 2024 16:56:36 +0500 Message-ID: <20240111115639.3981970-7-usama.anjum@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240111115639.3981970-1-usama.anjum@collabora.com> References: <20240111115639.3981970-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