Skip to content

RFC 1G page support for guest_memfd

Ackerley Tng kvm linux-fsdevel linux-mm lkml qemu-devel 2 versions – NAK

Status from this message: NAK.

Get series with b4
b4 am [email protected]

Versions newest first · linked by author and title

  1. v2 RFC Latest51 patches 212 repliesNAK
  2. v1 RFC39 patches 90 repliesSuperseded

Patches in v2

#Subject and filesSizeRepliesApplied
1/51KVM: guest_memfd: Make guest mem use guest mem inodes instead of anonymous inodesinclude/uapi/linux/magic.h virt/kvm/guest_memfd.c virt/kvm/kvm_main.c +1 more+125 -260 replies
2/51KVM: guest_memfd: Introduce and use shareability to guard faultingDocumentation/virt/kvm/api.rst include/uapi/linux/kvm.h virt/kvm/guest_memfd.c+129 -239 replies
3/51KVM: selftests: Update guest_memfd_test for INIT_PRIVATE flagtools/testing/selftests/kvm/guest_memfd_test.c+24 -125 replies
4/51KVM: guest_memfd: Introduce KVM_GMEM_CONVERT_SHARED/PRIVATE ioctlsinclude/uapi/linux/kvm.h virt/kvm/guest_memfd.c+366 -250 replies
5/51KVM: guest_memfd: Skip LRU for guest_memfd foliosmm/filemap.c mm/memcontrol.c virt/kvm/guest_memfd.c+86 -83 replies
6/51KVM: Query guest_memfd for private/shared statusinclude/linux/kvm_host.h virt/kvm/guest_memfd.c+34 -74 replies
7/51KVM: guest_memfd: Add CAP KVM_CAP_GMEM_CONVERSIONarch/arm64/include/asm/kvm_host.h arch/x86/include/asm/kvm_host.h include/linux/kvm_host.h +3 more+7 -370 replies
8/51KVM: selftests: Test flag validity after guest_memfd supports conversionstools/testing/selftests/kvm/guest_memfd_test.c+23 -30 replies
9/51KVM: selftests: Test faulting with respect to GUEST_MEMFD_FLAG_INIT_PRIVATEtools/testing/selftests/kvm/guest_memfd_test.c+97 -150 replies
10/51KVM: selftests: Refactor vm_mem_add to be more flexibletools/testing/selftests/kvm/include/kvm_util.h tools/testing/selftests/kvm/include/test_util.h tools/testing/selftests/kvm/lib/kvm_util.c +1 more+328 -1571 reply
11/51KVM: selftests: Allow cleanup of ucall_pool from hosttools/testing/selftests/kvm/include/ucall_common.h tools/testing/selftests/kvm/lib/ucall_common.c+9 -81 reply
12/51KVM: selftests: Test conversion flows for guest_memfdtools/testing/selftests/kvm/Makefile.kvm tools/testing/selftests/kvm/guest_memfd_conversions_test.c tools/testing/selftests/kvm/include/kvm_util.h+664 -01 reply
13/51KVM: selftests: Add script to exercise private_mem_conversions_testtools/testing/selftests/kvm/x86/private_mem_conversions_test.sh+82 -00 replies
14/51KVM: selftests: Update private_mem_conversions_test to mmap guest_memfdtools/testing/selftests/kvm/include/kvm_util.h tools/testing/selftests/kvm/lib/kvm_util.c tools/testing/selftests/kvm/x86/private_mem_conversions_test.c+176 -240 replies
15/51KVM: selftests: Update script to map shared memory from guest_memfdtools/testing/selftests/kvm/x86/private_mem_conversions_test.sh+3 -00 replies
16/51mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio()mm/hugetlb.c+11 -173 replies
17/51mm: hugetlb: Cleanup interpretation of gbl_chg in alloc_hugetlb_folio()mm/hugetlb.c+12 -160 replies
18/51mm: hugetlb: Cleanup interpretation of map_chg_state within alloc_hugetlb_folio()mm/hugetlb.c+39 -551 reply
19/51mm: hugetlb: Rename alloc_surplus_hugetlb_foliomm/hugetlb.c+20 -180 replies
20/51mm: mempolicy: Refactor out policy_node_nodemask()include/linux/mempolicy.h mm/mempolicy.c+35 -70 replies
21/51mm: hugetlb: Inline huge_node() into callersinclude/linux/mempolicy.h mm/hugetlb.c mm/mempolicy.c+10 -360 replies
22/51mm: hugetlb: Refactor hugetlb allocation functionsmm/hugetlb.c+30 -342 replies
23/51mm: hugetlb: Refactor out hugetlb_alloc_folio()include/linux/hugetlb.h mm/hugetlb.c+118 -862 replies
24/51mm: hugetlb: Add option to create new subpool without using surplusfs/hugetlbfs/inode.c include/linux/hugetlb.h mm/hugetlb.c+61 -200 replies
25/51mm: truncate: Expose preparation steps for truncate_inode_pages_finalinclude/linux/mm.h mm/truncate.c+17 -100 replies
26/51mm: Consolidate freeing of typed folios on final folio_put()include/linux/page-flags.h mm/swap.c+33 -50 replies
27/51mm: hugetlb: Expose hugetlb_subpool_{get,put}_pages()include/linux/hugetlb.h mm/hugetlb.c+5 -40 replies
28/51mm: Introduce guestmem_hugetlb to support folio_put() handling of guestmem pagesinclude/linux/page-flags.h mm/Kconfig mm/Makefile +4 more+61 -00 replies
29/51mm: guestmem_hugetlb: Wrap HugeTLB as an allocator for guest_memfdinclude/linux/guestmem.h include/uapi/linux/guestmem.h mm/Kconfig +1 more+212 -17 replies
30/51mm: truncate: Expose truncate_inode_folio()include/linux/mm.h mm/guestmem_hugetlb.c mm/internal.h +1 more+3 -20 replies
31/51KVM: x86: Set disallow_lpage on base_gfn and guest_memfd pgoff misalignmentarch/x86/kvm/x86.c+44 -90 replies
32/51KVM: guest_memfd: Support guestmem_hugetlb as custom allocatorinclude/uapi/linux/kvm.h virt/kvm/Kconfig virt/kvm/guest_memfd.c+199 -104 replies
33/51KVM: guest_memfd: Allocate and truncate from custom allocatormm/memory.c virt/kvm/guest_memfd.c+132 -116 replies
34/51mm: hugetlb: Add functions to add/delete folio from hugetlb listsinclude/linux/hugetlb.h mm/hugetlb.c+24 -00 replies
35/51mm: guestmem_hugetlb: Add support for splitting and merging pagesinclude/linux/guestmem.h mm/guestmem_hugetlb.c+347 -53 replies
36/51mm: Convert split_folio() macro to functioninclude/linux/huge_mm.h+5 -11 reply
37/51filemap: Pass address_space mapping to ->free_folio()Documentation/filesystems/locking.rst Documentation/filesystems/vfs.rst fs/nfs/dir.c +6 more+31 -190 replies
38/51KVM: guest_memfd: Split allocator pages for guest_memfd usemm/filemap.c virt/kvm/guest_memfd.c+483 -2015 replies
39/51KVM: guest_memfd: Merge and truncate on fallocate(PUNCH_HOLE)virt/kvm/guest_memfd.c+68 -84 replies
40/51KVM: guest_memfd: Update kvm_gmem_mapping_order to account for page statusvirt/kvm/guest_memfd.c+62 -100 replies
41/51KVM: Add CAP to indicate support for HugeTLB as custom allocatorinclude/uapi/linux/kvm.h virt/kvm/kvm_main.c+5 -00 replies
42/51KVM: selftests: Add basic selftests for hugetlb-backed guest_memfdtools/testing/selftests/kvm/guest_memfd_test.c+67 -270 replies
43/51KVM: selftests: Update conversion flows test for HugeTLBtools/testing/selftests/kvm/guest_memfd_conversions_test.c+98 -730 replies
44/51KVM: selftests: Test truncation paths of guest_memfdtools/testing/selftests/kvm/guest_memfd_conversions_test.c+95 -00 replies
45/51KVM: selftests: Test allocation and conversion of subfoliostools/testing/selftests/kvm/guest_memfd_conversions_test.c+88 -00 replies
46/51KVM: selftests: Test that guest_memfd usage is reported via hugetlbtools/testing/selftests/kvm/Makefile.kvm tools/testing/selftests/kvm/guest_memfd_hugetlb_reporting_test.c tools/testing/selftests/kvm/guest_memfd_provide_hugetlb_cgroup_mount.sh+421 -00 replies
47/51KVM: selftests: Support various types of backing sources for private memorytools/testing/selftests/kvm/include/test_util.h tools/testing/selftests/kvm/lib/test_util.c+94 -10 replies
48/51KVM: selftests: Update test for various private memory backing source typestools/testing/selftests/kvm/x86/private_mem_conversions_test.c+29 -130 replies
49/51KVM: selftests: Update private_mem_conversions_test.sh to test with HugeTLB pagestools/testing/selftests/kvm/x86/private_mem_conversions_test.sh+22 -70 replies
50/51KVM: selftests: Add script to test HugeTLB statisticstools/testing/selftests/kvm/guest_memfd_wrap_test_check_hugetlb_reporting.sh+95 -00 replies
51/51KVM: selftests: Test guest_memfd for accuracy of st_blockstools/testing/selftests/kvm/guest_memfd_test.c+46 -90 replies

