From 3aca999247e8e3913b6f5a78b557d8dfd7cc6feb Mon Sep 17 00:00:00 2001 From: Cheng Jian Date: Wed, 11 May 2022 20:53:34 +0800 Subject: [PATCH] description/memory: Drain remote per-cpu directly --- study/kernel/00-DESCRIPTION/ARCH.md | 12 +++- study/kernel/00-DESCRIPTION/BPF.md | 14 ++++- study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md | 57 ++++++++++--------- 3 files changed, 54 insertions(+), 29 deletions(-) diff --git a/study/kernel/00-DESCRIPTION/ARCH.md b/study/kernel/00-DESCRIPTION/ARCH.md index d5112b1..3b6e529 100644 --- a/study/kernel/00-DESCRIPTION/ARCH.md +++ b/study/kernel/00-DESCRIPTION/ARCH.md @@ -272,7 +272,7 @@ SGX 旨在以硬件安全为强制性保障, 不依赖于固件和软件的安 ARM & Linaro [Kernel versions highlights](https://developer.arm.com/tools-and-software/open-source-software/linux-kernel) -ARM64 架构文档地址下载 [](https://developer.arm.com/architectures/cpu-architecture) +ARM64 架构文档地址下载 [cpu-architecture](https://developer.arm.com/architectures/cpu-architecture) [Memory Layout on AArch64 Linux](https://www.kernel.org/doc/html/latest/arm64/memory.html) @@ -281,6 +281,16 @@ ARM64 架构文档地址下载 [](https://developer.arm.com/architectures/cpu-ar [硬件特性列表](https://developer.arm.com/architectures/cpu-architecture/a-profile/exploration-tools/feature-names-for-a-profile) + +[Armv8/armv9 架构入门指南(中文)](http://hehezhou.cn/arm_doc) + +[arm8/armv9寄存器速查](http://hehezhou.cn/arm) + +[arm8/armv9指令集](http://hehezhou.cn/isa) + +[代码在线阅读(含有Linux Kernel5.14、TF-A2.5、optee3.16、ffa-spmc等)](http://hehezhou.cn:8080/optee316) + + | 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 | |:----:|:----:|:---:|:----:|:---------:|:----:| | 2012/09/17 | Catalin Marinas | [AArch64 Linux kernel port](https://lore.kernel.org/lkml/1347035226-18649-1-git-send-email-catalin.marinas@arm.com) | 支持 ARM64 | v3 ☑ 3.7-rc1 | [Patchwork v4,0/2](https://patchwork.kernel.org/project/linux-arm-kernel/patch/1347035226-18649-8-git-send-email-catalin.marinas@arm.com) | diff --git a/study/kernel/00-DESCRIPTION/BPF.md b/study/kernel/00-DESCRIPTION/BPF.md index 42d19e7..32dfdcf 100644 --- a/study/kernel/00-DESCRIPTION/BPF.md +++ b/study/kernel/00-DESCRIPTION/BPF.md @@ -190,9 +190,21 @@ raw_tracepoint 相比 tracepoint [The BPF allocator runs into trouble](https://lwn.net/Articles/892743) - [Toward signed BPF programs](https://lwn.net/Articles/853489) + +# 用户态 +------- + +## surtrace & pyLCC +------- + +[微信公众号-Linux 内核之旅--内核 trace 三板斧 - surtrace-cmd](https://mp.weixin.qq.com/s/XanaxrLDwkqTqcfq9B2eOw) + +[龙蜥开源内核追踪利器 Surftrace:协议包解析效率提升 10 倍! | 龙蜥技术](https://mp.weixin.qq.com/s/o3Q-spZmBbs4Gbhv-3U91g) + +[iofsstat:帮你轻松定位 IO 突高,前因后果一目了然 | 龙蜥技术](https://developer.aliyun.com/article/867067) +
* 本作品/博文 ( [AderStep-紫夜阑珊-青伶巷草 Copyright ©2013-2017](http://blog.csdn.net/gatieme) ), 由 [成坚(gatieme)](http://blog.csdn.net/gatieme) 创作. diff --git a/study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md b/study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md index 0ee0173..5079554 100644 --- a/study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md +++ b/study/kernel/00-DESCRIPTION/MEMORY_MANAGER.md @@ -1162,7 +1162,7 @@ PCP 页面对内存碎片可能有潜在的冲击, 它可能会意外导致碎 | 2008/02/04 | Christoph Lameter | [Page allocator: clean up pcp draining functions](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f8f2172537de7af0b0fbd33502d18d52b1339bc) | 1. 重命名 drain_all_local_pages() 为 drain_all_pages(), 因为它清理的其实是所有 CPU 的 PCP 页面, 而不仅仅是 local 的.
2. drain_all_pages() 使用 on_each_cpu() 替代 smp_call_function(). | v1 ☑✓ 2.6.25-rc1 | [LORE](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f8f2172537de7af0b0fbd33502d18d52b1339bc) | | 2012/02/09 | Gilad Ben-Yossef | [mm: only IPI CPUs to drain local pages if they exist](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=74046494ea68676d29ef6501a4bd950f08112a2c) | [Reduce cross CPU IPI interference](https://lore.kernel.org/all/1328776585-22518-1-git-send-email-gilad@benyossef.com) 减少系统中 IPI 数量优化的其中一个补丁, drain_all_pages() 中不再直接发 IPI 给各个 CPU 去 drain_all_pages(), 而是先统计下当前拥有 PCP 页面的 CPU, 标记为 cpus_with_pcps, 只对这些 CPU 发送 IPI. | v9 ☑✓ 3.4-rc1 | [LORE v9,8/8](https://lore.kernel.org/lkml/1328776585-22518-8-git-send-email-gilad@benyossef.com) | -* 使用 WQ_RECLAIM 来 Drain PCP +* 使用统一的 WQ_RECLAIM WorkQueue 来 Drain PCP 原本内存分配(慢速路径)下 Drain PCP 的操作都是通过 IPI 在中断上下文来完成的, v4.11 为了实现 Order-0 页面的批量分配(Bulk Allocator), 优化了页面分配的性能, 引入了中断安全的 Per CPU Allocator. 虽然这个特性很快因为性能回归被 [revert](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d34b0733b452ca3ef1dee36436dab08b8aa6a85c). 但是其他重构却被保留, 其中就包含 [commit 0ccce3b92421 ("mm, page_alloc: drain per-cpu pages from workqueue context")](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=0ccce3b924212e121503619df97cc0f17189b77b) 不再通过发送 IPI 的方式去通知其他 CPU 释放其 PCP 页面, 通过引入 per-cpu 的 drain_local_pages_wq 将释放 PCP 的页面放到 workqueue 上去执行. @@ -1176,7 +1176,33 @@ PCP 页面对内存碎片可能有潜在的冲击, 它可能会意外导致碎 | 2017/01/23 | Mel Gorman | [mm, page_alloc: drain per-cpu pages from workqueue context](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=0ccce3b924212e121503619df97cc0f17189b77b) | [Use per-cpu allocator for !irq requests and prepare for a bulk allocator v5](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=374ad05ab64d696303cec5cc8ec3a65d457b7b1c) 重构 Per CPU Pages 分配器的其中一个补丁. 不再使用 IPI(在中断上下文)去释放 PCP, 而是 [将 drain_local_pages_wq() 将 drain_local_pages() 放到 WORK 中去完成](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0ccce3b924212e121503619df97cc0f17189b77b), 从而防止 PCP 在 IPI 等中断上下文中被释放. | v5 ☑ 4.11-rc1 | [LORE RFC](https://lore.kernel.org/all/20170207201950.20482-1-mhocko@kernel.org), [LORE v5,0/4](https://lore.kernel.org/all/20170123153906.3122-1-mgorman@techsingularity.net), [关注 COMMIT](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=0ccce3b924212e121503619df97cc0f17189b77b) | | 2017/02/24 | Mel Gorman | [mm, page_alloc: use static global work_struct for draining per-cpu](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bd233f538d51c2cae6f0bfc2cf7f0960e1683b8a) | 使用静态的 per-cpu 的 work_struct pcpu_drain 来替代之前 drain_all_pages() 中每次动态通过 alloc_percpu_gfp() 申请的 workqueue. | v1 ☑✓ 4.11-rc1 | [LORE](https://lore.kernel.org/lkml/20170125083038.rzb5f43nptmk7aed@techsingularity.net/), [commit](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bd233f538d51c2cae6f0bfc2cf7f0960e1683b8a) | | 2017/03/07 | Michal Hocko | [mm: move pcp and lru-pcp drainging into single wq](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ce612879ddc78ea7e4de4be80cba4ebf9caa07ee) | 引入一个统一名为 mm_percpu_wq 的 WQ_MEM_RECLAIM workqueue 来接管当前 MM 下存在的 vmstat_work, lru_add_drain_per_cpu 和 drain_local_pages_wq. | v1 ☑✓ 4.11-rc6 | [LORE RFC](https://lore.kernel.org/all/20170207210908.530-1-mhocko@kernel.org)
*-*-*-*-*-*-*-*
[LORE v1](https://lore.kernel.org/all/20170307131751.24936-1-mhocko@kernel.org) | -| 2022/04/20 | Mel Gorman | [Drain remote per-cpu directly](https://patchwork.kernel.org/project/linux-mm/cover/20220420095906.27349-1-mgorman@techsingularity.net/) | 633724 | v1 ☐☑ | [LORE v1,0/6](https://lore.kernel.org/r/20220420095906.27349-1-mgorman@techsingularity.net) | + +* Remote per-cpu cache access + +最初释放 PCP 是通过 IPI 来完成的, 并且经历了不断的修正和优化, 参见 v2.6.24-rc1 的 [Drain per-cpu lists when high-order allocations fail](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e2c55dc87f4a398b9c4dcc702dbc23a07fe14e23), v2.6.25-rc1 的 [Page allocator: clean up pcp draining functions](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f8f2172537de7af0b0fbd33502d18d52b1339bc), v3.4-rc1 的 [mm: only IPI CPUs to drain local pages if they exist](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=74046494ea68676d29ef6501a4bd950f08112a2c). + +随后 v4.11-rc1 的 [mm, page_alloc: drain per-cpu pages from workqueue context](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0ccce3b924212e121503619df97cc0f17189b77b). + +然而即使经历了这么多年的修改, 这个解决方案并不完美. 使用 workqueue 的方式来释放 PCP lists, 最好的情况是, 只需要目标 CPU 上一次上下文切换(切换到 kworker)来运行释放 PCP 列表的回调就可以了. 但是, 如果目标 CPU 处于 tickless 模式, 或者它正在运行高优先级实时任务, 那么工作队列条目可能在很长一段时间内根本不运行. 因此, CPU 上的任何空闲页面都将被锁定在其本地列表中. + +想要完美的解决这个问题, 就需要要在一个 CPU 上即可完成系统中所有 CPU 的 PCP 页面, 这就需要提供一种机制, 能够让一个 CPU 可以安全地访问 其他 remote CPU 的 PCP 页面. + +2021 年, Nicolas Saenz Julienne 的 [mm/page_alloc: Remote per-cpu page list drain support](https://lore.kernel.org/all/20211103170512.2745765-1-nsaenzju@redhat.com) 通过允许远程 CPU 的本地列表中获取页面来缓解这个问题. 尝试添加了自旋锁来控制对 per-CPU 列表的访问, 从根本上消除了它们的 per-CPUness; 这个解决方案是有效的, 但是它只是增加了创建 per-CPU 列表以避免的开销. 所以这些补丁没有进入内核. + +这个算法使用了 RCU 的方式来完成 remote CPU 释放 PCP 页面的操作.
将 PCP 页面列表结构封装到 pcplists 中, 每个 CPU 现在都有两组列表来保存空闲页面: lp(local_page) 和 drain, 其中一组在任何给定的时间都在使用, 而另一组则保留在备用状态(并且是空的). 当系统想要释放所有 CPU 的 PCP 页面时, 就就通过 rcu_replace_pointer() 交换两个指针, 并通过 synchronize_rcu() 等待宽限期结束后对 PCP 页面进行释放. 通过 RCU 这种方式, 不用再通过以前 IPI 或者 workqueue 的方式在 per-cpu 上去完成, 而是通过一个 remote CPU 即可释放系统中所有 CPU 的 PCP 页面.
+其主要优点是它可以很好地解决问题, 避免了对基于配置的启发式方法的需求或不得不修改应用程序(即使用 Marcello Tosatti ATM 正在工作的隔离 prctrl). 参见 [Remote per-CPU page list draining](https://lwn.net/Articles/884448). + +但是在经历了多个版本之后, 并没有被社区所认可. 2022 年, MM 领域的大佬 Mel Gorman 接手了这项工作. 发布了 [Drain remote per-cpu directly](https://patchwork.kernel.org/project/linux-mm/cover/20220420095906.27349-1-mgorman@techsingularity.net). 与 Nicolas 之前 RCU 的方式类似, 他们都移除了以前 WorkQueue 中释放 PCP list 的方案, 但是解决的方式略有不同, Mel 直接使用了 IRQ 安全的 local_lock() 保护 PCP lists. local_lock 本身可以防止迁移, 禁用 IRQ 可以防止在页面分配过程中由于被中断打断而造成异常. 一个自旋锁 [spinlock](https://lore.kernel.org/all/20220509130805.20335-6-mgorman@techsingularity.net) 被添加到 per_cpu_pages 结构中, 以保护列表的内容, 而 local_lock_irq 则进一步阻止迁移和 IRQ 重入. 从而允许一个 CPU 安全地清空远程 PCP lists. + + +| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 | +|:----:|:----:|:---:|:----:|:---------:|:----:| +| 2021/09/21 | Sebastian Andrzej Siewior | [mm/swap: Add static key dependent pagevec locking](https://patchwork.kernel.org/project/linux-mm/cover/20190424111208.24459-1-bigeasy@linutronix.de) | 本系列实现了 swap 的代码路径中通过禁用抢占来同步它对 per-cpu pagevec 结构体的访问. 这是可行的, 需要从中断上下文访问的结构体是通过禁用中断来保护的.
有一种情况下, 需要访问远程 CPU 的 per-cpu 数据, 在 v1 版本中, 试图添加每个 cpu 的自旋锁来访问结构体. 这将增加 lockdep 覆盖率和从远程 CPU 的访问, 不需要 worker.
在 v2 中这是通过在远程 CPU 上启动一个 worker 并等待它完成来解决的.
关于无争用 spin_lock () 的代价, 以及避免每个 cpu worker 的好处很少, 因为它很少被使用. 然后听从社区的建议使用 static key use_pvec_lock, 在某些情况下(如 NOHZ_FULL 情况), 它支持每个 cpu 的锁定. | v1 ☐ | [PatchWork 0/4,v2](https://patchwork.kernel.org/project/linux-mm/cover/20190424111208.24459-1-bigeasy@linutronix.de) | +| 2021/09/21 | Nicolas Saenz Julienne | [mm: Remote LRU per-cpu pagevec cache/per-cpu page list drain support](https://patchwork.kernel.org/project/linux-mm/cover/20210921161323.607817-1-nsaenzju@redhat.com) | 本系列介绍了 mm/swap.c 的每个 CPU LRU pagevec 缓存和 mm/page_alloc 的每个 CPU 页面列表的另一种锁定方案 remote_pcpu_cache_access, 这将允许远程 CPU 消耗它们.
目前, 只有一个本地 CPU 被允许更改其每个 CPU 列表, 并且当进程需要它时, 它会按需这样做 (通过在本地 CPU 上排队引流任务).
大多数系统会迅速处理这个问题, 但它会给 NOHZ_FULL CPU 带来问题, 这些 CPU 无法在不破坏其功能保证(延迟、带宽等) 的情况下接受任何类型的中断. 如果这些进程能够远程耗尽列表本身, 就可以与隔离的 CPU 共存, 但代价是更多的锁约束.
通过 static key remote_pcpu_cache_access 来控制该特性的开启与否, 对于非 nohz_full 用户来说, 默认禁用它, 这保证了最小的功能或性能退化. 而只有当 NOHZ_FULL 的初始化过程成功时, 该特性才会被启用. | v2 ☐ | [2021/09/21 PatchWork 0/6](https://patchwork.kernel.org/project/linux-mm/cover/20210921161323.607817-1-nsaenzju@redhat.com)
*-*-*-*-*-*-*-*
[2021/11/03 PatchWork v2,0/3](https://patchwork.kernel.org/project/linux-mm/cover/20211103170512.2745765-1-nsaenzju@redhat.com) | +| 2022/02/08 | Nicolas Saenz Julienne | [mm/page_alloc: Remote per-cpu lists drain support](https://lore.kernel.org/all/20220208100750.1189808-1-nsaenzju@redhat.com) | 参见 [Remote per-CPU page list draining](https://lwn.net/Articles/884448) | v1 ☐☑✓ | [LORE v1,0/2](https://lore.kernel.org/all/20220208100750.1189808-1-nsaenzju@redhat.com) | +| 2022/02/24 | Suren Baghdasaryan | [mm: page_alloc: replace mm_percpu_wq with kthreads in drain_all_pages](https://lore.kernel.org/all/20220225012819.1807147-1-surenb@google.com) | 20220225012819.1807147-1-surenb@google.com | v1 ☐☑✓ | [LORE v1,0/1](https://lore.kernel.org/all/20220225012819.1807147-1-surenb@google.com) | +| 2022/05/09 | Mel Gorman | [Drain remote per-cpu directly](https://patchwork.kernel.org/project/linux-mm/cover/20220420095906.27349-1-mgorman@techsingularity.net) | 直接使用了 IRQ 安全的 local_lock() 保护 PCP lists. local_lock 本身可以防止迁移, 禁用 IRQ 可以防止在页面分配过程中由于被中断打断而造成异常. 一个自旋锁 [spinlock](https://lore.kernel.org/all/20220509130805.20335-6-mgorman@techsingularity.net) 被添加到 per_cpu_pages 结构中, 以保护列表的内容, 而 local_lock_irq 则进一步阻止迁移和 IRQ 重入. 从而允许一个 CPU 安全地清空远程 PCP lists. | v1 ☐☑ | [2022/04/20 LORE v1,0/6](https://lore.kernel.org/r/20220420095906.27349-1-mgorman@techsingularity.net)
*-*-*-*-*-*-*-*
[2022/05/09 LORE v2,0/6](https://lore.kernel.org/r/20220509130805.20335-1-mgorman@techsingularity.net) | + #### 2.2.5.3 PCP Batch-Free free_pcppages_bulk ------- @@ -1371,29 +1397,6 @@ v2.6.16-rc1 时, 大家发现 pcp->low 水线貌似并没有什么太大的用 | 2021/05/25 | Mel Gorman | [Calculate pcp->high based on zone sizes and active CPUs](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=74f44822097c665041010994502b5971d6cd9f04) | pcp->high 和 pcp->batch 根据 zone 内内存的大小进行调整. 移除了不适用的 vm.percpu_pagelist_fraction 参数. | v2 ☑ 5.14-rc1 | [LORE v1,0/6](https://lore.kernel.org/all/20210521102826.28552-1-mgorman@techsingularity.net)
*-*-*-*-*-*-*-*
[LORE v2,0/6](https://lore.kernel.org/lkml/20210525080119.5455-1-mgorman@techsingularity.net) | -#### 2.2.5.6 Remote per-cpu cache access -------- - -最初释放 PCP 是通过 IPI 来完成的, 并且经历了不断的修正和优化, 参见 v2.6.24-rc1 的 [Drain per-cpu lists when high-order allocations fail](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e2c55dc87f4a398b9c4dcc702dbc23a07fe14e23), v2.6.25-rc1 的 [Page allocator: clean up pcp draining functions](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f8f2172537de7af0b0fbd33502d18d52b1339bc), v3.4-rc1 的 [mm: only IPI CPUs to drain local pages if they exist](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=74046494ea68676d29ef6501a4bd950f08112a2c). 以及 v4.11-rc1 的 [mm, page_alloc: drain per-cpu pages from workqueue context](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0ccce3b924212e121503619df97cc0f17189b77b). - -然而即使经历了这么多年的修改, 这个解决方案并不完美. 最好的情况是, 它会导致每个目标 CPU 上的上下文切换来运行排除列表的回调. 但是, 如果目标 CPU 处于 tickless 模式, 或者它正在运行高优先级实时任务, 那么工作队列条目可能在很长一段时间内根本不运行. 因此, CPU 上的任何空闲页面都将被锁定在其本地列表中, 幸运的是, 大多数空闲页面可能就是锁定在本地列表中的. - -想要完美的解决这个问题, 就要在一个 CPU 上即可完成系统中所有 CPU 的 PCP 页面, 这就需要提供一种机制, 能够让一个 CPU 可以安全地访问 remote CPU 的 PCP 页面. - -[mm/page_alloc: Remote per-cpu page list drain support](https://lore.kernel.org/all/20211103170512.2745765-1-nsaenzju@redhat.com) 通过允许远程 CPU 的本地列表中获取页面来缓解这个问题. 尝试添加了自旋锁来控制对 per-CPU 列表的访问, 从根本上消除了它们的 per-CPUness; 这个解决方案是有效的, 但是它只是增加了创建 per-CPU 列表以避免的开销. 所以这些补丁没有进入内核. - -新算法使用了 RCU 的方式来完成 remote CPU 释放 PCP 页面的操作.
将 PCP 页面列表结构封装到 pcplists 中, 每个 CPU 现在都有两组列表来保存空闲页面: lp(local_page) 和 drain, 其中一组在任何给定的时间都在使用, 而另一组则保留在备用状态(并且是空的). 当系统想要释放所有 CPU 的 PCP 页面时, 就就通过 rcu_replace_pointer() 交换两个指针, 并通过 synchronize_rcu() 等待宽限期结束后对 PCP 页面进行释放. 通过 RCU 这种方式, 不用再通过以前 IPI 或者 workqueue 的方式在 per-cpu 上去完成, 而是通过一个 remote CPU 即可释放系统中所有 CPU 的 PCP 页面.
-其主要优点是它可以很好地解决问题, 避免了对基于配置的启发式方法的需求或不得不修改应用程序(即使用 Marcello Tosatti ATM 正在工作的隔离 prctrl). 参见 [Remote per-CPU page list draining](https://lwn.net/Articles/884448) - -| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 | -|:----:|:----:|:---:|:----:|:---------:|:----:| -| 2021/09/21 | Sebastian Andrzej Siewior | [mm/swap: Add static key dependent pagevec locking](https://patchwork.kernel.org/project/linux-mm/cover/20190424111208.24459-1-bigeasy@linutronix.de) | 本系列实现了swap 的代码路径中通过禁用抢占来同步它对 per-cpu pagevec 结构体的访问. 这是可行的, 需要从中断上下文访问的结构体是通过禁用中断来保护的.
有一种情况下, 需要访问远程 CPU 的 per-cpu 数据, 在 v1 版本中, 试图添加每个 cpu 的自旋锁来访问结构体. 这将增加 lockdep 覆盖率和从远程 CPU 的访问, 不需要 worker.
在 v2 中这是通过在远程 CPU 上启动一个 worker 并等待它完成来解决的.
关于无争用 spin_lock () 的代价, 以及避免每个 cpu worker 的好处很少, 因为它很少被使用. 然后听从社区的建议使用 static key use_pvec_lock, 在某些情况下(如 NOHZ_FULL 情况), 它支持每个 cpu 的锁定. | v1 ☐ | [PatchWork 0/4,v2](https://patchwork.kernel.org/project/linux-mm/cover/20190424111208.24459-1-bigeasy@linutronix.de) | -| 2021/09/21 | Nicolas Saenz Julienne | [mm: Remote LRU per-cpu pagevec cache/per-cpu page list drain support](https://patchwork.kernel.org/project/linux-mm/cover/20210921161323.607817-1-nsaenzju@redhat.com) | 本系列介绍了 mm/swap.c 的每个 CPU LRU pagevec 缓存和 mm/page_alloc 的每个 CPU 页面列表的另一种锁定方案 remote_pcpu_cache_access, 这将允许远程 CPU 消耗它们.
目前, 只有一个本地 CPU 被允许更改其每个 CPU 列表, 并且当进程需要它时, 它会按需这样做 (通过在本地 CPU 上排队引流任务).
大多数系统会迅速处理这个问题, 但它会给 NOHZ_FULL CPU 带来问题, 这些 CPU 无法在不破坏其功能保证(延迟、带宽等) 的情况下接受任何类型的中断. 如果这些进程能够远程耗尽列表本身, 就可以与隔离的 CPU 共存, 但代价是更多的锁约束.
通过 static key remote_pcpu_cache_access 来控制该特性的开启与否, 对于非 nohz_full 用户来说, 默认禁用它, 这保证了最小的功能或性能退化. 而只有当 NOHZ_FULL 的初始化过程成功时, 该特性才会被启用. | v2 ☐ | [2021/09/21 PatchWork 0/6](https://patchwork.kernel.org/project/linux-mm/cover/20210921161323.607817-1-nsaenzju@redhat.com)
*-*-*-*-*-*-*-*
[2021/11/03 PatchWork v2,0/3](https://patchwork.kernel.org/project/linux-mm/cover/20211103170512.2745765-1-nsaenzju@redhat.com) | -| 2022/02/08 | Nicolas Saenz Julienne | [mm/page_alloc: Remote per-cpu lists drain support](https://lore.kernel.org/all/20220208100750.1189808-1-nsaenzju@redhat.com) | 参见 [Remote per-CPU page list draining](https://lwn.net/Articles/884448) | v1 ☐☑✓ | [LORE v1,0/2](https://lore.kernel.org/all/20220208100750.1189808-1-nsaenzju@redhat.com) | -| 2022/02/24 | Suren Baghdasaryan | [mm: page_alloc: replace mm_percpu_wq with kthreads in drain_all_pages](https://lore.kernel.org/all/20220225012819.1807147-1-surenb@google.com) | 20220225012819.1807147-1-surenb@google.com | v1 ☐☑✓ | [LORE v1,0/1](https://lore.kernel.org/all/20220225012819.1807147-1-surenb@google.com) | - - - #### 2.2.5.7 PCP 分配器框架变更与优化时间线(总结) ------- @@ -3744,7 +3747,7 @@ __alloc_pages_direct_reclaim() | 2010/11/09 | Glauber Costa | [vmscan: per-node deferred work](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1d3d4437eae1bb2963faab427f65f90663c64aa1) | 实现 per node 的内存回收. | v1 ☑ 3.19-rc1 | [LORE](https://lore.kernel.org/lkml/20101109123246.GA11477@amd), [LORE v9,00/17](https://lore.kernel.org/all/153112469064.4097.2581798353485457328.stgit@localhost.localdomain), [COMMIT](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1d3d4437eae1bb2963faab427f65f90663c64aa1) | | 2010/11/09 | Nick Piggin | [mm: vmscan implement per-zone shrinkers](https://lore.kernel.org/all/153063036670.1818.16010062622751502.stgit@localhost.localdomain/) | 实现 per zone 的内存回收. | v1 ☑ 3.19-rc1 | [LORE](https://lore.kernel.org/lkml/20101109123246.GA11477@amd), [LORE v9,00/17](https://lore.kernel.org/all/153112469064.4097.2581798353485457328.stgit@localhost.localdomain), [COMMIT](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6b4f7799c6a5703ac6b8c0649f4c22f00fa07513) | | 2012/11/28 | Dave Chinner | [Numa aware LRU lists and shrinkers](https://lore.kernel.org/all/1354058086-27937-1-git-send-email-david@fromorbit.com) | 实现 SHRINKER_NUMA_AWARE | v1 ☐☑✓ | [LORE v1,0/19](https://lore.kernel.org/all/1354058086-27937-1-git-send-email-david@fromorbit.com) | -| 2022/04/22 | Roman Gushchin | [mm: introduce shrinker sysfs interface](https://patchwork.kernel.org/project/linux-mm/cover/20220416002756.4087977-1-roman.gushchin@linux.dev/) | 内核中有 50 多个不同的 shrinker, 在内存压力下, 内核会按照它们在系统中创建/注册的顺序对它们施加一些压力. 其中一些只能包含很少的对象, 一些可以相当大. 有些可以有效地回收内存, 有些则不然. 但是当前却没有有效的方法对单个 shrinker 进行计数和扫描, 并对其进行分析. 现有的唯一调试机制是 do_shrink_slab() 中的两个 TRACEPOINT: mm_shrink_slab_start 和 mm_shrink_slab_end. 不过, 它们并没有涵盖所有内容: 报告 0 个对象的 shrinker永远不会出现, 也不支持支持支持 MEMCG 的 shrinker. shrinker 通过其扫描功能进行识别, 但这并不总是足够的. 为了为内存 shrinker 提供更好的可见性和调试选项, 这个补丁集引入了 `/sys/kernel/shrinker` 接口, 在某种程度上类似于 `/sys/kernel/slab`. 为系统中注册的每个 shrinker 创建一个目录, 该目录包含两个文件结点 "count" 和 "scan" , 允许触发 count_objects() 和 scan_objects() 回调. 对于 MEMCG-Aware 和 NUMA-Aware 的 shrinker, 还额外提供了 count_memcg、scan_memcg、count_node、scan_node、count_memcg_node 和 scan_memcg_node. 它们允许获取每个 MEMCG 和每个 NUMA NODE 的对象计数, 并仅收缩特定的 MEMCG 或者 NUMA NODE. 为了使调试更加愉快, 补丁集还为所有 shrinker 命名, 以便 sysfs 条目可以有更多有意义的名称. | v2 ☐☑ | [LORE v1,0/5](https://lore.kernel.org/r/20220416002756.4087977-1-roman.gushchin@linux.dev)
*-*-*-*-*-*-*-*
[LORE v1,0/5](https://lore.kernel.org/all/20220422015853.748291-1-roman.gushchin@linux.dev)
*-*-*-*-*-*-*-*
[LORE v2,0/7](https://lore.kernel.org/r/20220422202644.799732-1-roman.gushchin@linux.dev) | +| 2022/04/22 | Roman Gushchin | [mm: introduce shrinker debugfs interface](https://patchwork.kernel.org/project/linux-mm/cover/20220416002756.4087977-1-roman.gushchin@linux.dev/) | 内核中有 50 多个不同的 shrinker, 在内存压力下, 内核会按照它们在系统中创建/注册的顺序对它们施加一些压力. 其中一些只能包含很少的对象, 一些可以相当大. 有些可以有效地回收内存, 有些则不然. 但是当前却没有有效的方法对单个 shrinker 进行计数和扫描, 并对其进行分析. 现有的唯一调试机制是 do_shrink_slab() 中的两个 TRACEPOINT: mm_shrink_slab_start 和 mm_shrink_slab_end. 不过, 它们并没有涵盖所有内容: 报告 0 个对象的 shrinker永远不会出现, 也不支持支持支持 MEMCG 的 shrinker. shrinker 通过其扫描功能进行识别, 但这并不总是足够的. 为了为内存 shrinker 提供更好的可见性和调试选项, 这个补丁集引入了 `/sys/kernel/shrinker` 接口, 在某种程度上类似于 `/sys/kernel/slab`. 为系统中注册的每个 shrinker 创建一个目录, 该目录包含两个文件结点 "count" 和 "scan" , 允许触发 count_objects() 和 scan_objects() 回调. 对于 MEMCG-Aware 和 NUMA-Aware 的 shrinker, 还额外提供了 count_memcg、scan_memcg、count_node、scan_node、count_memcg_node 和 scan_memcg_node. 它们允许获取每个 MEMCG 和每个 NUMA NODE 的对象计数, 并仅收缩特定的 MEMCG 或者 NUMA NODE. 为了使调试更加愉快, 补丁集还为所有 shrinker 命名, 以便 sysfs 条目可以有更多有意义的名称. | v2 ☐☑ | [LORE v1,0/5](https://lore.kernel.org/r/20220416002756.4087977-1-roman.gushchin@linux.dev)
*-*-*-*-*-*-*-*
[LORE v1,0/5](https://lore.kernel.org/all/20220422015853.748291-1-roman.gushchin@linux.dev)
*-*-*-*-*-*-*-*
[LORE v2,0/7](https://lore.kernel.org/r/20220422202644.799732-1-roman.gushchin@linux.dev)
*-*-*-*-*-*-*-*
[LORE v3,0/6](https://lore.kernel.org/r/20220509183820.573666-1-roman.gushchin@linux.dev) | | 2022/04/21 | Kent Overstreet | [Printbufs & shrinker OOM reporting](https://patchwork.kernel.org/project/linux-mm/cover/20220419203202.2670193-1-kent.overstreet@gmail.com) | 633514 | v1 ☐☑ | [LORE v1,0/4](https://lore.kernel.org/all/20220419203202.2670193-1-kent.overstreet@gmail.com)
*-*-*-*-*-*-*-*
[LORE v1,0/4](https://lore.kernel.org/all/20220421234837.3629927-1-kent.overstreet@gmail.com) | @@ -4548,7 +4551,7 @@ Google 的工程师 Mina Almasry 提出了一种新的思路, 通过 [mremap 的 | 2022/02/01 | Anshuman Khandual | [mm/hugetlb: Generalize ARCH_WANT_GENERAL_HUGETLB](https://patchwork.kernel.org/project/linux-mm/patch/1643718465-4324-1-git-send-email-anshuman.khandual@arm.com/) | 610328 |v1 ☐☑ | [PatchWork v1,0/1](https://lore.kernel.org/r/1643718465-4324-1-git-send-email-anshuman.khandual@arm.com) | | 2022/03/07 | Mike Kravetz | [hugetlb: do not demote poisoned hugetlb pages](https://patchwork.kernel.org/project/linux-mm/patch/20220307215707.50916-1-mike.kravetz@oracle.com/) | 621194 | v1 ☐☑ | [LORE v1,0/1](https://lore.kernel.org/r/20220307215707.50916-1-mike.kravetz@oracle.com) | | 2022/03/18 | Muchun Song | [add hugetlb_free_vmemmap sysctl](https://patchwork.kernel.org/project/linux-mm/cover/20220307130708.58771-1-songmuchun@bytedance.com/) | 621009 | v3 ☐☑ | [2022/03/07 LORE v3,0/4](https://lore.kernel.org/r/20220307130708.58771-1-songmuchun@bytedance.com)
*-*-*-*-*-*-*-*
[2022/03/18 LORE v4,0/4](https://lore.kernel.org/r/20220318100720.14524-1-songmuchun@bytedance.com) | -| 2022/04/12 | Muchun Song | [add hugetlb_optimize_vmemmap sysctl](https://patchwork.kernel.org/project/linux-mm/cover/20220412111434.96498-1-songmuchun@bytedance.com/) | 631440 | v7 ☐☑ | [LORE v7,0/4](https://lore.kernel.org/r/20220412111434.96498-1-songmuchun@bytedance.com)
*-*-*-*-*-*-*-*
[LORE v8,0/4](https://lore.kernel.org/r/20220413144748.84106-1-songmuchun@bytedance.com)
*-*-*-*-*-*-*-*
[LORE v9,0/4](https://lore.kernel.org/r/20220429121816.37541-1-songmuchun@bytedance.com) | +| 2022/04/12 | Muchun Song | [add hugetlb_optimize_vmemmap sysctl](https://patchwork.kernel.org/project/linux-mm/cover/20220412111434.96498-1-songmuchun@bytedance.com/) | 631440 | v7 ☐☑ | [LORE v7,0/4](https://lore.kernel.org/r/20220412111434.96498-1-songmuchun@bytedance.com)
*-*-*-*-*-*-*-*
[LORE v8,0/4](https://lore.kernel.org/r/20220413144748.84106-1-songmuchun@bytedance.com)
*-*-*-*-*-*-*-*
[LORE v9,0/4](https://lore.kernel.org/r/20220429121816.37541-1-songmuchun@bytedance.com)
*-*-*-*-*-*-*-*
[LORE v10,0/4](https://lore.kernel.org/r/20220509062703.64249-1-songmuchun@bytedance.com) | | 2013/03/20 | David Rientjes | [mm, hugetlb: include hugepages in meminfo](https://lore.kernel.org/all/alpine.DEB.2.02.1303201207110.28997@chino.kir.corp.google.com) | alpine.DEB.2.02.1303201207110.28997@chino.kir.corp.google.com | v2 ☐☑✓ | [LORE](https://lore.kernel.org/all/alpine.DEB.2.02.1303201207110.28997@chino.kir.corp.google.com) | | 2022/04/15 | Christophe Leroy | [mm, hugetlbfs: Allow for "high" userspace addresses](https://patchwork.kernel.org/project/linux-mm/patch/ab847b6edb197bffdfe189e70fb4ac76bfe79e0d.1650033747.git.christophe.leroy@csgroup.eu/) | 632590 | v10 ☐☑ | [LORE v10](https://lore.kernel.org/r/ab847b6edb197bffdfe189e70fb4ac76bfe79e0d.1650033747.git.christophe.leroy@csgroup.eu) | | 2022/05/08 | Mike Kravetz | [hugetlb: Change huge pmd sharing synchronization again](https://patchwork.kernel.org/project/linux-mm/cover/20220420223753.386645-1-mike.kravetz@oracle.com/) | 之前 [v5.7 中添加了](https://lore.kernel.org/linux-mm/43faf292-245b-5db5-cce9-369d8fb6bd21@infradead.org) commit c0d0381ade79 ("hugetlbfs: use i_mmap_rwsem for more pmd sharing synchronization") 时, 社区就[报告了性能回归](https://lore.kernel.org/lkml/20200622005551.GK5535@shao2-debian). 当时, Mike Kravetz 提出了一个[解决回归的建议](https://lore.kernel.org/linux-mm/20200706202615.32111-1-mike.kravetz@oracle.com), 但没有被合入. 这个补丁集使用一个新的 hugetlb 特定的 per-vma rw 信号量来同步 PMD 共享. 为了更好的演示这个性能回归, 作者构造了一个简单的测试用例. | v2 ☐☑ | [2022/04/20 LORE v2,0/6](https://lore.kernel.org/r/20220420223753.386645-1-mike.kravetz@oracle.com)
*-*-*-*-*-*-*-*
[2022/05/08 LORE v3,0/8](https://lore.kernel.org/r/20220508183420.18488-1-mike.kravetz@oracle.com) |