From patchwork Wed Jul 26 09:51:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Roberts X-Patchwork-Id: 13327785 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 3E351C001DE for ; Wed, 26 Jul 2023 09:52:16 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id AD66F6B007D; Wed, 26 Jul 2023 05:52:15 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id AAE236B007E; Wed, 26 Jul 2023 05:52:15 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 94E836B0080; Wed, 26 Jul 2023 05:52:15 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 8260C6B007D for ; Wed, 26 Jul 2023 05:52:15 -0400 (EDT) Received: from smtpin25.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 6020F1601FA for ; Wed, 26 Jul 2023 09:52:15 +0000 (UTC) X-FDA: 81053297430.25.3DA549F Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf18.hostedemail.com (Postfix) with ESMTP id 99F351C000E for ; Wed, 26 Jul 2023 09:52:13 +0000 (UTC) Authentication-Results: imf18.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf18.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=1690365133; 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=YAYuga94X0gYR3iPhGr2eIcuvk2ipwl7xIVV/NAaqzI=; b=at3u/iiLa9/054JtO1TJQRsjlozT8t0E2Ih0bfyehcFlzviopPIbUWpQOYmabP6LN7jrQ6 nCNMDXLevUMBCHcwMQysxZ0AAKFS3kIaYub+L2RXlOnafx/aXFtB2t8aLxD+lMTAP0amX2 CLmSJ+SS/TVeUa/2jiljbSsRgT7LhTc= ARC-Authentication-Results: i=1; imf18.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf18.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=1690365133; a=rsa-sha256; cv=none; b=e5i2sNGTzDOW4TcdkSU9agoqOoWK7GBL/Zfq5e+aGdKLHcEvXtcyGV4avx29+Ph3qtxbtO dXIBszqCSY8venpLh610dB5eDOipTxl5APaDm7WzGR4G58hXGX6VRUzUBEVCEwRgUAUDU9 8SiGdcyFCwBWpeXr8DkKuMaPVRuCmHQ= 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 8860416A3; Wed, 26 Jul 2023 02:52:55 -0700 (PDT) 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 4CFB33F67D; Wed, 26 Jul 2023 02:52:10 -0700 (PDT) From: Ryan Roberts To: Andrew Morton , Matthew Wilcox , Yin Fengwei , David Hildenbrand , Yu Zhao , Catalin Marinas , Will Deacon , Anshuman Khandual , Yang Shi , "Huang, Ying" , Zi Yan , Luis Chamberlain , Itaru Kitayama Cc: Ryan Roberts , linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 5/5] selftests/mm/cow: Add large anon folio tests Date: Wed, 26 Jul 2023 10:51:46 +0100 Message-Id: <20230726095146.2826796-6-ryan.roberts@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230726095146.2826796-1-ryan.roberts@arm.com> References: <20230726095146.2826796-1-ryan.roberts@arm.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 99F351C000E X-Rspam-User: X-Rspamd-Server: rspam02 X-Stat-Signature: 6zkcd7kkm3hxn9irq48i8t89w5gjxi8e X-HE-Tag: 1690365133-200382 X-HE-Meta: U2FsdGVkX194NxDYLI3ELpTRgarPq8kFGj1BG23ob267VmdcYLEeg3TC5GBJO6ied9nTV+sNDLnEHkvm+aainKYRD5c2sehfvjU3twph2If5/xU/b10VpOXctFRbiT29Mh01uoBwSB7WlCtd4SQqSWZFRymrWGCrUW9d12bo+rBXLwJ/Be1xsPErz8bDnhna/nbDpzGSPovO1XuR/Yc0OIwe9xW2oGd3EJi60+DG85+NAVu3AxAK7vIfYYhvd0YaQ30VyE7617gfmhrmaNO4MBfXz5y3mPc4i0+ZQcpFQl+FV5nKLyTbz2GrSfM6WuwudXz4XwRY5zFd9BVA8aG5nynFBkvl3GqLPIFan3w0OtiDeGm/35qERQaBHdpxsZWkN6jloFErJ/h9hi2ecajHBYxmF0THsUzjA/nGCDd+R4S1fl43WchmrgQi6bB6rwqbBWvXq4Iu8gJnqQfhSHiokL1D/oA3wTiZKOMY1rJK9A+dYCpor+WIXcUyDKlUgVtFnuXCp1J71kDsox1e/zou8VhOU8QTvWdr8NCpL/5eGwXp3RAeX+55GUAx+gt+qTwukHTL9YVE/VxXUYMdt9y6ckgYLPtgSuWCsX+X2kVK8bgm+iG71HB7uunL+M7ixj2hR1qZP5wwN/BR58jSSQPMWoKDKdUxVVTKFqOPC/xZivNcjjMT/gzdt3QU/7CWabXp0ZPmxAPJ38cdU4L+t2Ybo/oqPGYDs0bBY7QWi8s1EDWMP7nHF354a0ow37wwIK/LKGaq+giBh3JbGNZ6DsAj5aOL9iB9p2Zq9f2PeWnxf1n6SaXoUSJayVnboGPvsfr5SNfuqxjBTR3R8F1HxikOhXV7bjyfFeSbaqHUTvOdv89WaS9+Cey1kWqWYumCXe2uWW6HNVRQCRR5hY7obGZFxS9QFApXgjKokG8RJYb5rtYEOr62ViCAB7jAbv2mLcKtXx7ybyYjPtubGC3+nOv mU9FqSqX OLAbUNdTldCv/P6ukqEREO4IeFTQOB1a+CDMNCCqpy49iCW+kpqBpJsDxu12hT0U7Sw+3M46MkEVNlo3OdbEwIQq33G/A3FvWszMssi4jqaFLJ02Q6tniUkKO1LOFZvULcb9z2orBRvttoo3/Q9fI8nMp7t9V8pVyPCJYxfK1hhteHcouzt3KpyOjMnXwmp6B1PTWEeHV5cProOUwVnaLMe7vN4sa3IcG7GAv 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: Add tests similar to the existing THP tests, but which operate on memory backed by large anonymous folios, which are smaller than THP. This reuses all the existing infrastructure. If the test suite detects that large anonyomous folios are not supported by the kernel, the new tests are skipped. Signed-off-by: Ryan Roberts --- tools/testing/selftests/mm/cow.c | 111 +++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c index 304882bf2e5d..932242c965a4 100644 --- a/tools/testing/selftests/mm/cow.c +++ b/tools/testing/selftests/mm/cow.c @@ -33,6 +33,7 @@ static size_t pagesize; static int pagemap_fd; static size_t thpsize; +static size_t lafsize; static int nr_hugetlbsizes; static size_t hugetlbsizes[10]; static int gup_fd; @@ -927,6 +928,42 @@ static void run_with_partial_shared_thp(test_fn fn, const char *desc) do_run_with_large(fn, LARGE_RUN_PARTIAL_SHARED, thpsize); } +static void run_with_laf(test_fn fn, const char *desc) +{ + ksft_print_msg("[RUN] %s ... with large anon folio\n", desc); + do_run_with_large(fn, LARGE_RUN_PTE, lafsize); +} + +static void run_with_laf_swap(test_fn fn, const char *desc) +{ + ksft_print_msg("[RUN] %s ... with swapped-out large anon folio\n", desc); + do_run_with_large(fn, LARGE_RUN_PTE_SWAPOUT, lafsize); +} + +static void run_with_single_pte_of_laf(test_fn fn, const char *desc) +{ + ksft_print_msg("[RUN] %s ... with single PTE of large anon folio\n", desc); + do_run_with_large(fn, LARGE_RUN_SINGLE_PTE, lafsize); +} + +static void run_with_single_pte_of_laf_swap(test_fn fn, const char *desc) +{ + ksft_print_msg("[RUN] %s ... with single PTE of swapped-out large anon folio\n", desc); + do_run_with_large(fn, LARGE_RUN_SINGLE_PTE_SWAPOUT, lafsize); +} + +static void run_with_partial_mremap_laf(test_fn fn, const char *desc) +{ + ksft_print_msg("[RUN] %s ... with partially mremap()'ed large anon folio\n", desc); + do_run_with_large(fn, LARGE_RUN_PARTIAL_MREMAP, lafsize); +} + +static void run_with_partial_shared_laf(test_fn fn, const char *desc) +{ + ksft_print_msg("[RUN] %s ... with partially shared large anon folio\n", desc); + do_run_with_large(fn, LARGE_RUN_PARTIAL_SHARED, lafsize); +} + static void run_with_hugetlb(test_fn fn, const char *desc, size_t hugetlbsize) { int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB; @@ -1105,6 +1142,14 @@ static void run_anon_test_case(struct test_case const *test_case) run_with_partial_mremap_thp(test_case->fn, test_case->desc); run_with_partial_shared_thp(test_case->fn, test_case->desc); } + if (lafsize) { + run_with_laf(test_case->fn, test_case->desc); + run_with_laf_swap(test_case->fn, test_case->desc); + run_with_single_pte_of_laf(test_case->fn, test_case->desc); + run_with_single_pte_of_laf_swap(test_case->fn, test_case->desc); + run_with_partial_mremap_laf(test_case->fn, test_case->desc); + run_with_partial_shared_laf(test_case->fn, test_case->desc); + } for (i = 0; i < nr_hugetlbsizes; i++) run_with_hugetlb(test_case->fn, test_case->desc, hugetlbsizes[i]); @@ -1126,6 +1171,8 @@ static int tests_per_anon_test_case(void) if (thpsize) tests += 8; + if (lafsize) + tests += 6; return tests; } @@ -1680,15 +1727,74 @@ static int tests_per_non_anon_test_case(void) return tests; } +static size_t large_anon_folio_size(void) +{ + /* + * There is no interface to query this. But we know that it must be less + * than thpsize. So we map a thpsize area, aligned to thpsize offset by + * thpsize/2 (to avoid a hugepage being allocated), then touch the first + * page and see how many pages get faulted in. + */ + + int max_order = __builtin_ctz(thpsize); + size_t mmap_size = thpsize * 3; + char *mmap_mem = NULL; + int order = 0; + char *mem; + size_t offset; + int ret; + + /* For alignment purposes, we need 2.5x the requested size. */ + mmap_mem = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (mmap_mem == MAP_FAILED) + goto out; + + /* Align the memory area to thpsize then offset it by thpsize/2. */ + mem = (char *)(((uintptr_t)mmap_mem + thpsize) & ~(thpsize - 1)); + mem += thpsize / 2; + + /* We might get a bigger large anon folio when MADV_HUGEPAGE is set. */ + ret = madvise(mem, thpsize, MADV_HUGEPAGE); + if (ret) + goto out; + + /* Probe the memory to see how much is populated. */ + mem[0] = 0; + for (order = 0; order < max_order; order++) { + offset = (1 << order) * pagesize; + if (!pagemap_is_populated(pagemap_fd, mem + offset)) + break; + } + +out: + if (mmap_mem) + munmap(mmap_mem, mmap_size); + + if (order == 0) + return 0; + + return offset; +} + int main(int argc, char **argv) { int err; + gup_fd = open("/sys/kernel/debug/gup_test", O_RDWR); + pagemap_fd = open("/proc/self/pagemap", O_RDONLY); + if (pagemap_fd < 0) + ksft_exit_fail_msg("opening pagemap failed\n"); + pagesize = getpagesize(); thpsize = read_pmd_pagesize(); if (thpsize) ksft_print_msg("[INFO] detected THP size: %zu KiB\n", thpsize / 1024); + lafsize = large_anon_folio_size(); + if (lafsize) + ksft_print_msg("[INFO] detected large anon folio size: %zu KiB\n", + lafsize / 1024); nr_hugetlbsizes = detect_hugetlb_page_sizes(hugetlbsizes, ARRAY_SIZE(hugetlbsizes)); detect_huge_zeropage(); @@ -1698,11 +1804,6 @@ int main(int argc, char **argv) ARRAY_SIZE(anon_thp_test_cases) * tests_per_anon_thp_test_case() + ARRAY_SIZE(non_anon_test_cases) * tests_per_non_anon_test_case()); - gup_fd = open("/sys/kernel/debug/gup_test", O_RDWR); - pagemap_fd = open("/proc/self/pagemap", O_RDONLY); - if (pagemap_fd < 0) - ksft_exit_fail_msg("opening pagemap failed\n"); - run_anon_test_cases(); run_anon_thp_test_cases(); run_non_anon_test_cases();