Reviews trailers per patch

5 of 51 patches have a Reviewed-by or Acked-by.

PatchGregory PriceVlastimil BabkaDavid HildenbrandMike DayJames Houghton
1/51
2/51
3/51
4/51
5/51
6/51
7/51
8/51
9/51
10/51
11/51
12/51
13/51
14/51
15/51
16/51R-b
17/51
18/51
19/51
20/51R-b
21/51
22/51
23/51
24/51
25/51
26/51A-b A-b
27/51
28/51A-b A-b
29/51
30/51
31/51
32/51
33/51
34/51
35/51
36/51
37/51A-b T-b
38/51
39/51
40/51
41/51
42/51
43/51
44/51
45/51
46/51
47/51
48/51
49/51
50/51
51/51

Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes. Scroll the table sideways for all 5 reviewers.

Read the v2 thread

Cover letter [RFC PATCH v2 00/51] 1G page support for guest_memfd

Hello,

This patchset builds upon discussion at LPC 2024 and many guest_memfd upstream calls to provide 1G page support for guest_memfd by taking pages from HugeTLB.

This patchset is based on Linux v6.15-rc6, and requires the mmap support for guest_memfd patchset (Thanks Fuad!) [1].

For ease of testing, this series is also available, stitched together, at https://github.com/googleprodkernel/linux-cc/tree/gmem-1g-page-support-rfc-v2

