Skip to content

lianux-mm/linux_patch_learn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 

Repository files navigation

linux_patch_learn

patch review and learn

roadmap

THP

  • 2010-11-03 [PATCH 00 of 66] Transparent Hugepage Support #32 - Andrea Arcangeli
    • 支持 anon THP
    • v33 https://lore.kernel.org/all/20101215051540.GP5638@random.random/
    • thp: transparent hugepage core
      • 处理 anon page fault 时,会预先分配好一个 PTE pagetable,存放到 mm_struct 粒度的链表里。现在这个函数叫做 pgtable_trans_huge_deposit(),与之相对应的函数是 pgtable_trans_huge_withdraw(),即存款和提款。
      • zap_huge_pmd() 时,会把这个预留的 pagetalbe 释放掉。
  • 2014-11-11 Transparent huge page reference counting [LWN.net]
  • 2015-10-06 [PATCHv12 00/37] THP refcounting redesign - Kirill A. Shutemov
    • 新的 refcount mapcout 方案
      • anon THP 同时存在 PMD map 和 PTE map 时,会给所有 subpage 的 mapcount +1,这是为了保证 atomici page_remove_rmap();并且,还会加上 PG_double_map bit,用于在 page_remove_rmap() 时判断是否同时存在 anon THP 的 PMD map 和 PTE map,如果同时存在,并且此时正在 remove 最后一个 PMD map 了,就需要把之前给所有 subpage +1 的 mapcount 给 -1 回来。
    • 支持 THP 的 PMD map 和 PTE map 共存
    • [PATCHv12 29/37] thp: implement split_huge_pmd() 新的 PMD 页表拆分实现
      • 会 page_ref_add(page, HPAGE_PMD_NR - 1); 这是因为多出了 512 个 PTE 映射,少了 1 个 PMD 映射,而对 subpage 进行 get_page() 实际上是对 head page 操作的。
    • [PATCHv12 30/37] thp: add option to setup migration entries during PMD split
      1. PATCH RFC 和之前一样依赖于 compound_lock()
      2. 从 PATCHv2 开始,则是通过 migration PTE entries 来 stabilize page counts,也就是把页面放进 swapcache?和 try_to_unmap 差不多。
    • [PATCHv12 32/37] thp: reintroduce split_huge_page() 新的 THP 大页拆分实现
      1. 持有 anon_vma 锁,因为接下来我们要 rmap walk 了
      2. 检查是不是只有 caller 有额外的一个 refcount(也就是除了与 mapcount 一一对应的 refcount 以外,还有其他的 refcount,这也意味着现在页面被 pin 住了无法 migrate)
      3. freeze_page():这个函数名不够好,其实就是反向映射,并做页表拆分
      4. 遍历 anon_vma 区间树,找到所有映射了该大页的 PMD 虚拟地址
      5. freeze_page_vma() 拆分 PMD 页表。有可能已经 swap out 了,页表已经拆分了,这时则是处理这些 PTE swap entry。
    • [PATCHv12 34/37] thp: introduce deferred_split_huge_page() 首次支持延迟拆分大页。如果某个 THP 已经不存在 PMD map,如果其中某些 subpage 不存在 PTE map,那么这些 subpage 也许是可以被释放的(之所以说“也许”,是因为还要考虑到 refcount),这就需要先 split THP 拆成小页,然后才能释放。这个 patch 做的事情:在 subpage 也许可以被释放时,把要拆分的 THP 放进一个队列,等内存回收时由 shrinker 来释放。
      • 在 page_remove_rmap() PMD page 时,如果这是最后一个 unmap 的大页,并且有 nr 个 subpage 没有 PTE map,说明这 nr 个 subpage 可以被释放,把 THP 放进队列。
      • 在 page_remove_rmap() subpage 时,如果 unmap 该 subpage 后,该 subpage 的 mapcount 为 -1,这说明,首先,已经没有 PageDoubleMap 带来的 1 个 mapcount,即,该 THP 没有 PMD map 了,另外,还说明该 subpage 没有 PTE map 了。于是把 THP 放进队列。
      • 定义了一个 deferred_split_shrinker
      • 在拆分 THP 时,如果该大页在队列内,则将其从队列中移除。
      • 对 mlocked THP 的处理
  • 2016-03-07 [PATCHv2 0/4] thp: simplify freeze_page() and unfreeze_page() - Kirill A. Shutemov
    • 在大页拆分时,使用通用的 rmap walker try_to_unmap(),简化了 freeze_page()unfreeze_page()
    • TTU_SPLIT_HUGE_PMD 会让 try_to_unmap() 时先 split_huge_pmd_address() 拆分 PMD 页表。注意每次调用 try_to_unmap() 只会 unmap 一个 page 的所有反向映射,所以要调用 HPAGE_PMD_NR 次。
  • 2016-05-11 Transparent huge pages in the page cache [LWN.net]
  • 2016-06-15 [PATCHv9 00/32] THP-enabled tmpfs/shmem using compound pages - Kirill A. Shutemov
    • 支持 tmpfs/shmem THP
    • [PATCHv9 05/32] rmap: support file thp
      • page_add_file_rmap() 对于 THP 会把每个 subpage 的 mapcount 都 +1。不理解为什不能和 page_add_anon_rmap() 一样,commit message 里说是后续再优化。
      • 不理解。PG_double_map 的优化对 file page 无效,这是因为 lifecycle 与 anon page 不同,file page 在没有 map 时还可以继续存在,随时再次被 map。
    • thp: support file pages in zap_huge_pmd()
    • thp: handle file pages in split_huge_pmd()
      • 只做了 unmap,没有像 anon page 那样分配页表去填 PTE,因为 file page 可以等到 page fault 时再去填 PTE 页表。不理解,如果填 PTE 页表,避免后续可能的 pagefault 不是很好吗?
    • thp: handle file COW faults
      • split huge pmd 然后在 pte level 处理。因为不清楚在 private file page CoW 场景分配 huge page 的收益如何,可能是过度设计。
    • thp: skip file huge pmd on copy_huge_pmd()
      • 典型场景:进程 clone。对于 file pages,可以不 alloc pagetable,不 copy pte/pmd,可以在 pagefault 时做。copy_huge_pmd() 的调用路径只有 copy_page_range(),后者会使得没有 vma->anon_vma 的跳过 copy pte/pmd。但是因为 private file mapping 是可以有 anon_vma 的,所以没有跳过,这里选择了让 copy_huge_pmd() 通过 vma->vm_ops 把这种情况检查出来,跳过 private file huge pmd 的 copy。
    • thp: file pages support for split_huge_page()
    • vmscan: split file huge pages before paging them out
    • filemap: prepare find and delete operations for huge pages
    • shmem: add huge pages support
  • 2022-11-03 [PATCH 0/3] mm,huge,rmap: unify and speed up compound mapcounts - Hugh Dickins
    • 优化 compound mapcount
    • mm,thp,rmap: simplify compound page mapcount handling
  • 2022-11-22 [PATCH v2 0/3] mm,thp,rmap: rework the use of subpages_mapcount - Hugh Dickins
  • 2024-04-09 [PATCH v1 00/18] mm: mapcount for large folios + page_mapcount() cleanups - David Hildenbrand
  • 2023-07-10 [PATCH v4 0/9] Create large folios in iomap buffered write path - Matthew Wilcox (Oracle)
  • 2024-04-15 [PATCH v3 0/4] mm/filemap: optimize folio adding and splitting - Kairui Song
  • 2024-05-21 Facing down mapcount madness [LWN.net]
  • 2024-02-26 [PATCH v5 0/8] Split a folio to any lower order folios - Zi Yan
    • 支持将 folio split 到任意 low order
  • 2025-03-07 [PATCH v10 0/8] Buddy allocator like (or non-uniform) folio split - Zi Yan
    • 支持 non-uniform folio split
  • 2025-05-12 [PATCH v2 0/8] ext4: enable large folio for regular files - Zhang Yi
    • 为 ext4 regular files 支持 large folio
  • 2017-05-15 🚧 [PATCH -mm -v11 0/5] THP swap: Delay splitting THP during swapping out - Huang, Ying

