From patchwork Wed Nov 15 13:27:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Roberts X-Patchwork-Id: 13456682 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E8A4C48BF9 for ; Wed, 15 Nov 2023 13:28:25 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 269A06B0349; Wed, 15 Nov 2023 08:28:25 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 2183D6B034A; Wed, 15 Nov 2023 08:28:25 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 106FF6B034B; Wed, 15 Nov 2023 08:28:25 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id F19B96B0349 for ; Wed, 15 Nov 2023 08:28:24 -0500 (EST) Received: from smtpin22.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id C4DA6120778 for ; Wed, 15 Nov 2023 13:28:24 +0000 (UTC) X-FDA: 81460267728.22.5B3A3EA Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf27.hostedemail.com (Postfix) with ESMTP id 1B4CB40029 for ; Wed, 15 Nov 2023 13:28:22 +0000 (UTC) Authentication-Results: imf27.hostedemail.com; dkim=none; spf=pass (imf27.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com; dmarc=pass (policy=none) header.from=arm.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1700054903; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zWwgPOnMyq5HoZd3FqMCvj8FMHXJmiw0mbIe3GqzCJ4=; b=3wwK8AYggYSCzUlitP0t5a2uQiuI9fhpZssmVGaA5IJAdBJbF0R57VZyFbKn8JBoYk5E3u tx/SKQfVXQEQ0COnjBs8himNl/YQMOE5ZCZAQt/ea1I7DM0YwKeIXKT1KD8FBPAC7xBW1Q WOwcmhdtpWE6l+0jQFzrmbQ+wJWzrv4= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1700054903; a=rsa-sha256; cv=none; b=bERB+WeADg8u/wHoiTXy2c9Ppj1ClLw7a9uliI48EX9epVeumRLS8TQPZ+Ip4xf6IVNcVk OLhR65ua3inepRqJBEkGlXbQ6krk05TbZG+KRkm16+xKHeyk+KBG+AP3QHKqWnIFQPGkDW FByjoZlK4xS8rvMG/AT6B23od4vo5PI= ARC-Authentication-Results: i=1; imf27.hostedemail.com; dkim=none; spf=pass (imf27.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com; dmarc=pass (policy=none) header.from=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E9C04DA7; Wed, 15 Nov 2023 05:29:07 -0800 (PST) Received: from e125769.cambridge.arm.com (e125769.cambridge.arm.com [10.1.196.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7A2383F7B4; Wed, 15 Nov 2023 05:28:19 -0800 (PST) From: Ryan Roberts To: Andrew Morton , Matthew Wilcox , Yin Fengwei , David Hildenbrand , Yu Zhao , Catalin Marinas , Anshuman Khandual , Yang Shi , "Huang, Ying" , Zi Yan , Luis Chamberlain , Itaru Kitayama , "Kirill A. Shutemov" , John Hubbard , David Rientjes , Vlastimil Babka , Hugh Dickins , Kefeng Wang Cc: Ryan Roberts , linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 08/10] selftests/mm/khugepaged: Enlighten for small-sized THP Date: Wed, 15 Nov 2023 13:27:32 +0000 Message-Id: <20231115132734.931023-9-ryan.roberts@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231115132734.931023-1-ryan.roberts@arm.com> References: <20231115132734.931023-1-ryan.roberts@arm.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 1B4CB40029 X-Rspam-User: X-Stat-Signature: x59s53xbfgagxr7gyyctpj33i648dwee X-Rspamd-Server: rspam03 X-HE-Tag: 1700054902-512542 X-HE-Meta: U2FsdGVkX18Vx8Lv5xnSsoS3A7yHEkGEIxMitZTVhzNSh6CdjFtLFztAfVMOit0Hy34VEsLiiQ0x7XuuMLhBqdEAyWnA0f5NKzuu5+YF0/+fG/dJ1OpExCWddN1sbl4U29JRrXkzbm2SLIW44rbAiAbnoXUv1pW069F8rL4IxzIIj2FVsIq/2Rs8h6dYjQZ7yA8WqUnlYwfMUiH34h9nMQdGwRl5J0WRd/uxuzfZKO4fTY+lZWQAcwCUpBYoDyaHKoBjPZT398f2XKg2yvloPRIKvjmmbC7mzpMhKT39KFvW68qMlCqtRhzvem+lkzusstAXOJtMJaN+SNQZ6/Pyx5hgDwFGKr5ph/Zs2p7SnEcpYIQOKTo1HzNtbj0ch4i2/W4aSafV9/MARrcOTGieI+BpGFdEdGW68Acw9y4CtUIaJJGE7A7yEKG2hiRCC2Ypj4rNJGNuX1sUjJDK86GfcVEdncPAdc4dErpSlh/u+KHc8fnsdCTL4If2DXjAoZ3CpPmZv+jcMKMqkr3wmzPztCtont6T4xTer8OSH26KS12/SLlS9Bz++NpZLWC++GcF8WNyDGDzwfahQgiueNchMbdD/w3gHC7laSX1tr60GUDPUA5uC4k2ADzP0CRDhH1pprtpvQMUlKRrZyz8V8jhtMg2mA8T3u9YhzNL20GxJUEj82ETBHUOShp8zgqq9Jr/hTWUAokDx8TOT4HYywdB85RB0b5rDGsnqXItqDiKAllqw4XZSu3jTwnWUZyhapFPCEDgdpvmDMuEjtCZyelhU+L5aYLQAcsX0kGvg7W6a9jJ4rv6Ms6TEpkhhPd743lfjcANDln27WjeXL8d9ZJtBBPUrLFLRoxCBMwOmtjEqFg+e7tnbdfuHj7dWEc7EiKVkeqY+fmHVzFfgV1Md++hZJW0L25B/p9Ikjm32vGbyctPxbWme+LVJEWrZsLgAYw4192+Ny06pHuyBJ/ZEu2 Sr9ZCM65 VgMvokPuH2lbtJcSdLJx9PstlU1nNzbYsSOzMMw0S3nrHS8rHJwcp9hHLm6yO9uocWhjyif6VeqIMjX8FdqWLoD3qFoFXM5IJwmGF+cVDXRaN62FMc1gXqsx0sjDCpqvOBTLmGpKl7lx4lBqIK5BwB68w8fyoBeE001/DPyox3yVHOo5kXwXoi4LgbYv8Ry2jeHB6jrkOTnXx9O/CJtqiltEkGvmTuYO2lKDrUDLoGF4J/lc= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: The `collapse_max_ptes_none` test was previously failing when small-sized THP had enabled="always". The root cause is because the test faults in 1 page less than the threshold it set for collapsing. But when using small-sized THP we "over allocate" and therefore the threshold is passed, and collapse unexpectedly succeeds. Solve this by enlightening khugepaged selftest. Add a command line option to pass in the desired small-sized THP that should be used for all anonymous allocations. The harness will then explicitly configure small-sized THP as requested and modify the `collapse_max_ptes_none` test so that it faults in the threshold minus the number of pages in the configured small-sized THP. If no command line option is provided, default to order 0, as per previous behaviour. I chose to use an order in the command line interface, since this makes the interface agnostic of base page size, making it easier to invoke from run_vmtests.sh. Signed-off-by: Ryan Roberts --- tools/testing/selftests/mm/khugepaged.c | 48 +++++++++++++++++------ tools/testing/selftests/mm/run_vmtests.sh | 2 + 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c index 473ba095cffd..4d24f2eb158e 100644 --- a/tools/testing/selftests/mm/khugepaged.c +++ b/tools/testing/selftests/mm/khugepaged.c @@ -28,6 +28,7 @@ static unsigned long hpage_pmd_size; static unsigned long page_size; static int hpage_pmd_nr; +static int anon_order; #define PID_SMAPS "/proc/self/smaps" #define TEST_FILE "collapse_test_file" @@ -607,6 +608,11 @@ static bool is_tmpfs(struct mem_ops *ops) return ops == &__file_ops && finfo.type == VMA_SHMEM; } +static bool is_anon(struct mem_ops *ops) +{ + return ops == &__anon_ops; +} + static void alloc_at_fault(void) { struct thp_settings settings = *thp_current_settings(); @@ -673,6 +679,7 @@ static void collapse_max_ptes_none(struct collapse_context *c, struct mem_ops *o int max_ptes_none = hpage_pmd_nr / 2; struct thp_settings settings = *thp_current_settings(); void *p; + int fault_nr_pages = is_anon(ops) ? 1 << anon_order : 1; settings.khugepaged.max_ptes_none = max_ptes_none; thp_push_settings(&settings); @@ -686,10 +693,10 @@ static void collapse_max_ptes_none(struct collapse_context *c, struct mem_ops *o goto skip; } - ops->fault(p, 0, (hpage_pmd_nr - max_ptes_none - 1) * page_size); + ops->fault(p, 0, (hpage_pmd_nr - max_ptes_none - fault_nr_pages) * page_size); c->collapse("Maybe collapse with max_ptes_none exceeded", p, 1, ops, !c->enforce_pte_scan_limits); - validate_memory(p, 0, (hpage_pmd_nr - max_ptes_none - 1) * page_size); + validate_memory(p, 0, (hpage_pmd_nr - max_ptes_none - fault_nr_pages) * page_size); if (c->enforce_pte_scan_limits) { ops->fault(p, 0, (hpage_pmd_nr - max_ptes_none) * page_size); @@ -1076,7 +1083,7 @@ static void madvise_retracted_page_tables(struct collapse_context *c, static void usage(void) { - fprintf(stderr, "\nUsage: ./khugepaged [dir]\n\n"); + 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"); @@ -1085,15 +1092,34 @@ static void usage(void) 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: Small-sized THP size, expressed as page order.\n"); + fprintf(stderr, "\t\t Defaults to 0. Use this size for anon allocations.\n"); exit(1); } -static void parse_test_type(int argc, const char **argv) +static void parse_test_type(int argc, char **argv) { + int opt; char *buf; const char *token; - if (argc == 1) { + while ((opt = getopt(argc, argv, "s:h")) != -1) { + switch (opt) { + case 's': + anon_order = atoi(optarg); + break; + case 'h': + default: + usage(); + } + } + + argv += optind; + argc -= optind; + + if (argc == 0) { /* Backwards compatibility */ khugepaged_context = &__khugepaged_context; madvise_context = &__madvise_context; @@ -1101,7 +1127,7 @@ static void parse_test_type(int argc, const char **argv) return; } - buf = strdup(argv[1]); + buf = strdup(argv[0]); token = strsep(&buf, ":"); if (!strcmp(token, "all")) { @@ -1135,11 +1161,13 @@ static void parse_test_type(int argc, const char **argv) if (!file_ops) return; - if (argc != 3) + if (argc != 2) usage(); + + get_finfo(argv[1]); } -int main(int argc, const char **argv) +int main(int argc, char **argv) { int hpage_pmd_order; struct thp_settings default_settings = { @@ -1164,9 +1192,6 @@ int main(int argc, const char **argv) parse_test_type(argc, argv); - if (file_ops) - get_finfo(argv[2]); - setbuf(stdout, NULL); page_size = getpagesize(); @@ -1183,6 +1208,7 @@ int main(int argc, const char **argv) default_settings.khugepaged.max_ptes_shared = hpage_pmd_nr / 2; default_settings.khugepaged.pages_to_scan = hpage_pmd_nr * 8; default_settings.hugepages[hpage_pmd_order].enabled = THP_GLOBAL; + default_settings.hugepages[anon_order].enabled = THP_ALWAYS; save_settings(); thp_push_settings(&default_settings); diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh index 00757445278e..f3fa2238daef 100755 --- a/tools/testing/selftests/mm/run_vmtests.sh +++ b/tools/testing/selftests/mm/run_vmtests.sh @@ -359,6 +359,8 @@ CATEGORY="cow" run_test ./cow CATEGORY="thp" run_test ./khugepaged +CATEGORY="thp" run_test ./khugepaged -s 2 + CATEGORY="thp" run_test ./transhuge-stress -d 20 CATEGORY="thp" run_test ./split_huge_page_test