Re: [RFC PATCH 00/16] 1GB THP support on x86_64

From: Roman Gushchin
Date: Thu Sep 03 2020 - 12:31:10 EST


On Thu, Sep 03, 2020 at 09:32:54AM +0200, Michal Hocko wrote:
> On Wed 02-09-20 14:06:12, Zi Yan wrote:
> > From: Zi Yan <ziy@xxxxxxxxxx>
> >
> > Hi all,
> >
> > This patchset adds support for 1GB THP on x86_64. It is on top of
> > v5.9-rc2-mmots-2020-08-25-21-13.
> >
> > 1GB THP is more flexible for reducing translation overhead and increasing the
> > performance of applications with large memory footprint without application
> > changes compared to hugetlb.
>
> Please be more specific about usecases. This better have some strong
> ones because THP code is complex enough already to add on top solely
> based on a generic TLB pressure easing.

Hello, Michal!

We at Facebook are using 1 GB hugetlbfs pages and are getting noticeable
performance wins on some workloads.

Historically we allocated gigantic pages at the boot time, but recently moved
to cma-based dynamic approach. Still, hugetlbfs interface requires more management
than we would like to do. 1 GB THP seems to be a better alternative. So I definitely
see it as a very useful feature.

Given the cost of an allocation, I'm slightly skeptical about an automatic
heuristics-based approach, but if an application can explicitly mark target areas
with madvise(), I don't see why it wouldn't work.

In our case we'd like to have a reliable way to get 1 GB THPs at some point
(usually at the start of an application), and transparently destroy them on
the application exit.

Once we'll have the patchset in a relatively good shape, I'll be happy to give
it a test in our environment and share results.

Thanks!

