From patchwork Tue Jan 23 17:14:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Roberts X-Patchwork-Id: 13527907 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 BDD6CC47258 for ; Tue, 23 Jan 2024 17:14:34 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 3C1906B0078; Tue, 23 Jan 2024 12:14:34 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 370AF6B007D; Tue, 23 Jan 2024 12:14:34 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 25FE46B007E; Tue, 23 Jan 2024 12:14:34 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 179836B0078 for ; Tue, 23 Jan 2024 12:14:34 -0500 (EST) Received: from smtpin25.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id B15A6A205D for ; Tue, 23 Jan 2024 17:14:33 +0000 (UTC) X-FDA: 81711224826.25.EBD53EE Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf20.hostedemail.com (Postfix) with ESMTP id 257BF1C001F for ; Tue, 23 Jan 2024 17:14:30 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=none; spf=pass (imf20.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-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1706030071; a=rsa-sha256; cv=none; b=tAo5g6Sc9jvni5ydoMf+fJexWCbwfN620nvo1hc20qKQe5/011lzxroHt1VoPfgDAoPQWh nUu//B645sNFhp1dUSankhfSXm/dRdxa0LFy686BeFICrgU3X77y8ZtoaKTLrXiTTy90O/ qSTU7zq4kGkSeUqEDbsxpo2dKPu9Lw8= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=none; spf=pass (imf20.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=1706030071; 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:references; bh=QsMkMfFABK/0Bni0zXJF7etTs9dTaqtvVyu79hTPc/Q=; b=MmfzfRhwpEC0lxKejKqHoNxyA0R84vPn2Y/gZjvSIuLkDhuqqr7udIZTEB00HPEH4eDi1+ GsYXv3qceS5F0XCT1Zql2ZQ6zge45UYBW9XEfsQSmNBBcA61kGw7gHxMBv/GRsfJKnfz+c E/6r9k2RvOZ+iGql76PJj+YaW5GCutw= 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 563861FB; Tue, 23 Jan 2024 09:15: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 E84063F5A1; Tue, 23 Jan 2024 09:14:28 -0800 (PST) From: Ryan Roberts To: Andrew Morton , Yang Shi , Rik van Riel , Matthew Wilcox Cc: Ryan Roberts , linux-mm@kvack.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v1] mm: thp_get_unmapped_area must honour topdown preference Date: Tue, 23 Jan 2024 17:14:20 +0000 Message-Id: <20240123171420.3970220-1-ryan.roberts@arm.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 257BF1C001F X-Stat-Signature: cq5bi7h9k5xfx8za1dnqzot668961d3i X-HE-Tag: 1706030070-766722 X-HE-Meta: U2FsdGVkX19r80sFxnIC/dkAb3y+bNRLLjnJIa+eHJf6r8XrO5qC0gGohhoYC4zTrzkmzSgFC388oWTeoRL/ghFbaXEnBWDMiQ/VF6KuvQZZ6SFxvTti4UsdL3LmId5s19YvBN4Wxc4lT0t+MTgp0pHXiTBmSqyEh2sS4of+LWaqEEgiRpxDq3Puy61zNuK3FTM3yfYKo6CCFnc/DUQhQx14vUGZJSPYlpZLvbWRo0LxJ+WQZm7Rcs6dtwrUhE4smLC09+eIHMxbOMCYxtDQVGkBc/F0EaToXlvqU3xHN5KVyjohVksv8VFO/M5cQFfOcURyWGi3yPQAiREZ85bW3l0MFwqL2sY9QNGUi2AQ4VBQQEqjBaWQnfeVo3obpmX9aETtHhNv2X815uF3JzfkODRW9dgF7JsYYu7aeAIBqVH44GgsYJT+dczQQBALmqjM9DQ633fU/HYY4WUJqzOpcLwh5SCjBTxWwfEwdeL4dPJc7KnyZ9RvwzYY9vy2a08pkVUNrZ28XDnjmdBrPbb2QMNbbYUGJsGS03of3NpoHI2erF2tIM9H5M7VF+CWgnegUZjImMVmRCG6WkPIU3QI63O6HMMdBl75Gow2OOIELpOyBPANeM7ndOg2cBuaihLVUZaxuyWHCUIWsDIKHAtRjAfw+49olqSZoUGfNGqE0bhoDE8CYk58QnmCaegypUyYehP/hgfOETsHlus2lwTvCGFKzerh5KqD1uyt9VSGZSizznY8Kkzjin4/CFSypqP8BGnvnsWFuW4NpKU/SjSiipjc45k2gIfbk8/NO9tzmXVZBs52dy6VmNYuLVuMCxbKyqteKqeA4Ji35cFzO9psGPj4GhYtJY8rw1UCfiD9EfDxMHUaq2UdCh70A10UgKT7av9i5zQ5SWqzeJEb/bt4u61PmYVDzR3rEpo2b5PmmDr4DxuYP4KqzWE3ATqPwOa0XRsgsCueW3VyvdzLrdd 5msbxDTD hAXMlOyhCVCkhSY5fzDVKtjM79aJVYO3rV+4EqcuC4vQaN/0VTiLcOar1/587nkfvtjLHW4V43fnzoj5/Yic1Qk4uMiNu23L1fO0z42rhbKNbpRe/7yqctZyZaIFzxpbCzPL/aM0X3ie9t80rhSsNlxzMsUp28gywX58fzdXo//fW3j9sHDlCqt5Y8TAG/ouMw+snIIBeiZ/ElqIH1GItTFiENBYTt7h8qIS9VU3jQ6cwdWll0hr1ooLIyTGXzOMDz5iXPco4tNFXvg8= 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 addition of commit efa7df3e3bb5 ("mm: align larger anonymous mappings on THP boundaries") caused the "virtual_address_range" mm selftest to start failing on arm64. Let's fix that regression. There were 2 visible problems when running the test; 1) it takes much longer to execute, and 2) the test fails. Both are related: The (first part of the) test allocates as many 1GB anonymous blocks as it can in the low 256TB of address space, passing NULL as the addr hint to mmap. Before the faulty patch, all allocations were abutted and contained in a single, merged VMA. However, after this patch, each allocation is in its own VMA, and there is a 2M gap between each VMA. This causes the 2 problems in the test: 1) mmap becomes MUCH slower because there are so many VMAs to check to find a new 1G gap. 2) mmap fails once it hits the VMA limit (/proc/sys/vm/max_map_count). Hitting this limit then causes a subsequent calloc() to fail, which causes the test to fail. The problem is that arm64 (unlike x86) selects ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT. But __thp_get_unmapped_area() allocates len+2M then always aligns to the bottom of the discovered gap. That causes the 2M hole. Fix this by detecting cases where we can still achive the alignment goal when moved to the top of the allocated area, if configured to prefer top-down allocation. While we are at it, fix thp_get_unmapped_area's use of pgoff, which should always be zero for anonymous mappings. Prior to the faulty change, while it was possible for user space to pass in pgoff!=0, the old mm->get_unmapped_area() handler would not use it. thp_get_unmapped_area() does use it, so let's explicitly zero it before calling the handler. This should also be the correct behavior for arches that define their own get_unmapped_area() handler. Fixes: efa7df3e3bb5 ("mm: align larger anonymous mappings on THP boundaries") Closes: https://lore.kernel.org/linux-mm/1e8f5ac7-54ce-433a-ae53-81522b2320e1@arm.com/ Cc: stable@vger.kernel.org Signed-off-by: Ryan Roberts --- Applies on top of v6.8-rc1. Would be good to get this into the next -rc. Thanks, Ryan mm/huge_memory.c | 10 ++++++++-- mm/mmap.c | 6 ++++-- 2 files changed, 12 insertions(+), 4 deletions(-) -- 2.25.1 diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 94ef5c02b459..8c66f88e71e9 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -809,7 +809,7 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, { loff_t off_end = off + len; loff_t off_align = round_up(off, size); - unsigned long len_pad, ret; + unsigned long len_pad, ret, off_sub; if (off_end <= off_align || (off_end - off_align) < size) return 0; @@ -835,7 +835,13 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, if (ret == addr) return addr; - ret += (off - ret) & (size - 1); + off_sub = (off - ret) & (size - 1); + + if (current->mm->get_unmapped_area == arch_get_unmapped_area_topdown && + !off_sub) + return ret + size; + + ret += off_sub; return ret; } diff --git a/mm/mmap.c b/mm/mmap.c index b78e83d351d2..d89770eaab6b 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1825,15 +1825,17 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, /* * mmap_region() will call shmem_zero_setup() to create a file, * so use shmem's get_unmapped_area in case it can be huge. - * do_mmap() will clear pgoff, so match alignment. */ - pgoff = 0; get_area = shmem_get_unmapped_area; } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { /* Ensures that larger anonymous mappings are THP aligned. */ get_area = thp_get_unmapped_area; } + /* Always treat pgoff as zero for anonymous memory. */ + if (!file) + pgoff = 0; + addr = get_area(file, addr, len, pgoff, flags); if (IS_ERR_VALUE(addr)) return addr;