This patchset can be divided into two sections:

(a) Patches from the beginning up to and including "KVM: selftests:
Update script to map shared memory from guest_memfd" are a modified version of "conversion support for guest_memfd", which Fuad is managing [2].

(b) Patches after "KVM: selftests: Update script to map shared memory from guest_memfd" till the end are patches that actually bring in 1G page support for guest_memfd.

These are the significant differences between (a) and [2]:

+ [2] uses an xarray to track sharability, but I used a maple tree because for 1G pages, iterating pagewise to update shareability was prohibitively slow even for testing. I was choosing from among multi-index xarrays, interval trees and maple trees [3], and picked maple trees because
+ Maple trees were easier to figure out since I didn't have to compute the correct multi-index order and handle edge cases if the converted range wasn't a neat power of 2.
+ Maple trees were easier to figure out as compared to updating parts of a multi-index xarray.
+ Maple trees had an easier API to use than interval trees.
+ [2] doesn't yet have a conversion ioctl, but I needed it to test 1G support end-to-end.
+ (a) Removes guest_memfd from participating in LRU, which I needed, to get conversion selftests to work as expected, since participation in LRU was causing some unexpected refcounts on folios which was blocking conversions.

I am sending (a) in emails as well, as opposed to just leaving it on GitHub, so that we can discuss by commenting inline on emails. If you'd like to just look at 1G page support, here are some key takeaways from the first section (a):

+ If GUEST_MEMFD_FLAG_SUPPORT_SHARED is requested during guest_memfd creation, guest_memfd will
+ Track shareability (whether an index in the inode is guest-only or if the host is allowed to fault memory at a given index).
+ Always be used for guest faults - specifically, kvm_gmem_get_pfn() will be used to provide pages for the guest.
+ Always be used by KVM to check private/shared status of a gfn.
+ guest_memfd now has conversion ioctls, allowing conversion to private/shared
+ Conversion can fail if there are unexpected refcounts on any folios in the range.

Focusing on (b) 1G page support, here's an overview:

1. A bunch of refactoring patches for HugeTLB that isolates the allocation of a HugeTLB folio from other HugeTLB concepts such as VMA-level reservations, and HugeTLBfs-specific concepts, such as where memory policy is stored in the VMA, or where the subpool is stored on the inode.
2. A few patches that add a guestmem_hugetlb allocator within mm/. The guestmem_hugetlb allocator is a wrapper around HugeTLB to modularize the memory management functions, and to cleanly handle cleanup, so that folio cleanup can happen after the guest_memfd inode (and even KVM) goes away.
3. Some updates to guest_memfd to use the guestmem_hugetlb allocator.
4. Selftests for 1G page support.

Here are some remaining issues/TODOs:

