From patchwork Wed Nov 22 16:29:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Roberts X-Patchwork-Id: 13465127 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 3D24FC61D9B for ; Wed, 22 Nov 2023 16:30:32 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CF6768D0049; Wed, 22 Nov 2023 11:30:31 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id CCD608D0008; Wed, 22 Nov 2023 11:30:31 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B70458D0049; Wed, 22 Nov 2023 11:30:31 -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 A5E4D8D0008 for ; Wed, 22 Nov 2023 11:30:31 -0500 (EST) Received: from smtpin27.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 61D1C120DDC for ; Wed, 22 Nov 2023 16:30:31 +0000 (UTC) X-FDA: 81486128262.27.D1EB73C Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf07.hostedemail.com (Postfix) with ESMTP id 5072340004 for ; Wed, 22 Nov 2023 16:30:29 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf07.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1700670629; 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=2VGC7c1ft+lgk5wsEVLPeYQiDE3/AUylWLHZb/XuNQJnAsBEzwkEM1uqanrB6glzxobG7T Lv6MGVuVxsqseA7c+/qCod/thWx+awx6n+S3EEq3g0XEpaSngkBOFcvBnDkXicaSb3Fu4z Qgw5tXHOat0OlnFkqhyv7vJaIlPjQQo= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf07.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1700670629; a=rsa-sha256; cv=none; b=5/CnXXrcdZcNfkxFqvbHWysMcSPSKKvW7YO0UNvDOWNyvBoV61cXIsgmta28ooiSwFYeFF pjWGYaSFJJJbOE3WHgj773anDb0/xZiaT2gVa57TXCzuuNsv+0pCxRKRnznWs505X8mFr8 F+/V5MjYabFSB7lwkuGYWlBDoXupxsA= 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 5F4E2C15; Wed, 22 Nov 2023 08:31:15 -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 E66B83F73F; Wed, 22 Nov 2023 08:30:25 -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: [RESEND PATCH v7 08/10] selftests/mm/khugepaged: Enlighten for small-sized THP Date: Wed, 22 Nov 2023 16:29:48 +0000 Message-Id: <20231122162950.3854897-9-ryan.roberts@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231122162950.3854897-1-ryan.roberts@arm.com> References: <20231122162950.3854897-1-ryan.roberts@arm.com> MIME-Version: 1.0 X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 5072340004 X-Stat-Signature: c1nx5o8qx831busjauzapz5f1kzo1icc X-Rspam-User: X-HE-Tag: 1700670629-543684 X-HE-Meta: U2FsdGVkX19AFGWdIgNKXAw29f1qOuwYANV4djM41v6WTK6kIHEttTA8J68bqxgEcE6TV/XM0ph5OOc7aGoq6CaHJ11NQtGOmiMeTBhWw+VLKcH3f9NvFShRv7c+NRyb0yWGdiFMj/u4rZ23aueKjsNoqd/Pf0SqkVDZLSjvTTgIhboPU3soc3kNoJSbTdQop4w3WUTewatPCdRjZq05uw5Q2NnATHRG01ursFxZjH99K8RY5HVIv0UXhnx/RZfjSG/0RTkAMenoVu0ps/l3MXr2iVhu/sDlz2bOBH+5wpQIbZR10TIQcNZLIGXYW21eLovpL0yzcFkwIJHIj4J644I/m6ZJlYHwo7IlOyWuixe4umEV8Ie9JS6TZ5Xh9y+rbcUXVakLG01b6FaD3hPV9vMn5LpM4O69NpqUe+Fz5QR8YWiVpjRqv6A7X7hsIT4QcO8orOb4ZfG6h7TgId/dLqRMm9JgVBkBAqyLV5QgE8lZp9DvNvDELX9CXg4nBmAR0vIfKVOoiDvzijE9e+gfsIPbQ36NN4ley6pBJDxERzNcGUXBQn9VDgjwIL24kd4gEhWO2ivcDS+de6QS6b4eSI02qU4YdnrGIAPgJEgp4Jw5DrAj3V1DglfEw1/FwVGRwwUgJKB3LFLjILU5LdoOmGbV3VorzYzZoRhXyair4sfO0Yt01YolW29ZhgqwK9eFhVUFz5FjkFgbASRsNJLMsOQ8HDRi6nWD9a/tNFNI0WpIaHCLdS4p2xFV/WQ2K4X96GFslIMPsYsPVYX33Vrd8UyiUztgYbs5dDVLDqHNsZaCstceQkpMuUz4amyTBCP1btH/0ktfdJzRz8/9oyAEJrP7DD/zL4guUveeH9moTywQW34RH5gy+NMiwUsJyCQYnwOG5Cz7RB7KX3+8Nd4lo3GCt7rlQY0Y9LicCfKtEJLQ4g5VMjPBLHH6WP2U0t4icyAMmz0fRb/CnT7XhQe 3Z2xm/mp rekvfmSQG/f5uU+GBof9cGga1Q4vTu1tyCBNeEz2YFUa9I6a2F9p/TFfJaVTtvpb/Wsv3rchlS+O1ixuysutyK60s/1c99vTrBqqvt794jJv1/MX96DWYIFRA0Z1Xt9LZurCyvrVfuw4TK9mcpcY9TxEcsGwyLPmJSUWzk756drGD5QYlyJkQBfcz94heuUwD4RHTZMcSilEWxbxuCeyV5BNHSc1TuikZZQQHLuIxa1vO3EM= 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(-) -- 2.25.1 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