Documentation/admin-guide/mm/hugetlbpage.rst.
                        Format: size[KMG]
  
 +      hugetlb_cma=    [HW,CMA] The size of a CMA area used for allocation
 +                      of gigantic hugepages. Or using node format, the size
 +                      of a CMA area per node can be specified.
 +                      Format: nn[KMGTPE] or (node format)
 +                              <node>:nn[KMGTPE][,<node>:nn[KMGTPE]]
 +
 +                      Reserve a CMA area of given size and allocate gigantic
 +                      hugepages using the CMA allocator. If enabled, the
 +                      boot-time allocation of gigantic hugepages is skipped.
 +
        hugetlb_free_vmemmap=
-                       [KNL] Reguires CONFIG_HUGETLB_PAGE_FREE_VMEMMAP
+                       [KNL] Reguires CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
                        enabled.
                        Allows heavy hugetlb users to free up some more
                        memory (7 * PAGE_SIZE for each 2MB hugetlb page).
 
        int (*launder_folio)(struct folio *);
        bool (*is_partially_uptodate)(struct folio *, size_t from, size_t count);
        int (*error_remove_page)(struct address_space *, struct page *);
-       int (*swap_activate)(struct file *);
+       int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)
        int (*swap_deactivate)(struct file *);
+       int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
  
  locking rules:
 -      All except dirty_folio and freepage may block
 +      All except dirty_folio and free_folio may block
  
  ======================        ======================== =========      ===============
 -ops                   PageLocked(page)         i_rwsem        invalidate_lock
 +ops                   folio locked             i_rwsem        invalidate_lock
  ======================        ======================== =========      ===============
  writepage:            yes, unlocks (see below)
 -readpage:             yes, unlocks                            shared
 +read_folio:           yes, unlocks                            shared
  writepages:
 -dirty_folio           maybe
 +dirty_folio:          maybe
  readahead:            yes, unlocks                            shared
  write_begin:          locks the page           exclusive
  write_end:            yes, unlocks             exclusive
  error_remove_page:    yes
  swap_activate:                no
  swap_deactivate:      no
+ swap_rw:              yes, unlocks
  ======================        ======================== =========      ===============
  
 -->write_begin(), ->write_end() and ->readpage() may be called from
 +->write_begin(), ->write_end() and ->read_folio() may be called from
  the request handler (/dev/loop).
  
 -->readpage() unlocks the page, either synchronously or via I/O
 +->read_folio() unlocks the folio, either synchronously or via I/O
  completion.
  
 -->readahead() unlocks the pages that I/O is attempted on like ->readpage().
 +->readahead() unlocks the folios that I/O is attempted on like ->read_folio().
  
  ->writepage() is used for two purposes: for "memory cleansing" and for
  "sync".  These are quite different operations and the behaviour may differ
 
  
                bool (*is_partially_uptodate) (struct folio *, size_t from,
                                               size_t count);
 -              void (*is_dirty_writeback) (struct page *, bool *, bool *);
 +              void (*is_dirty_writeback)(struct folio *, bool *, bool *);
                int (*error_remove_page) (struct mapping *mapping, struct page *page);
-               int (*swap_activate)(struct file *);
+               int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)
                int (*swap_deactivate)(struct file *);
+               int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
        };
  
  ``writepage``
 
        select ARCH_SUPPORTS_ATOMIC_RMW
        select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
        select ARCH_SUPPORTS_HUGETLBFS if MMU
+       select ARCH_SUPPORTS_PAGE_TABLE_CHECK
        select ARCH_USE_MEMTEST
 +      select ARCH_USE_QUEUED_RWLOCKS
        select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
        select ARCH_WANT_FRAME_POINTERS
        select ARCH_WANT_GENERAL_HUGETLB
 
  endif
  
  obj-y                         :=  init.o init_$(BITS).o fault.o ioremap.o extable.o mmap.o \
-                                   pgtable.o physaddr.o tlb.o cpu_entry_area.o maccess.o
 -                                  pgtable.o physaddr.o setup_nx.o tlb.o cpu_entry_area.o maccess.o pgprot.o