1. Memory error handling such as machine check errors have not been implemented.
2. I've not looked into preparedness of pages, only zeroing has been considered.
3. When allocating HugeTLB pages, if two threads allocate indices mapping to the same huge page, the utilization in guest_memfd inode's subpool may momentarily go over the subpool limit (the requested size of the inode at guest_memfd creation time), causing one of the two threads to get -ENOMEM. Suggestions to solve this are appreciated!
4. max_usage_in_bytes statistic (cgroups v1) for guest_memfd HugeTLB pages should be correct but needs testing and could be wrong.
5. memcg charging (charge_memcg()) for cgroups v2 for guest_memfd HugeTLB pages after splitting should be correct but needs testing and could be wrong.
6. Page cache accounting: When a hugetlb page is split, guest_memfd will incur page count in both NR_HUGETLB (counted at hugetlb allocation time) and NR_FILE_PAGES stats (counted when split pages are added to the filemap). Is this aligned with what people expect?

Here are some optimizations that could be explored in future series:

1. Pages could be split from 1G to 2M first and only split to 4K if necessary.
2. Zeroing could be skipped for Coco VMs if hardware already zeroes the pages.

Here's RFC v1 [4] if you're interested in the motivation behind choosing HugeTLB, or the history of this patch series.

[1] https://lore.kernel.org/all/[email protected]/T/
[2] https://lore.kernel.org/all/[email protected]/T/
[3] https://lore.kernel.org/all/[email protected]/
[4] https://lore.kernel.org/all/[email protected]/T/

---

Ackerley Tng (49):
KVM: guest_memfd: Make guest mem use guest mem inodes instead of
anonymous inodes
KVM: guest_memfd: Introduce and use shareability to guard faulting
KVM: selftests: Update guest_memfd_test for INIT_PRIVATE flag
KVM: guest_memfd: Introduce KVM_GMEM_CONVERT_SHARED/PRIVATE ioctls
KVM: guest_memfd: Skip LRU for guest_memfd folios
KVM: Query guest_memfd for private/shared status
KVM: guest_memfd: Add CAP KVM_CAP_GMEM_CONVERSION
KVM: selftests: Test flag validity after guest_memfd supports
conversions
KVM: selftests: Test faulting with respect to
GUEST_MEMFD_FLAG_INIT_PRIVATE
KVM: selftests: Refactor vm_mem_add to be more flexible
KVM: selftests: Allow cleanup of ucall_pool from host
KVM: selftests: Test conversion flows for guest_memfd
KVM: selftests: Add script to exercise private_mem_conversions_test
KVM: selftests: Update private_mem_conversions_test to mmap
guest_memfd
KVM: selftests: Update script to map shared memory from guest_memfd
mm: hugetlb: Consolidate interpretation of gbl_chg within
alloc_hugetlb_folio()
mm: hugetlb: Cleanup interpretation of gbl_chg in
alloc_hugetlb_folio()
mm: hugetlb: Cleanup interpretation of map_chg_state within
alloc_hugetlb_folio()
mm: hugetlb: Rename alloc_surplus_hugetlb_folio
mm: mempolicy: Refactor out policy_node_nodemask()
mm: hugetlb: Inline huge_node() into callers
mm: hugetlb: Refactor hugetlb allocation functions
mm: hugetlb: Refactor out hugetlb_alloc_folio()
mm: hugetlb: Add option to create new subpool without using surplus
mm: truncate: Expose preparation steps for truncate_inode_pages_final
mm: hugetlb: Expose hugetlb_subpool_{get,put}_pages()
mm: Introduce guestmem_hugetlb to support folio_put() handling of
guestmem pages
mm: guestmem_hugetlb: Wrap HugeTLB as an allocator for guest_memfd
mm: truncate: Expose truncate_inode_folio()
KVM: x86: Set disallow_lpage on base_gfn and guest_memfd pgoff
misalignment
KVM: guest_memfd: Support guestmem_hugetlb as custom allocator
KVM: guest_memfd: Allocate and truncate from custom allocator
mm: hugetlb: Add functions to add/delete folio from hugetlb lists
mm: guestmem_hugetlb: Add support for splitting and merging pages
mm: Convert split_folio() macro to function
KVM: guest_memfd: Split allocator pages for guest_memfd use
KVM: guest_memfd: Merge and truncate on fallocate(PUNCH_HOLE)
KVM: guest_memfd: Update kvm_gmem_mapping_order to account for page
status
KVM: Add CAP to indicate support for HugeTLB as custom allocator
KVM: selftests: Add basic selftests for hugetlb-backed guest_memfd
KVM: selftests: Update conversion flows test for HugeTLB
KVM: selftests: Test truncation paths of guest_memfd
KVM: selftests: Test allocation and conversion of subfolios
KVM: selftests: Test that guest_memfd usage is reported via hugetlb
KVM: selftests: Support various types of backing sources for private
memory
KVM: selftests: Update test for various private memory backing source
types
KVM: selftests: Update private_mem_conversions_test.sh to test with
HugeTLB pages
KVM: selftests: Add script to test HugeTLB statistics
KVM: selftests: Test guest_memfd for accuracy of st_blocks

