From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-dl1-f51.google.com (mail-dl1-f51.google.com [74.125.82.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 621E717736 for ; Thu, 5 Feb 2026 05:46:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.51 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770270375; cv=none; b=A+Z8ErmnHBr56X6egPBlg6QqjVxrVY+Ys/+YiUrodIkotCiuex6JiAMc6vGCLHkazH7Hr+LIxu5eL0cm/7aa4YvfQP7orsZhhB8H30yiT7A/jXdKQVEn3hSzmf2fPzlWj+Z2TuKtKikXIXu7h8SIILKVietYv1Qq6rFzQBWdj8I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770270375; c=relaxed/simple; bh=jShptl4srAhKRXEhRU0neBHPKns3RtElZChyvt+akPE=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=ZuEsxxOAo8tvqqU5Ke6Hf0/EpYCScmwoBruocvwAWKN3u4rR3LZLlpMHJzC5Z3KEwi0N+MT0MFsKVqjnTyNgO5qWK9+KRDbMt9MMyxNhx2DppCDam/zYuQdS0z277kLofVV8wAuxpNDcyGnn3/fM2UxFObv6YUk3jb3/ZXiFjWE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jNwTaPIm; arc=none smtp.client-ip=74.125.82.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jNwTaPIm" Received: by mail-dl1-f51.google.com with SMTP id a92af1059eb24-1233b953bebso1561276c88.1 for ; Wed, 04 Feb 2026 21:46:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770270374; x=1770875174; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=xh8SRryTbBKNPrusvQGIQRE83r+fwBp2qy2Ro8RHIOE=; b=jNwTaPImwZmJXkVPTb4QCZgsexUXvm0J0pJUu7iaj2mSSe+6UTju7ODlO3mFRR6lMz PLgiZOeW/RC4dKq3tDCx+NDrQYT40jjXJV4Rr68kwzRzNZkujtDUmvMHzlgrxKXjzRZZ JclBOLoHMHRfTnqpp2dET6YaHWyCdeuXgBNjuJvlSUTbB3s0OUgYmwiRZjj790fzwyDu oUBxXnWVsK7x7VmUWIci7et94LYpADbZ7+/aE+qys1P2ZA8zucOT5KDz4fwLlTWdNSy8 gKVvEC/ELDPLBmDnH/Vr0GJxLTweNknHShborgmj2qoJBu2lGF+tRtjaRYW3G6NmmQoY 6rqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770270374; x=1770875174; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=xh8SRryTbBKNPrusvQGIQRE83r+fwBp2qy2Ro8RHIOE=; b=kRsfH7ZQXz6aQk2H3OmKHyCOuG56cOBnTSsKUtwTQrwZyB80K+dEJqDUYkFl86ZyU/ 2fIP62wWAsOuA+kK/WdSxKu4VSEqh5m6gcbkeVTOi4p8OCOern8TuB8qLH9w10ymFVLf sIP2JZUIdWVq3uzcTWV/IcX0YY0dbHURguMh/wjmtN3VOC1NdqNWHgK9XqhiL/RF1qQq ylT03vM6T6FO+wn/0nvXRkUATm1EFAKh5CZNZ/MzRi7OoJIElV9Dl6f5KH2x7tmZJ3iX 735v9T3C8dOmQretifBPEwKivdA5OEwsf9N+SJ8gJu5fa0rGHO4ZMMkfXrDnsDYlqa+t QDag== X-Forwarded-Encrypted: i=1; AJvYcCWLSMF434Q31x9t5iVbyFahf6ujWODiG22SYasXz67q9zlOwoQoebSTej47FPBbTFPZ2cnVbnggMW5JBrc=@vger.kernel.org X-Gm-Message-State: AOJu0Yxgt67VpX9cG+fFUkvAxjalZrgPBiK0WhxzuKYOWW7vKid8DLOS RTQfVQGvH62iVEMAxg3sNFDhQbSDMRzxZVifwiGldVrpgHIRmEp9gaxA X-Gm-Gg: AZuq6aLKvIOf3K/fEg3heyVeu72sY7/bJqJ5USZ7jzc9fpsJQvzybod+MOGVCpev1Jm 1JhnqJLRT3EgAt9kj/egdGbw1jQi3z+zKlyYTW6K7V8Al2KxfZ4v5RH3B9YTPPxaxWWQsJqck+j mY4N+nFdtJtLdO8w30R7IkMipKEWWc7yBTCKsfx+glYZzmf3iidtdW+OYHgIbpRNwRPzhHSstpC 1VjNjMWvMv4MSb4O8Y9Prs5Ih9rgJ4mvUFVoJiUnq5kQxYxM1wAjpxlEInhLZUfLGKD4c1zC5UH guvyZrZlM7NU+bGZ3o6Gtq7k3CGJDM7ARHQJUPVN+Yb2y0GSKNfYwl4cRgtqMA6OkP+ZgHmOT6j N2cMNHDVLwixYSFni+q0hfHSKEWbV6I9rYn7JuP9yPKMsOU3p3feyW2oTlkjkY6ySrjHr5SRMDV 8BWiEbRNCIbbPHcCnX/5IMZWyMvBZ0o5/J9Q== X-Received: by 2002:a05:7022:7a2:b0:122:153:d161 with SMTP id a92af1059eb24-126f477cf4amr2706153c88.17.1770270374198; Wed, 04 Feb 2026 21:46:14 -0800 (PST) Received: from [10.36.158.92] ([50.175.227.221]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-126f4e05ce7sm3514842c88.1.2026.02.04.21.46.13 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 04 Feb 2026 21:46:13 -0800 (PST) Message-ID: <582ffff0-c1ed-4a25-9130-1b1c9d290998@gmail.com> Date: Wed, 4 Feb 2026 21:46:12 -0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [RFC 00/12] mm: PUD (1GB) THP implementation Content-Language: en-GB To: Frank van der Linden Cc: Zi Yan , Andrew Morton , David Hildenbrand , lorenzo.stoakes@oracle.com, linux-mm@kvack.org, hannes@cmpxchg.org, riel@surriel.com, shakeel.butt@linux.dev, kas@kernel.org, baohua@kernel.org, dev.jain@arm.com, baolin.wang@linux.alibaba.com, npache@redhat.com, Liam.Howlett@oracle.com, ryan.roberts@arm.com, vbabka@suse.cz, lance.yang@linux.dev, linux-kernel@vger.kernel.org, kernel-team@meta.com References: <20260202005451.774496-1-usamaarif642@gmail.com> <3561FD10-664D-42AA-8351-DE7D8D49D42E@nvidia.com> <20f92576-e932-435f-bb7b-de49eb84b012@gmail.com> From: Usama Arif In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 03/02/2026 16:08, Frank van der Linden wrote: > On Tue, Feb 3, 2026 at 3:29 PM Usama Arif wrote: >> >> >> >> On 02/02/2026 08:24, Zi Yan wrote: >>> On 1 Feb 2026, at 19:50, Usama Arif wrote: >>> >>>> This is an RFC series to implement 1GB PUD-level THPs, allowing >>>> applications to benefit from reduced TLB pressure without requiring >>>> hugetlbfs. The patches are based on top of >>>> f9b74c13b773b7c7e4920d7bc214ea3d5f37b422 from mm-stable (6.19-rc6). >>> >>> It is nice to see you are working on 1GB THP. >>> >>>> >>>> Motivation: Why 1GB THP over hugetlbfs? >>>> ======================================= >>>> >>>> While hugetlbfs provides 1GB huge pages today, it has significant limitations >>>> that make it unsuitable for many workloads: >>>> >>>> 1. Static Reservation: hugetlbfs requires pre-allocating huge pages at boot >>>> or runtime, taking memory away. This requires capacity planning, >>>> administrative overhead, and makes workload orchastration much much more >>>> complex, especially colocating with workloads that don't use hugetlbfs. >>> >>> But you are using CMA, the same allocation mechanism as hugetlb_cma. What >>> is the difference? >>> >> >> So we dont really need to use CMA. CMA can help a lot ofcourse, but we dont *need* it. >> For e.g. I can run the very simple case [1] of trying to get 1G pages in the upstream >> kernel without CMA on my server and it works. The server has been up for more than a week >> (so pretty fragmented), is running a bunch of stuff in the background, uses 0 CMA memory, >> and I tried to get 20x1G pages on it and it worked. >> It uses folio_alloc_gigantic, which is exactly what this series uses: >> >> $ uptime -p >> up 1 week, 3 days, 5 hours, 7 minutes >> $ cat /proc/meminfo | grep -i cma >> CmaTotal: 0 kB >> CmaFree: 0 kB >> $ echo 20 | sudo tee /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages >> 20 >> $ cat /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages >> 20 >> $ free -h >> total used free shared buff/cache available >> Mem: 1.0Ti 142Gi 292Gi 143Mi 583Gi 868Gi >> Swap: 129Gi 3.5Gi 126Gi >> $ ./map_1g_hugepages >> Mapping 20 x 1GB huge pages (20 GB total) >> Mapped at 0x7f43c0000000 >> Touched page 0 at 0x7f43c0000000 >> Touched page 1 at 0x7f4400000000 >> Touched page 2 at 0x7f4440000000 >> Touched page 3 at 0x7f4480000000 >> Touched page 4 at 0x7f44c0000000 >> Touched page 5 at 0x7f4500000000 >> Touched page 6 at 0x7f4540000000 >> Touched page 7 at 0x7f4580000000 >> Touched page 8 at 0x7f45c0000000 >> Touched page 9 at 0x7f4600000000 >> Touched page 10 at 0x7f4640000000 >> Touched page 11 at 0x7f4680000000 >> Touched page 12 at 0x7f46c0000000 >> Touched page 13 at 0x7f4700000000 >> Touched page 14 at 0x7f4740000000 >> Touched page 15 at 0x7f4780000000 >> Touched page 16 at 0x7f47c0000000 >> Touched page 17 at 0x7f4800000000 >> Touched page 18 at 0x7f4840000000 >> Touched page 19 at 0x7f4880000000 >> Unmapped successfully >> >> >> >> >>>> >>>> 4. No Fallback: If a 1GB huge page cannot be allocated, hugetlbfs fails >>>> rather than falling back to smaller pages. This makes it fragile under >>>> memory pressure. >>> >>> True. >>> >>>> >>>> 4. No Splitting: hugetlbfs pages cannot be split when only partial access >>>> is needed, leading to memory waste and preventing partial reclaim. >>> >>> Since you have PUD THP implementation, have you run any workload on it? >>> How often you see a PUD THP split? >>> >> >> Ah so running non upstream kernels in production is a bit more difficult >> (and also risky). I was trying to use the 512M experiment on arm as a comparison, >> although I know its not the same thing with PAGE_SIZE and pageblock order. >> >> I can try some other upstream benchmarks if it helps? Although will need to find >> ones that create VMA > 1G. >> >>> Oh, you actually ran 512MB THP on ARM64 (I saw it below), do you have >>> any split stats to show the necessity of THP split? >>> >>>> >>>> 5. Memory Accounting: hugetlbfs memory is accounted separately and cannot >>>> be easily shared with regular memory pools. >>> >>> True. >>> >>>> >>>> PUD THP solves these limitations by integrating 1GB pages into the existing >>>> THP infrastructure. >>> >>> The main advantage of PUD THP over hugetlb is that it can be split and mapped >>> at sub-folio level. Do you have any data to support the necessity of them? >>> I wonder if it would be easier to just support 1GB folio in core-mm first >>> and we can add 1GB THP split and sub-folio mapping later. With that, we >>> can move hugetlb users to 1GB folio. >>> >> >> I would say its not the main advantage? But its definitely one of them. >> The 2 main areas where split would be helpful is munmap partial >> range and reclaim (MADV_PAGEOUT). For e.g. jemalloc/tcmalloc can now start >> taking advantge of 1G pages. My knowledge is not that great when it comes >> to memory allocators, but I believe they track for how long certain areas >> have been cold and can trigger reclaim as an example. Then split will be useful. >> Having memory allocators use hugetlb is probably going to be a no? >> >> >>> BTW, without split support, you can apply HVO to 1GB folio to save memory. >>> That is a disadvantage of PUD THP. Have you taken that into consideration? >>> Basically, switching from hugetlb to PUD THP, you will lose memory due >>> to vmemmap usage. >>> >> >> Yeah so HVO saves 16M per 1G, and the page depost mechanism adds ~2M as per 1G. >> We have HVO enabled in the meta fleet. I think we should not only think of PUD THP >> as a replacement for hugetlb, but to also enable further usescases where hugetlb >> would not be feasible. >> >> Ater the basic infrastructure for 1G is there, we can work on optimizing, I think >> there would be a a lot of interesting work we can do. HVO for 1G THP would be one >> of them? >> >>>> >>>> Performance Results >>>> =================== >>>> >>>> Benchmark results of these patches on Intel Xeon Platinum 8321HC: >>>> >>>> Test: True Random Memory Access [1] test of 4GB memory region with pointer >>>> chasing workload (4M random pointer dereferences through memory): >>>> >>>> | Metric | PUD THP (1GB) | PMD THP (2MB) | Change | >>>> |-------------------|---------------|---------------|--------------| >>>> | Memory access | 88 ms | 134 ms | 34% faster | >>>> | Page fault time | 898 ms | 331 ms | 2.7x slower | >>>> >>>> Page faulting 1G pages is 2.7x slower (Allocating 1G pages is hard :)). >>>> For long-running workloads this will be a one-off cost, and the 34% >>>> improvement in access latency provides significant benefit. >>>> >>>> ARM with 64K PAGE_SZIE supports 512M PMD THPs. In meta, we have a CPU >>>> bound workload running on a large number of ARM servers (256G). I enabled >>>> the 512M THP settings to always for a 100 servers in production (didn't >>>> really have high expectations :)). The average memory used for the workload >>>> increased from 217G to 233G. The amount of memory backed by 512M pages was >>>> 68G! The dTLB misses went down by 26% and the PID multiplier increased input >>>> by 5.9% (This is a very significant improvment in workload performance). >>>> A significant number of these THPs were faulted in at application start when >>>> were present across different VMAs. Ofcourse getting these 512M pages is >>>> easier on ARM due to bigger PAGE_SIZE and pageblock order. >>>> >>>> I am hoping that these patches for 1G THP can be used to provide similar >>>> benefits for x86. I expect workloads to fault them in at start time when there >>>> is plenty of free memory available. >>>> >>>> >>>> Previous attempt by Zi Yan >>>> ========================== >>>> >>>> Zi Yan attempted 1G THPs [2] in kernel version 5.11. There have been >>>> significant changes in kernel since then, including folio conversion, mTHP >>>> framework, ptdesc, rmap changes, etc. I found it easier to use the current PMD >>>> code as reference for making 1G PUD THP work. I am hoping Zi can provide >>>> guidance on these patches! >>> >>> I am more than happy to help you. :) >>> >> >> Thanks!!! >> >>>> >>>> Major Design Decisions >>>> ====================== >>>> >>>> 1. No shared 1G zero page: The memory cost would be quite significant! >>>> >>>> 2. Page Table Pre-deposit Strategy >>>> PMD THP deposits a single PTE page table. PUD THP deposits 512 PTE >>>> page tables (one for each potential PMD entry after split). >>>> We allocate a PMD page table and use its pmd_huge_pte list to store >>>> the deposited PTE tables. This ensures split operations don't fail due >>>> to page table allocation failures (at the cost of 2M per PUD THP) >>>> >>>> 3. Split to Base Pages >>>> When a PUD THP must be split (COW, partial unmap, mprotect), we split >>>> directly to base pages (262,144 PTEs). The ideal thing would be to split >>>> to 2M pages and then to 4K pages if needed. However, this would require >>>> significant rmap and mapcount tracking changes. >>>> >>>> 4. COW and fork handling via split >>>> Copy-on-write and fork for PUD THP triggers a split to base pages, then >>>> uses existing PTE-level COW infrastructure. Getting another 1G region is >>>> hard and could fail. If only a 4K is written, copying 1G is a waste. >>>> Probably this should only be done on CoW and not fork? >>>> >>>> 5. Migration via split >>>> Split PUD to PTEs and migrate individual pages. It is going to be difficult >>>> to find a 1G continguous memory to migrate to. Maybe its better to not >>>> allow migration of PUDs at all? I am more tempted to not allow migration, >>>> but have kept splitting in this RFC. >>> >>> Without migration, PUD THP loses its flexibility and transparency. But with >>> its 1GB size, I also wonder what the purpose of PUD THP migration can be. >>> It does not create memory fragmentation, since it is the largest folio size >>> we have and contiguous. NUMA balancing 1GB THP seems too much work. >> >> Yeah this is exactly what I was thinking as well. It is going to be expensive >> and difficult to migrate 1G pages, and I am not sure if what we get out of it >> is worth it? I kept the splitting code in this RFC as I wanted to show that >> its possible to split and migrate and the rejecting migration code is a lot easier. >> >>> >>> BTW, I posted many questions, but that does not mean I object the patchset. >>> I just want to understand your use case better, reduce unnecessary >>> code changes, and hopefully get it upstreamed this time. :) >>> >>> Thank you for the work. >>> >> >> Ah no this is awesome! Thanks for the questions! Its basically the discussion I >> wanted to start with the RFC. >> >> >> [1] https://gist.github.com/uarif1/35dcd63f9d76048b07eb5c16ace85991 >> >> > > It looks like the scenario you're going for is an application that > allocates a sizeable chunk of memory upfront, and would like it to be > 1G pages as much as possible, right? > Hello! Yes. But also it doesnt need to be a single chunk (VMA). > You can do that with 1G THPs, the advantage being that any failures to > get 1G pages are not explicit, so you're not left with having to grow > the number of hugetlb pages yourself, and see how many you can use. > > 1G THPs seem useful for that. I don't recall all of the discussion > here, but I assume that hooking 1G THP support in to khugepaged is > quite something else - the potential churn to get an 1G page could > well cause more system interference than you'd like. > Yes completely agree. > The CMA scenario Rik was talking about is similar: you set > hugetlb_cma=NG, and then, when you need 1G pages, you grow the hugetlb > pool and use them. Disadvantage: you have to do it explicitly. > > However, hugetlb_cma does give you a much larger chance of getting > those 1G pages. The example you give, 20 1G pages on a 1T system where > there is 292G free, isn't much of a problem in my experience. You > should have no problem getting that amount of 1G pages. Things get > more difficult when most of your memory is taken - hugetlb_cma really > helps there. E.g. we have systems that have 90% hugetlb_cma, and there > is a pretty good success rate converting back and forth between > hugetlb and normal page allocator pages with hugetlb_cma, while > operating close to that 90% hugetlb coverage. Without CMA, the success > rate drops quite a bit at that level. Yes agreed. > > CMA balancing is a related issue, for hugetlb. It fixes a problem that > has been known for years: the more memory you set aside for movable > only allocations (e.g. hugetlb_cma), the less breathing room you have > for unmovable allocations. So you risk the 'false OOM' scenario, where > the kernel can't make an unmovable allocation, even though there is > enough memory available, even outside of CMA. It's just that those > MOVABLE pageblocks were used for movable allocations. So ideally, you > would migrate those movable allocations to CMA under those > circumstances. Which is what CMA balancing does. It's worked out very > well for us in the scenario I list above (most memory being > hugetlb_cma). > > Anyway, I'm rambling on a bit. Let's see if I got this right: > > 1G THP > - advantages: transparent interface > - disadvantage: no HVO, lower success rate under higher memory > pressure than hugetlb_cma > Yes! But also, the problem of having no HVO for THPs I think can be worked on once the support for it is there. The lower success rate is a much more difficult problem to solve. > hugetlb_cma > - disadvantage: explicit interface, for higher values needs 'false > OOM' avoidance > - advange: better success rate under pressure. > > I think 1G THPs are a good solution for "nice to have" scenarios, but > there will still be use cases where a higher success rate is preferred > and HugeTLB is preferred. > Agreed. I dont think 1G THPs can completely replace hugetlb. Maybe after getting after several years of work to optimize it, there might be a path to it but not at the very start. > Lastly, there's also the ZONE_MOVABLE story. I think 1G THPs and > ZONE_MOVABLE could work well together, improving the success rate. But > then the issue of pinning raise its head again, and whether that > should be allowed or configurable per zone.. > Ack > - Frank