++                                  pgtable.o physaddr.o tlb.o cpu_entry_area.o maccess.o pgprot.o
  
  obj-y                         += pat/
  
 
        .write_begin = nfs_write_begin,
        .write_end = nfs_write_end,
        .invalidate_folio = nfs_invalidate_folio,
 -      .releasepage = nfs_release_page,
 +      .release_folio = nfs_release_folio,
-       .direct_IO = nfs_direct_IO,
  #ifdef CONFIG_MIGRATION
        .migratepage = nfs_migrate_page,
  #endif
 
  static inline unsigned int nr_free_highpages(void) { return 0; }
  static inline unsigned long totalhigh_pages(void) { return 0UL; }
  
 +static inline bool is_kmap_addr(const void *x)
 +{
 +      return false;
 +}
 +
  #endif /* CONFIG_HIGHMEM */
  
- /*
-  * Prevent people trying to call kunmap_atomic() as if it were kunmap()
-  * kunmap_atomic() should get the return value of kmap_atomic, not the page.
+ /**
+  * kunmap_atomic - Unmap the virtual address mapped by kmap_atomic() - deprecated!
+  * @__addr:       Virtual address to be unmapped
+  *
+  * Unmaps an address previously mapped by kmap_atomic() and re-enables
+  * pagefaults. Depending on PREEMP_RT configuration, re-enables also
+  * migration and preemption. Users should not count on these side effects.
+  *
+  * Mappings should be unmapped in the reverse order that they were mapped.
+  * See kmap_local_page() for details on nesting.
+  *
+  * @__addr can be any address within the mapped page, so there is no need
+  * to subtract any offset that has been added. In contrast to kunmap(),
+  * this function takes the address returned from kmap_atomic(), not the
+  * page passed to it. The compiler will warn you if you pass the page.
   */
  #define kunmap_atomic(__addr)                                 \
  do {                                                          \
 
  #define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
  #endif
  
+ /*
+  * Arches can define this function if they want to decide the minimum slab
+  * alignment at runtime. The value returned by the function must be a power
+  * of two and >= ARCH_SLAB_MINALIGN.
+  */
+ #ifndef arch_slab_minalign
+ static inline unsigned int arch_slab_minalign(void)
+ {
+       return ARCH_SLAB_MINALIGN;
+ }
+ #endif
+ 
  /*
 - * kmalloc and friends return ARCH_KMALLOC_MINALIGN aligned
 - * pointers. kmem_cache_alloc and friends return ARCH_SLAB_MINALIGN
 - * aligned pointers.
 + * kmem_cache_alloc and friends return pointers aligned to ARCH_SLAB_MINALIGN.
 + * kmalloc and friends return pointers aligned to both ARCH_KMALLOC_MINALIGN
 + * and ARCH_SLAB_MINALIGN, but here we only assume the former alignment.
   */
  #define __assume_kmalloc_alignment __assume_aligned(ARCH_KMALLOC_MINALIGN)
  #define __assume_slab_alignment __assume_aligned(ARCH_SLAB_MINALIGN)
 
  int cg_write(const char *cgroup, const char *control, char *buf)
  {
        char path[PATH_MAX];
-       ssize_t len = strlen(buf);
+       ssize_t len = strlen(buf), ret;
  
        snprintf(path, sizeof(path), "%s/%s", cgroup, control);
- 
-       if (write_text(path, buf, len) == len)
-               return 0;
- 
-       return -1;
+       ret = write_text(path, buf, len);
+       return ret == len ? 0 : ret;
  }
  
 +int cg_write_numeric(const char *cgroup, const char *control, long value)
 +{
 +      char buf[64];
 +      int ret;
 +
 +      ret = sprintf(buf, "%lu", value);
 +      if (ret < 0)
 +              return ret;
 +
 +      return cg_write(cgroup, control, buf);
 +}
 +
  int cg_find_unified_root(char *root, size_t len)
  {
        char buf[10 * PAGE_SIZE];