Elliot Berman (1):
filemap: Pass address_space mapping to ->free_folio()

Fuad Tabba (1):
mm: Consolidate freeing of typed folios on final folio_put()

 Documentation/filesystems/locking.rst         |    2 +-
 Documentation/filesystems/vfs.rst             |   15 +-
 Documentation/virt/kvm/api.rst                |    5 +
 arch/arm64/include/asm/kvm_host.h             |    5 -
 arch/x86/include/asm/kvm_host.h               |   10 -
 arch/x86/kvm/x86.c                            |   53 +-
 fs/hugetlbfs/inode.c                          |    2 +-
 fs/nfs/dir.c                                  |    9 +-
 fs/orangefs/inode.c                           |    3 +-
 include/linux/fs.h                            |    2 +-
 include/linux/guestmem.h                      |   23 +
 include/linux/huge_mm.h                       |    6 +-
 include/linux/hugetlb.h                       |   19 +-
 include/linux/kvm_host.h                      |   32 +-
 include/linux/mempolicy.h                     |   11 +-
 include/linux/mm.h                            |    2 +
 include/linux/page-flags.h                    |   32 +
 include/uapi/linux/guestmem.h                 |   29 +
 include/uapi/linux/kvm.h                      |   16 +
 include/uapi/linux/magic.h                    |    1 +
 mm/Kconfig                                    |   13 +
 mm/Makefile                                   |    1 +
 mm/debug.c                                    |    1 +
 mm/filemap.c                                  |   12 +-
 mm/guestmem_hugetlb.c                         |  512 +++++
 mm/guestmem_hugetlb.h                         |    9 +
 mm/hugetlb.c                                  |  488 ++---
 mm/internal.h                                 |    1 -
 mm/memcontrol.c                               |    2 +
 mm/memory.c                                   |    1 +
 mm/mempolicy.c                                |   44 +-
 mm/secretmem.c                                |    3 +-
 mm/swap.c                                     |   32 +-
 mm/truncate.c                                 |   27 +-
 mm/vmscan.c                                   |    4 +-
 tools/testing/selftests/kvm/Makefile.kvm      |    2 +
 .../kvm/guest_memfd_conversions_test.c        |  797 ++++++++
 .../kvm/guest_memfd_hugetlb_reporting_test.c  |  384 ++++
 ...uest_memfd_provide_hugetlb_cgroup_mount.sh |   36 +
 .../testing/selftests/kvm/guest_memfd_test.c  |  293 ++-
 ...memfd_wrap_test_check_hugetlb_reporting.sh |   95 +
 .../testing/selftests/kvm/include/kvm_util.h  |  104 +-
 .../testing/selftests/kvm/include/test_util.h |   20 +-
 .../selftests/kvm/include/ucall_common.h      |    1 +
 tools/testing/selftests/kvm/lib/kvm_util.c    |  465 +++--
 tools/testing/selftests/kvm/lib/test_util.c   |  102 +
 .../testing/selftests/kvm/lib/ucall_common.c  |   16 +-
 .../kvm/x86/private_mem_conversions_test.c    |  195 +-
 .../kvm/x86/private_mem_conversions_test.sh   |  100 +
 virt/kvm/Kconfig                              |    5 +
 virt/kvm/guest_memfd.c                        | 1655 ++++++++++++++++-
 virt/kvm/kvm_main.c                           |   14 +-
 virt/kvm/kvm_mm.h                             |    9 +-
 53 files changed, 5080 insertions(+), 640 deletions(-)
 create mode 100644 include/linux/guestmem.h
 create mode 100644 include/uapi/linux/guestmem.h
 create mode 100644 mm/guestmem_hugetlb.c
 create mode 100644 mm/guestmem_hugetlb.h
 create mode 100644 tools/testing/selftests/kvm/guest_memfd_conversions_test.c
 create mode 100644 tools/testing/selftests/kvm/guest_memfd_hugetlb_reporting_test.c
 create mode 100755 tools/testing/selftests/kvm/guest_memfd_provide_hugetlb_cgroup_mount.sh
 create mode 100755 tools/testing/selftests/kvm/guest_memfd_wrap_test_check_hugetlb_reporting.sh
 create mode 100755 tools/testing/selftests/kvm/x86/private_mem_conversions_test.sh

--
2.49.0.1045.g170613ef41-goog