>
> > Design
> > =======
> >
> > 1GB THP implementation looks similar to exiting THP code except some new designs
> > for the additional page table level.
> >
> > 1. Page table deposit and withdraw using a new pagechain data structure:
> > instead of one PTE page table page, 1GB THP requires 513 page table pages
> > (one PMD page table page and 512 PTE page table pages) to be deposited
> > at the page allocaiton time, so that we can split the page later. Currently,
> > the page table deposit is using ->lru, thus only one page can be deposited.
> > A new pagechain data structure is added to enable multi-page deposit.
> >
> > 2. Triple mapped 1GB THP : 1GB THP can be mapped by a combination of PUD, PMD,
> > and PTE entries. Mixing PUD an PTE mapping can be achieved with existing
> > PageDoubleMap mechanism. To add PMD mapping, PMDPageInPUD and
> > sub_compound_mapcount are introduced. PMDPageInPUD is the 512-aligned base
> > page in a 1GB THP and sub_compound_mapcount counts the PMD mapping by using
> > page[N*512 + 3].compound_mapcount.
> >
> > 3. Using CMA allocaiton for 1GB THP: instead of bump MAX_ORDER, it is more sane
> > to use something less intrusive. So all 1GB THPs are allocated from reserved
> > CMA areas shared with hugetlb. At page splitting time, the bitmap for the 1GB
> > THP is cleared as the resulting pages can be freed via normal page free path.
> > We can fall back to alloc_contig_pages for 1GB THP if necessary.
>
> Do those pages get instantiated during the page fault or only via
> khugepaged? This is an important design detail because then we have to
> think carefully about how much automatic we want this to be. Memory
> overhead can be quite large with 2MB THPs already. Also what about the
> allocation overhead? Do you have any numbers?
>
> Maybe all these details are described in the patcheset but the cover
> letter should contain all that information. It doesn't make much sense
> to dig into details in a patchset this large without having an idea how
> feasible this is.
>
> Thanks.
>
> > Patch Organization
> > =======
> >
> > Patch 01 adds the new pagechain data structure.
> >
> > Patch 02 to 13 adds 1GB THP support in variable places.
> >
> > Patch 14 tries to use alloc_contig_pages for 1GB THP allocaiton.
> >
> > Patch 15 moves hugetlb_cma reservation to cma.c and rename it to hugepage_cma.
> >
> > Patch 16 use hugepage_cma reservation for 1GB THP allocation.
> >
> >
> > Any suggestions and comments are welcome.
> >
> >
> > Zi Yan (16):
> > mm: add pagechain container for storing multiple pages.
> > mm: thp: 1GB anonymous page implementation.
> > mm: proc: add 1GB THP kpageflag.
> > mm: thp: 1GB THP copy on write implementation.
> > mm: thp: handling 1GB THP reference bit.
> > mm: thp: add 1GB THP split_huge_pud_page() function.
> > mm: stats: make smap stats understand PUD THPs.
> > mm: page_vma_walk: teach it about PMD-mapped PUD THP.
> > mm: thp: 1GB THP support in try_to_unmap().
> > mm: thp: split 1GB THPs at page reclaim.
> > mm: thp: 1GB THP follow_p*d_page() support.
> > mm: support 1GB THP pagemap support.
> > mm: thp: add a knob to enable/disable 1GB THPs.
> > mm: page_alloc: >=MAX_ORDER pages allocation an deallocation.
> > hugetlb: cma: move cma reserve function to cma.c.
> > mm: thp: use cma reservation for pud thp allocation.
> >
> > .../admin-guide/kernel-parameters.txt | 2 +-
> > arch/arm64/mm/hugetlbpage.c | 2 +-
> > arch/powerpc/mm/hugetlbpage.c | 2 +-
> > arch/x86/include/asm/pgalloc.h | 68 ++
> > arch/x86/include/asm/pgtable.h | 26 +
> > arch/x86/kernel/setup.c | 8 +-
> > arch/x86/mm/pgtable.c | 38 +
> > drivers/base/node.c | 3 +
> > fs/proc/meminfo.c | 2 +
> > fs/proc/page.c | 2 +
> > fs/proc/task_mmu.c | 122 ++-
> > include/linux/cma.h | 18 +
> > include/linux/huge_mm.h | 84 +-
> > include/linux/hugetlb.h | 12 -
> > include/linux/memcontrol.h | 5 +
> > include/linux/mm.h | 29 +-
> > include/linux/mm_types.h | 1 +
> > include/linux/mmu_notifier.h | 13 +
> > include/linux/mmzone.h | 1 +
> > include/linux/page-flags.h | 47 +
> > include/linux/pagechain.h | 73 ++
> > include/linux/pgtable.h | 34 +
> > include/linux/rmap.h | 10 +-
> > include/linux/swap.h | 2 +
> > include/linux/vm_event_item.h | 7 +
> > include/uapi/linux/kernel-page-flags.h | 2 +
> > kernel/events/uprobes.c | 4 +-
> > kernel/fork.c | 5 +
> > mm/cma.c | 119 +++
> > mm/gup.c | 60 +-
> > mm/huge_memory.c | 939 +++++++++++++++++-
> > mm/hugetlb.c | 114 +--
> > mm/internal.h | 2 +
> > mm/khugepaged.c | 6 +-
> > mm/ksm.c | 4 +-
> > mm/memcontrol.c | 13 +
> > mm/memory.c | 51 +-
> > mm/mempolicy.c | 21 +-
> > mm/migrate.c | 12 +-
> > mm/page_alloc.c | 57 +-
> > mm/page_vma_mapped.c | 129 ++-
> > mm/pgtable-generic.c | 56 ++
> > mm/rmap.c | 289 ++++--
> > mm/swap.c | 31 +
> > mm/swap_slots.c | 2 +
> > mm/swapfile.c | 8 +-
> > mm/userfaultfd.c | 2 +-
> > mm/util.c | 16 +-
> > mm/vmscan.c | 58 +-
> > mm/vmstat.c | 8 +
> > 50 files changed, 2270 insertions(+), 349 deletions(-)
> > create mode 100644 include/linux/pagechain.h
> >
> > --
> > 2.28.0
> >
>
> --
> Michal Hocko
> SUSE Labs