selftest

  • 2025-8-18[PATCH v5 0/5] Better split_huge_page_test result check 这一组patch增加了对于thp分裂后的order检查,Just note that the code does not handle memremapped THP, since it only checks page flags without checking the PFN. So when a vaddr range is mapped to a THP/mTHP head page and some other THP/mTHP tail pages, the code just treats the whole vaddr range as if it is mapped to a single THP/mTHP and gets a wrong order. After-split folios do not have this concern, so gather_after_split_folio_orders() is simplified to not handle such cases. 目前支持的场景如上,虽然baoling老师重用了这组patch在[RFC PATCH 00/11] add shmem mTHP collapse support但是可能有点仍会出现问题,目前ziyan老师局限的这种场景比较稳健

TAO

mTHP

selftests

CONT PTE

rmap

selftests

madvise

  • 2025-06-07 [PATCH v4] mm: use per_vma lock for MADV_DONTNEED - Barry Song

    • mm: madvise: use walk_page_range_vma() instead of walk_page_range()

      • do_madvise [behavior=MADV_DONTNEED]

        • madvise_lock

          • lock_vma_under_rcu
            • madvise_do_behavior
              • madvise_single_locked_vma
                • madvise_vma_behavior
                  • madvise_dontneed_free
                    • madvise_dontneed_single_vma
                    • map_page_range_single_batched [.reclaim_pt = true]
                    • unmap_single_vma
                    • unmap_page_range
                    • zap_p4d_range
                    • zap_pud_range
                    • zap_pmd_range
                    • zap_pte_range
                    • try_get_and_clear_pmd
                    • free_pte

          调用关系如上所示 do_behavior 中遍历会调用 madvise_walk_vmas 就已经进行了 vma 的查找,之后调用 madvise_free_single_vma 时就不需要在 walk_page_range 进行 vma 的查找了,直接使用 use walk_page_range_vma()传入 vma 参数就可以,减少了一次 vma 的查找开销

    • mm: use per_vma lock for MADV_DONTNEED 目前支持的 per vma 仅限于本地进程 single vma 同时不能涉及 uffd,这样的情况使用 rcu 机制可以极大的降低优先级翻转和读者等待,其他的情况回退到 mmap_lock(读写锁), 新的锁的模式 MADVISE_VMA_READ_LOCK 区别原来的读写锁只有 dontneed 和 free 这俩行为支持

    • mm: madvise: use per_vma lock for MADV_FREE 为 free 扩展 per vma 支持,同时之前的 walk page 的路径中增加 PGWALK_VMA_RDLOCK_VERIFY 只会锁住当前的 vma

    • mm: fix the race between collapse and PT_RECLAIM under per-vma lock collapse 合并时操作的是整个的 2M 空间的 vma,而之前的 dontneed 和 free 的逻辑在回收时候允许支持 per vma 造成了 lock race,通过改变 lock 顺序解除 lock race

msharefs

LUO

MGLRU

mm init

reclaim

About

patch review and learn

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •