当前位置:首页>Linux>Linux MM 2026-04-29 最新 Feature 分析报告

Linux MM 2026-04-29 最新 Feature 分析报告

  • 2026-06-27 13:29:39
Linux MM 2026-04-29 最新 Feature 分析报告
目录
  1. ARM64 per-CPU 页表优化 this_cpu_*() 操作
  2. KASAN HW Tags 跳过栈和页表标记优化
  3. 移除 READ_ONLY_THP_FOR_FS 并支持可写文件 THP
  4. per-VMA 锁全配置可用化
  5. KHO:启动时大页分配与 KHO 良好协作
  6. Deferred Inode Reclaim:卸载复杂 inode 回收到工作队列
  7. process_mrelease 引入 PROCESS_MRELEASE_REAP_KILL 标志
  8. DAMON_RECLAIM/LRU_SORT 默认监控全部 System RAM
  9. memcontrol:修复 isolated CPU 上 FLUSHING_CACHED_CHARGE 永久卡死
  10. mm/vmscan:修复 MGLRU 中延迟的 flusher 唤醒
  11. mm/khugepaged:MADV_COLLAPSE 对 SCAN_PAGE_HAS_PRIVATE 返回 -EAGAIN
  12. mm/madvise:在 MADV_DONTNEED 中保留 uprobe 断点
  13. x86/mm:修复 PMD 大小 vmemmap 页的释放内存泄漏
  14. mm/memcontrol:修复 get_non_dying_memcg_end() RCU 不平衡
  15. mm:修复 pmd_special() 回退未识别 huge_zero PMD

1. ARM64 per-CPU 页表优化 this_cpu_*() 操作

系列[RFC PATCH 00/11] Optimize this_cpu_*() ops for non-x86 (ARM64 for this series)作者: Yang Shi版本: RFC v1(11 个 patch)

背景

x86 架构通过 GS 段寄存器可以直接访问 per-CPU 变量,无需关闭抢占,this_cpu_*() 操作非常高效。但在 ARM64 等非 x86 架构上,this_cpu_*() 必须通过 preempt_disable_notrace()/preempt_enable_notrace() 保护临界区——因为 per-CPU 变量的虚拟地址在每个 CPU 上不同:per_cpu(var, cpu) = per_cpu_offset[cpu] + &var。这导致每次 this_cpu_*() 操作都要执行两次不必要的 preempt 计数原子操作。在 AmpereOne 160 核等大规模多核 ARM64 场景下,大量 per-CPU 操作路径(内存统计、memcg、rss 计数器、rmap 等)均受此开销影响。该系列实现了 LSFMM 2026 提案中的方案:为每个 CPU 创建独立的 per-CPU 页表,将 per-CPU 变量映射到相同虚拟地址,从而消除对 preempt 操作的依赖。

解决的问题

  • ARM64 上 this_cpu_*() 操作必须被 preempt_disable_notrace()/preempt_enable_notrace() 包围,高核数场景下原子操作开销显著
  • 大量 mm 热路径(memcg 统计、rss 计数、rmap 遍历)均受此影响,每次 per-CPU 操作叠加两次 preempt 计数操作

如何做

核心思路是为每个 CPU 创建独立的 pgd 页表,在 ARM64 内核虚拟地址空间中划出两个 per-CPU 专用区域:全局 per-CPU 区域(Global Percpu)和本地 per-CPU 区域(Local Percpu),每个区域对齐到 PGDIR_SIZE 边界以最小化页表同步开销。per-CPU 分配器不再从 vmalloc 空间分配,而从专用的 PERCPU_START 区域分配。

关键技术路径:为每个 CPU 创建独立的 pgd 页表,所有 CPU 的 pgd 共享相同页表内容,仅 pgd 层级不同。本地 per-CPU 区域被映射到各 CPU 自己的页表中——每个 CPU 看到的本地 per-CPU 虚拟地址相同,但映射到不同的物理页。引入 __per_cpu_local_off(一个对所有 CPU 都相同的偏移量),配合新宏 local_cpu_ptr() 替换 raw_cpu_ptr() 直接计算 per-CPU 地址,完全移除 preempt_disable_notrace()/preempt_enable_notrace()

#define local_cpu_ptr(ptr)                      \({                                              \    __verify_pcpu_ptr(ptr);                     \    SHIFT_PERCPU_PTR(ptr, __per_cpu_local_off);  \})

页表同步通过 arch_sync_kernel_mappings() 实现:当 CPU0 的 pgd 发生变化时,通过 ARCH_PAGE_TABLE_SYNC_MASK 检测修改级别,将变更同步到所有其他 CPU 的 pgd。本地 per-CPU 区域被排除在同步之外,因为各 CPU 映射到不同物理页。

收益

测试环境:AmpereOne 160 核 ARM64 服务器,baseline 为 v7.1-rc1 内核。

测试场景
配置
改善幅度
Kernel Build
make -j160
,Fedora 默认配置,memcg 内
sys time 13%-18% 改善,wall time 3%-7% 改善
stress-ng vm ops
160 进程,128M 内存,1 亿次操作
8.5%
 改善
stress-ng mmapfork
160 进程,128M 内存,500 次操作
15%
 改善

回归:创建 10K memcg 时多消耗 2112K 虚拟内存。已知限制包括 KPTI 兼容性(需额外处理 trampoline 页表切换)和共享 TLB 的 SMT 机器不适用。


2. KASAN HW Tags 跳过栈和页表标记优化

系列[PATCH v4 0/3] kasan: hw_tags: Disable tagging for stack and page-tables作者: Muhammad Usama Anjum, Dev Jain版本: v4(3 个 patch)

背景

在 KASAN HW Tags(基于硬件内存标记扩展,MTE)模式下,内核栈和页表始终通过 match-all tag(KASAN_TAG_KERNEL)指针访问,硬件 MTE 完全不会对这些访问做 tag 检查。然而,当前分配栈和页表时,KASAN 仍会为每个 4K 页面执行 256 次 tag 设置指令(STG/STGP 或等效),并在释放时设置 invalid tag 进行 poisoning。这些 tag 操作完全不产生任何安全收益——因为 match-all tag 让硬件忽略了所有 tag 不匹配——却在高频场景(fork、多线程、缺页处理)中带来可观的指令开销。

解决的问题

  • 内核栈的每页 KASAN tag 设置(poisoning/unpoisoning)全部是无效工作:栈指针携带 match-all tag,硬件永远不会检查
  • 页表分配时的 KASAN tag 操作同样无效:页表始终通过 linear mapping 使用 match-all tag 访问
  • 大量 fork 操作(栈分配/释放)和页表操作(缺页处理、内存映射)受到不必要的 tag 操作开销影响

如何做

该方案复用 __GFP_SKIP_KASAN 标志,将其语义从常规页面分配器扩展到三类关键分配路径。整体设计遵循"按实际安全检查需求标记"的原则:对始终通过 match-all tag 访问的对象(栈、页表)跳过 tag 设置,但保留 page.flags 中的 KASAN_TAG_KERNEL 标记——这意味着硬件和内核代码仍认为该页面有效(match-all 指针可正常访问),而非 match-all tag 的访问仍然会触发 MTE fault,安全检测覆盖率完全不变

三类扩展路径分别是:

  • vmalloc 层:在 __vmalloc_node_range_noprof() 中检测 kasan_hw_tags_enabled() && (gfp_mask & __GFP_SKIP_KASAN),成立时跳过页保护位修改(不设置 KASAN_VMALLOC_PROT_NORMAL),且不调用 kasan_unpoison_vmalloc(),页面保持 poison tag
  • 内核栈:为 THREADINFO_GFP 和 GFP_VMAP_STACK 添加 __GFP_SKIP_KASAN,所有栈分配路径(fork 中的 alloc_thread_stack_node()、vmap 栈复用)自动跳过 tag 操作
  • 页表:为 GFP_PGTABLE_KERNEL 添加 __GFP_SKIP_KASAN,覆盖所有通过页面分配器分配的页表页(PTE、PMD、PUD、PGD 级别)

收益

测试配置:2000 次迭代,每次 fork 子进程并创建 N 个线程。

测试场景
优化前
优化后
改善幅度
Thread benchmark(2000 线程)
2.575 s
2.229 s
13.4%
 更快
Pgtable benchmark(2048 MB, 2000 次 fork)
19.08 s
17.62 s
7.6%
 更快

所有场景下 KASAN 安全覆盖率完全不变,仅移除了对 match-all 指针访问对象进行 tag 设置的无效工作。SLUB 支持的页表分配暂未覆盖(使用不广泛,留待后续)。


3. 移除 READ_ONLY_THP_FOR_FS 并支持可写文件 THP

系列[PATCH v5 00/14] Remove CONFIG_READ_ONLY_THP_FOR_FS and enable file THP for writable files作者: Zi Yan版本: v5(14 个 patch)

背景

CONFIG_READ_ONLY_THP_FOR_FS 是历史上为了解决文件透明大页(file THP)与写入冲突而引入的 Kconfig 选项。该机制要求文件必须以只读模式打开才能创建 file THP;一旦文件以写模式打开,内核强制调用 truncate_inode_partial_folio() 将已有 THP 分裂成 order-0 页面。随着 ext4、xfs、btrfs 等文件系统已经支持 large folio(大 folio),文件 THP 的创建条件应该由文件系统 runtime 能力(是否支持 PMD_ORDER 级别大 folio)决定,而非由一个粗粒度 Kconfig 开关控制。

解决的问题

  • CONFIG_READ_ONLY_THP_FOR_FS 造成不必要的 Kconfig 碎片化和代码路径分支
  • 可写文件的 pagecache folio 无法被 khugepaged 和 MADV_COLLAPSE collapse 成 THP
  • struct address_space 中的 nr_thps 计数器仅用于 "fd 变可写时触发提前分裂" 逻辑,造成不必要的内存和代码占用

如何做

核心改造是将文件 THP 的支持判断从 Kconfig 编译期决定转变为运行时文件系统能力查询。

安全基座:新增 mapping_pmd_folio_support() 辅助函数,检查文件系统的 mapping_max_folio_order() 是否达到 PMD_ORDER。在 collapse_file() 中以该运行时检查替代 CONFIG_READ_ONLY_THP_FOR_FS 编译期检查。同时引入 dirty-after-unmap 检查:在 try_to_unmap() 后对 to-be-collapsed folio 检查是否变脏——若变脏则跳过该 folio。这是实现可写文件 THP 的关键安全机制,因为之前依赖 inode->i_writecount 和 mapping->nr_thps 在 fd 变为可写前提前分裂的策略不再需要。

能力打通:从 file_thp_enabled() 和 hugepage_enabled() 中移除 CONFIG_READ_ONLY_THP_FOR_FS 检查,统一为基于 mapping_pmd_folio_support() 的判断。随后移除 Kconfig 选项本身。

废旧机制清理:移除 filemap_nr_thps_inc()/filemap_nr_thps_dec() 函数及所有调用点,从 struct address_space 中删除 nr_thps 字段。这些仅用于 "fd 变为可写时触发 drop all read-only THPs" 的逻辑。

可写文件 THP 收尾:从 file_thp_enabled() 中移除 inode_is_open_for_write() 检查。collapse_file() 中的 filemap_flush() 现在只对只读文件执行——对可写文件,要求用户态在 collapse 前显式刷脏,或使用 MADV_COLLAPSE(其 retry 路径自动处理 flush),避免 khugepaged 触发无条件系统级 writeback。

改造后的能力矩阵:

场景
PF
MADV_COLLAPSE
khugepaged
large folio FS(只读 fd)
Y
Y
Y
large folio FS(读写 fd)
Y
Y
Y(仅 clean folio)
不支持 large folio FS
N
N
N

收益

作者未提供性能数据。从代码逻辑推断的预期收益:

  • 所有支持 PMD-order large folio 的文件系统默认受益于 file THP,无需额外 Kconfig
  • 可写文件也能利用 THP 减少 TLB miss、提升文件 pagecache 访问性能
  • struct address_space 减少一个 atomic_t nr_thps 字段,大量 inode 场景下节省可观的 slab 内存

4. per-VMA 锁全配置可用化

系列[PATCH 0/6] mm: Make per-VMA locks available in all builds作者: Dave Hansen版本: RFC v1(6 个 patch)

背景

per-VMA lock(虚拟内存区域锁)自引入以来已稳定运行数年,通过 RCU + refcount 机制实现对单个 VMA 的细粒度读锁,有效缓解了 mmap_lock 在多线程工作负载下的竞争。但其可用性受限于 ARCH_SUPPORTS_PER_VMA_LOCK Kconfig,仅支持特定架构(x86、ARM64、PowerPC、RISC-V 等)且要求 SMP && MMU。这导致通用代码如果要使用 per-VMA lock,必须同时准备 mmap_lock 回退路径,大幅增加代码复杂度。作者在开发 x86 shadow stack(影子栈)代码时遇到递归锁定问题,想用 per-VMA lock 完全替代 mmap_lock,但发现它并非在所有配置下可用。

解决的问题

如何做

核心改造是移除所有架构的 select ARCH_SUPPORTS_PER_VMA_LOCK 并删除 CONFIG_PER_VMA_LOCK Kconfig,使 per-VMA lock 的底层原语(RCU、maple tree、refcount)在所有配置下无条件可用。vm_area_struct 和 mm_struct 中的 per-VMA lock 字段(vm_lockvm_lock_seqmm_lock_seq 等)始终存在。

同时引入全新 API lock_vma_under_rcu_wait()。这是一个重要的语义升级:当 per-VMA lock 快速路径(RCU 查找)遇到 writer 时,不再立即返回 NULL,而是通过 mmap_read_lock() 等待 writer 完成后重试(goto retry)。调用方不再需要回退路径——该 API 在缺页上下文中安全,因为它获取 mmap_lock 仅是为了等待 writer 完成,立即释放,从不持有锁,不产生递归锁定问题:

struct vm_area_struct *lock_vma_under_rcu_wait(struct mm_struct *mm,unsignedlong address){structvm_area_struct *vma;retry:    vma = lock_vma_under_rcu(mm, address);if (vma)return vma;  // 快速路径成功// 慢路径:等待 writer 完成后重试    mmap_read_lock(mm);    vma = vma_lookup(mm, address);    mmap_read_unlock(mm);if (!vma)returnNULL;goto retry;}

应用示范:binder_alloc_free_page() 移除 mmap_read_trylock() 回退路径,shstk_pop_sigframe() 的复杂 VMA 检测循环被简化为单次 lock_vma_under_rcu_wait() 调用。

收益

作者未提供性能数据(系列处于 RFC 早期阶段)。从代码逻辑推断的预期收益:

维度
效果
条件编译
完全移除 CONFIG_PER_VMA_LOCK#ifdef 分支,消除一类编译配置组合
架构覆盖
立即扩展到所有架构(包括 !MMU!SMP),无需逐个架构维护
新 API
lock_vma_under_rcu_wait()
 使通用代码可直接使用 per-VMA lock 而无需考虑回退

5. KHO:启动时大页分配与 KHO 良好协作

系列[PATCH 00/12] kho: make boot time huge page allocation work nicely with KHO作者: Pratyush Yadav版本: v1(12 个 patch)

背景

KHO(Kexec HandOver)是内核热升级(live update)机制的基础设施,允许当前内核将状态序列化传递给下一个内核。KHO 使用 scratch space(临时内存空间)为下一内核的早期启动提供内存;scratch 大小由当前内核的内存占用(RSRV_KERN 标记)乘以缩放系数决定。Gigantic huge page(通常 1 GiB 大页)通过 memblock_alloc_*() 在启动时分配,标记为 RSRV_KERN。在 hypervisor 场景中,将大量系统内存专用于 gigantic huge page(供 VM 使用)是常见做法。此外,即将到来的 hugetlb preservation 系列需要支持大页的 KHO 保留。

解决的问题

  • Scratch 大小膨胀:大页分配计入 RSRV_KERN,导致 KHO scratch size 计算膨胀。当大页占用超过系统内存的 50% 时(hypervisor 典型配置),scratch 分配因超过可用内存而失败,KHO 完全不可用
  • 大页无法被 KHO 保留:scratch 内存不能包含 preserved memory(保留内存),若大页从 scratch 分配则无法被保留,违反 scratch 设计假设

如何做

方案的核心思路是引入 extended scratch areas(扩展临时空间):在 KHO 启动时遍历 preserved memory radix tree(保留内存基数树)找出空闲内存区间,标记为扩展 scratch,供大页等用户内存分配使用。

整体分三个层次实现:

Radix Tree API 通用化:将 KHO radix tree API 从与 memory preservation 紧耦合中解耦为通用数据结构——kho_radix_add_page()/del_page() 重命名为 kho_radix_add_key()/del_key() 直接接收 key;引入 struct kho_in 存储 radix tree;walk 回调抽象为 struct kho_radix_walk_cb;支持 early-boot 使用和从物理地址初始化。

Extended Scratch 发现机制:新增 MEMBLOCK_KHO_SCRATCH_EXT 标志区别于原始 scratch。kho_extend_scratch() 以 1 GiB(KHO_EXT_SHIFT = 30)为粒度遍历 preserved memory radix tree,将未占用区间聚合为 1 GiB 块后标记为 extended scratch——聚合是为了避免大量细碎 key 导致 memblock.memory 性能退化。

大页分配与 scratch 解耦:引入 memblock_alloc_nid_user()。在 KHO scratch-only 阶段,仅从 extended scratch 满足用户内存分配,不使用核心 scratch。分配完成后调用 memblock_reserved_clear_kern() 清除 RSRV_KERN 标志,使大页不再计入 scratch 大小计算。

收益

测试环境:x86_64 qemu,64G 内存,50 个 1G 大页。

测试场景
Extended scratch 发现耗时
回收可用内存
两个 1M memfd
88 us
~62 GiB
两个 1G memfd(~500K 个 4K 页 preserved)
21,769 us(~22 ms)
57 GiB

最坏情况下 extended scratch 发现所需额外内存约为 6 个页面(KHO_TREE_MAX_DEPTH == 6),可覆盖 32 TiB 物理内存。方案使 KHO 在配备大量 gigantic huge page 的系统上可正常工作,同时为后续 hugetlb preservation 系列打下基础。


6. Deferred Inode Reclaim:卸载复杂 inode 回收到工作队列

系列[PATCH RFC 0/4] fs: Deferred inode reclaim作者: Jan Kara版本: RFC v1(4 个 patch)

背景

Linux 内核在内存回收(reclaim)路径中释放 inode 时,某些文件系统的 inode 回收操作非常复杂——需要启动事务(transaction)、读取块位图(block bitmap)、进行 IO 操作。这导致文件系统在 kswapd 或 direct reclaim 上下文中必须发起 GFP_NOFAIL 分配。GFP_NOFAIL 在回收路径中高度危险,因为无法保证前向进展(forward progress),可能触发 MM 子系统的警告甚至死锁。ext4 的典型调用链为 prune_dcache_sb() → shrink_dentry_list() → iput() → sync_lazytime() → __filemap_get_folio_mpol()。此外,有脏时间戳(dirty timestamp,I_DIRTY_TIME)的 inode 不会被插入 LRU 链表,脏时间戳默认 12 小时才过期,导致这些 inode 长时间脱离 LRU 老化。

解决的问题

  • 从回收路径中消除 GFP_NOFAIL 分配,避免 MM 子系统警告和潜在死锁
  • 脏时间戳 inode 长期脱离 LRU 老化,阻碍内存回收
  • 复杂 inode 回收阻塞 kswapd/direct reclaim,影响全局内存回收效率

如何做

核心思路是引入基于 workqueue(工作队列)的异步回收机制:将复杂的 inode 回收从回收路径卸载到后台工作队列执行,同时建立 EMA 节流(throttling)机制保持系统反压

首先将 iput() 中的 sync_lazytime()(同步脏时间戳回写)替换为新的 queue_dirtytime_writeback()。新函数不立即 IO,而是将 inode 移到 b_dirty_time 链表头部并篡改时间戳使其在下次周期性回写时被自然写出,从而消除回收路径中的 IO 触发。

随后引入 deferred reclaim 基础设施:新增 I_DEFER_RECLAIM 状态标志;在 inode_lru_isolate() 中将标记的 inode 分到 deferred 链表;prune_icache_sb() 将 deferred 链表通过 per-super_block 的 struct inode_deferred_reclaim(含 work_struct 和 spinlock)提交给 system_dfl_wq 异步回收。文件系统通过 mark_inode_reclaim_deferred() 标记 inode。

节流机制保证系统反压不会失控:当 deferred 链表长度超过 INODE_DEFERRED_RECLAIM_LIMIT(8192)时,throttle_inode_deferred_reclaim() 根据平均 inode 回收耗时(EMA,指数移动平均,权重 1/64)按比例阻塞创建 I_DEFER_RECLAIM inode 的任务,延迟最多为平均回收时间的 4 倍。

最后在 ext4 中接入:当 inode 在 ext4_mb_regular_allocator() 中有预分配块(需要加载块位图并运行事务才能释放)时,调用 mark_inode_reclaim_deferred()

收益

作者未提供性能数据。该系列仅经极轻量测试。预期收益:消除回收路径中 GFP_NOFAIL 分配,避免 MM 子系统警告和死锁;ext4 等文件系统无需在回收路径执行事务和 IO。


7. process_mrelease 引入 PROCESS_MRELEASE_REAP_KILL 标志

系列[PATCH v2] mm: process_mrelease: introduce PROCESS_MRELEASE_REAP_KILL flag作者: Minchan Kim版本: v2(1 个 patch)

背景

process_mrelease() 是 Android LMKD(Low Memory Killer Daemon)使用的关键系统调用,用于快速回收被杀进程的内存。当前设计需要用户空间先发 SIGKILL,再调用 process_mrelease()。两步之间存在调度竞争窗口:目标进程收到 SIGKILL 后可能立即进入退出路径(do_exit → exit_mm),一旦清除 task->mm,后续的 process_mrelease() 将因找不到 mm 而返回 -ESRCH。而此时实际的 exit_mmap 被推迟到 mm 引用计数归零——"读取 /proc/<pid>/cmdline 或其他远程 VM 访问经常无限期推迟此过程"(作者原文)。

解决的问题

  • 竞争窗口导致 process_mrelease() 返回 -ESRCH,内存回收延迟
  • Android LMKD 场景下 "forcing the system to unnecessarily kill additional innocent background apps before the memory from the first victim is recovered"(在第一个被杀进程的内存被回收前被迫杀更多无辜后台应用)

如何做

引入 PROCESS_MRELEASE_REAP_KILL UAPI 标志((1 << 0)),将 SIGKILL 发送和内存回收集成为一个原子操作。在发送 SIGKILL 之前通过 mmgrab() 持有 mm 引用(防止目标进程立即清除 mm),回收逻辑简化为 reap = reap_kill || task_will_free_mem(p)。对于 MMF_MULTIPROCESS 共享 mm 的进程直接返回 -EINVAL,防止不安全地回收共享内存。

与 OOM killer(内存不足杀手)的关键差异在于:process_mrelease() 由用户空间策略驱动,不强制在所有代价下回收成功,如果 kill_pid() 失败则回退跳过回收。

收益

作者未提供 benchmark 数据。功能收益:消除 kill+reap 竞争窗口,一次系统调用完成回收,避免因延迟回收导致不必要的额外杀进程。Suren Baghdasaryan 的 Reviewed-by 表明该设计获得了 Android 内存管理团队的认可。


8. DAMON_RECLAIM/LRU_SORT 默认监控全部 System RAM

系列[PATCH 0/7] mm/damon/reclaim,lru_sort: monitor all system rams by default作者: SeongJae Park版本: v1(7 个 patch)

背景

DAMON_RECLAIM 和 DAMON_LRU_SORT 默认将系统中最大的 System RAM 资源设置为监控目标。初衷是最小化监控非 System RAM 区域的开销。"the current design trades ease of setup for lower overhead"(当前设计以使用便利性换取更低开销)——但当系统有多个离散的大容量 System RAM 时(如 NUMA 系统各 500 GiB),默认只监控最大的一段,其余被忽略。用户必须在不同类型系统上手动设置 monitor_region_start/monitor_region_end

解决的问题

  • 多段 System RAM 系统上监控覆盖不全,NUMA 节点存在监控盲区
  • 用户需手动配置,增加使用复杂度和出错概率
  • 原有 trade-off 不再合理——DAMON 的采样型检测和自适应区域调整机制使额外开销可忽略不计

如何做

新增核心函数 damon_set_region_system_rams_default(),遍历 walk_system_ram_res() 获取所有 System RAM 资源的起止范围(第一个 start 到最后一个 end),覆盖全部物理内存段。DAMON_RECLAIM、DAMON_LRU_SORT 和 DAMON_STAT 三个调用方统一切换至新函数,删除旧的 damon_set_region_biggest_system_ram_default() 及其辅助函数。总体改动:+50 行,-88 行,净减少 38 行

收益

作者未提供 benchmark 数据。预期收益:用户无需手动配置即可覆盖全部 System RAM,消除 NUMA 系统上的监控盲区;代码库净减少 38 行。作者判断监控额外区域的性能开销 "should be negligible in most setups"(在大多数配置中应可忽略不计)。


9. memcontrol:修复 isolated CPU 上 FLUSHING_CACHED_CHARGE 永久卡死

系列[PATCH] mm/memcontrol: Avoid stuck FLUSHING_CACHED_CHARGE on isolated CPU作者: Hui Zhu版本: v1(1 个 patch)

背景

memcg(内存控制组)的 per-CPU stock 机制缓存小额 charge/uncharge,减少全局锁竞争。drain_all_stock() 遍历所有 CPU,在排程 drain work 前设置 FLUSHING_CACHED_CHARGE 标志防止重复排程。目标 CPU 通过 queue_work_on() 异步执行 drain 并清除该标志。

解决的问题

当目标 CPU 处于 isolated(隔离)状态(cpu_is_isolated() == true,由 cpuset CPU partition 设置)时,schedule_drain_work() 中 queue_work_on() 被静默跳过——但 FLUSHING_CACHED_CHARGE 已被置位且永远不会被清除。此后每个 drain_all_stock() 调用检查到该标志位后跳过此 stock,导致 per-CPU stock 被永久钉住("effectively pinned until something else on that CPU runs drain_local_*_stock() and clears the bit -- which on a long-isolated CPU may never happen")。

如何做

最小化修复:修改 schedule_drain_work() 增加 unsigned long *flags 参数。当 cpu_is_isolated(cpu) 为 true 时,调用 clear_bit(FLUSHING_CACHED_CHARGE, flags) 清除标志位(在 RCU 保护区外执行)。缓存 charge 保留在原地,将在 CPU 离开隔离状态后由其自身释放,或当隔离 CPU 自身调用 drain_all_stock() 时(cpu == curcpu 分支)完成 drain。涉及 mm/memcontrol.c,+22 行,-6 行。

收益

Fixes:2d05068610a3 ("memcg: Prepare to protect against concurrent isolated cpuset change")

修复了标志位卡死导致后续 drain 全部永久跳过的逻辑缺陷。修复后下次 drain_all_stock() 可正常重试该 stock。


10. mm/vmscan:修复 MGLRU 中延迟的 flusher 唤醒

系列[PATCH] mm/vmscan: fix delayed flusher wakeup in MGLRU作者: Vineet Agarwal版本: v1(1 个 patch)

背景

MGLRU(Multi-Gen LRU)在页面回收过程中,遇到大量脏文件页(dirty file folios)无法直接回收时,需唤醒后台 flusher 线程将脏页写回磁盘。Classic LRU 回收路径在每次 shrink_folio_list() 返回后立即用 per-batch 的局部统计值判断是否唤醒 flusher。而 MGLRU 将此判断推迟到 try_to_shrink_lruvec() 中,使用跨多轮 evict_folios() 累积的全局计数器。

解决的问题

当较早回收批次只隔离了脏文件页(dirty file folios),而较晚批次隔离了干净文件页(clean file folios)时,累积计数器失去同步。例如 batch 1 中 file_taken=100, unqueued_dirty=100;batch 2 中 file_taken+=60, unqueued_dirty+=0——最终比较变为 100 != 160,flusher 唤醒被错误跳过。实际效应:回收因脏页写回不及时而阻塞,可能触发不必要的 OOM,尤其在 cgroup v1 场景下。

如何做

将 flusher 唤醒逻辑从 try_to_shrink_lruvec() 移到 evict_folios() 内部,使用 per-batch 的局部变量 file_takenscan_folios() 将隔离的文件页数量写入调用者传入的 unsigned long *file_taken 指针;isolate_folios() 透传该指针;evict_folios() 在调用 shrink_folio_list() 后立即用当前批次的局部 file_taken 比对 stat.nr_unqueued_dirty,条件满足即唤醒 flusher 并执行写回节流。最后将 file_taken 追加到累积值中。

收益

Fixes:1bc542c6a0d14 ("mm/vmscan: wake up flushers conditionally to avoid cgroup OOM")

使 MGLRU 的脏页回收行为与 classic LRU 完全一致,消除了 flusher 唤醒被错误跳过的窗口。对于高脏页率的文件型工作负载(如数据库、文件服务器),可避免因写回不及时导致的回收停顿和潜在 OOM 触发。


11. mm/khugepaged:MADV_COLLAPSE 对 SCAN_PAGE_HAS_PRIVATE 返回 -EAGAIN

系列[PATCH] mm/khugepaged: return -EAGAIN for SCAN_PAGE_HAS_PRIVATE in MADV_COLLAPSE作者: Vineet Agarwal版本: v1(1 个 patch)

背景

MADV_COLLAPSE 是用户空间主动触发透明大页(THP)合并的 madvise 操作,其返回值遵循明确语义约定:临时性资源约束映射为 -EAGAIN(提示可重试),目标范围永久不可折叠的特性映射为 -EINVALcollapse_file() 在折叠文件映射 THP 时调用 filemap_release_folio() 释放 folio 的私有数据(private data),失败时返回 SCAN_PAGE_HAS_PRIVATE,当前在 madvise_collapse_errno() 中走 default 分支映射为 -EINVAL

解决的问题

filemap_release_folio() 失败通常反映的是临时性的 folio 状态——ext4 上仍有脏日志数据、btrfs 上 extent state 尚未释放、NFS 上回收文件系统私有状态失败——而非永久不可折叠的范围。返回 -EINVAL 误导用户空间以为该地址范围根本上不可折叠,而实际上写回/日志提交完成后重试即可成功。这与 SCAN_PAGE_DIRTY_OR_WRITEBACK 等临时性失败返回 -EAGAIN 的处理方式不一致。

如何做

在 madvise_collapse_errno() 的 switch 语句中,将 SCAN_PAGE_HAS_PRIVATE 从 default 分支(映射为 -EINVAL)移至已有 -EAGAIN 返回组,与 SCAN_PAGE_LRUSCAN_PAGE_DIRTY_OR_WRITEBACK 同等对待。一行改动。

收益

纠正了 MADV_COLLAPSE 的错误返回码,使用户空间程序在 filemap_release_folio() 因临时状态失败时正确重试。对 ext4/btrfs/NFS 上使用 MADV_COLLAPSE 的应用(如虚拟机、数据库)有直接收益——原本因 -EINVAL 放弃折叠的地址范围可在写回/日志提交后通过重试成功折叠,提高 THP 合并成功率。


12. mm/madvise:在 MADV_DONTNEED 中保留 uprobe 断点

系列[PATCH] mm/madvise: preserve uprobe breakpoints across MADV_DONTNEED作者: Darko Tominac版本: v1(1 个 patch)

背景

uprobes(用户空间探针)通过在文件映射的目标地址处插入软件断点指令(swbp)实现函数级别 instrumentation,广泛用于 eBPF 安全监控和性能追踪。uprobe_mmap() 仅在 VMA(虚拟内存区域)创建时被调用以安装断点,不会在单个页面 fault-in 时重新插桩。MADV_DONTNEED 允许用户空间提示内核丢弃指定文件映射范围内的页面内容——当这些页面再次被访问时从后备文件重新读取,但断点已永久丢失。

解决的问题

当文件映射页面包含 uprobe 断点指令时,MADV_DONTNEED 会丢弃这些页面,断点永久丢失,探针静默停止触发且无任何错误提示。复现路径:用户空间内存回收子系统对文件映射代码段调用 madvise(MADV_DONTNEED) → 包含 uprobe 断点的页面被丢弃 → eBPF 安全/追踪工具的 uprobe 在首次回收操作后数秒内停止工作。唯一的恢复方式是注销并重新注册受影响的 uprobes。

如何做

方案采用 "跳跃式 zapping" 策略,保护含 uprobe 断点的页面不被丢弃。

新增三个 uprobes 子系统 API:any_uprobes_registered() 快速全局检查是否有任何 uprobe 注册(!no_uprobe_events());vma_has_uprobes() 检查指定 VMA 范围内是否存在 uprobe(利用全局 rbtree 的 find_node_in_range());vma_first_uprobe_addr() 返回 VMA 区间内第一个 uprobe 的页对齐地址(rbtree 查找后向左遍历取最小 offset)。所有三个函数在 CONFIG_UPROBES=n 时有空的内联实现,零开销

在 madvise_dontneed_free() 中的跳过逻辑:快速路径——若无 uprobe 注册(likely(!any_uprobes_registered()))、或 VMA 非文件映射、或范围内无 uprobe——直接执行完整的 MADV_DONTNEED。慢速路径——用 vma_first_uprobe_addr() 从 rbtree 跳至每个 uprobe 页地址,zap 各 uprobe 页之前的干净区间然后跳过该页,循环覆盖整个 range,复杂度 O(M * log N)(M 为区间内 uprobe 数,N 为系统总 uprobe 数)。

收益

作者未提供性能数据。该修复解决了 MADV_DONTNEED 与 uprobes 之间的静默数据损坏问题——断点不再被意外清除。快速路径零额外开销,慢速路径利用 rbtree 跳跃避免逐页线性扫描。对使用 eBPF uprobe 进行安全监控、性能剖析或函数追踪的生产系统具有重要正确性保障。


13. x86/mm:修复 PMD 大小 vmemmap 页的释放内存泄漏

系列[PATCH v2] x86/mm: fix freeing of PMD-sized vmemmap pages作者: David Hildenbrand版本: v2(1 个 patch)

背景

commit bf9e4e30f353("x86/mm: use pagetable_free()")将 x86 非启动页表的释放路径统一迁移到 pagetable_free()。但 vmemmap 页面(通过 vmemmap_alloc_block() 分配的普通单页)被错误地纳入该路径。vmemmap 页不是 compound page(复合页)(HugeTLB Vmemmap Optimization 使用 altmap 的例外场景除外)。

解决的问题

  • pagetable_free() 内部调用 __free_pages(page, compound_order(page))。由于 vmemmap 页非 compound page,compound_order() 返回 0,因此在释放 PMD 大小(2 MB)的 vmemmap 页时,只释放了第一页(4 KB),其余 511 页(~2 MB)被泄漏
  • 原 free_pagetable() 中处理 SECTION_INFO 类型——但只有 vmemmap 页面被标记为 SECTION_INFO,页表页面不会有此标记,导致语义混淆
  • 对 vmemmap 页面调用 page_ptdesc() 在语义上错误

Fixes:bf9e4e30f353 ("x86/mm: use pagetable_free()")Cc: stable

复现方式:使用一个带 virtio-mem 设备的简单 VM,反复添加和移除内存。

如何做

将 vmemmap 和页表的释放路径彻底解耦,引入专用函数 free_vmemmap_pages(page, order, altmap)。该函数接收显式的 order 参数而非依赖 compound_order(),正确处理三种场景:altmap 页面调用 vmem_altmap_free();bootmem 保留页面(SECTION_INFO 类型)通过 put_page_bootmem() 逐页释放;普通页面直接 __free_pages(page, order)。同时从 free_pagetable() 中移除 SECTION_INFO 处理,使页表释放语义更精确。

收益

消除了每次释放 PMD 大小 vmemmap 页面时泄漏约 2 MB 的内存泄漏问题。作者通过代码审查发现("Found by code inspection while working on bootmem_info removal"),影响所有使用 PMD 大小 vmemmap 的 x86 系统。


14. mm/memcontrol:修复 get_non_dying_memcg_end() RCU 不平衡

系列[PATCH v3] mm: memcontrol: fix rcu unbalance in get_non_dying_memcg_end()作者: Qi Zheng版本: v3(1 个 patch)

背景

在 cgroup v2 混合模式环境下,memory controller 可在运行时从 cgroup v1 层次结构切换到 v2(hierarchy rebinding)。get_non_dying_memcg_start() 和 get_non_dying_memcg_end() 是一对函数,用于 mod_memcg_state() 和 mod_memcg_lruvec_state() 中以安全方式获取非 dying 状态的 memcg。两者各自独立评估 cgroup_subsys_on_dfl():v2 下不需要 RCU 保护,v1 下需要 rcu_read_lock() 来安全地遍历 memcg 父链(跳过 dying memcg)。

解决的问题

cgroup_subsys_on_dfl() 在运行时动态变化。如果 _start() 调用时 memory controller 在 v2(不获取 RCU 锁),随后发生 rebinding 切换到 v1,_end() 调用时看到 v1 却执行 rcu_read_unlock(),导致锁不平衡,内核产生 WARNING。复现路径为标准缺页处理 do_user_addr_fault → handle_mm_fault → mod_memcg_state / mod_memcg_lruvec_state

Fixes:8285917d6f38 ("mm: memcontrol: prepare for reparenting non-hierarchical stats")

如何做

将 "RCU 是否已持有" 的状态从隐式(依赖两次独立调用 cgroup_subsys_on_dfl())改为显式追踪。get_non_dying_memcg_start() 新增 bool *rcu_locked 参数,持有 RCU 锁时设为 true,否则 falseget_non_dying_memcg_end() 改为接收 bool rcu_locked 参数,不再重复调用 cgroup_subsys_on_dfl()。调用点(mod_memcg_state()mod_memcg_lruvec_state())通过栈上局部布尔变量传递锁状态,保证 RCU 锁的获取和释放严格配对。

收益

消除由 cgroup hierarchy rebinding 触发的 RCU 锁不平衡 WARNING,避免污染内核锁定调试基础设施。rcu_locked 是栈上局部变量,额外开销可忽略不计。已获 Shakeel Butt Acked-by 和 Muchun Song Reviewed-by。


15. mm:修复 pmd_special() 回退未识别 huge_zero PMD

系列[PATCH hotfix] mm: fix pmd_special() fallback to observe huge_zero作者: Hugh Dickins版本: v1(1 个 patch)

背景

在 x86 32 位且启用 THP(透明大页)的配置下,zap_huge_pmd() 用于清除 PMD 级别的大页映射。该函数调用 vm_normal_folio_pmd() → __vm_normal_page() 时使用 pmd_special() 判断 PMD 映射是否为 special 映射。零页和大零页(huge_zero page)被视为 special 映射——但 PMD 级别的 special 位由 CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 保护,该配置项在任何 32 位架构上均未启用。因此 pmd_special() 的回退实现简单返回 false

解决的问题

  • huge_zero PMD 被误判为 normal 映射,穿透到 __vm_normal_page() 中的 VM_WARN_ON_ONCE(is_huge_zero_pfn(pfn)) 断言,触发 WARNING
  • __vm_normal_page() 为 huge_zero PMD 返回非 NULL 的 struct page 指针,zap_huge_pmd() 调用者将其误认为普通 folio 而调整 RSS 计数器,触发 "Bad rss-counter state" BUG
  • 后续 reclaim 路径调用 shrink_huge_zero_folio_scan() 时遇到已被错误处理的 folio,触发 "Bad page state" BUG

Fixes:d80a9cb1a64a ("mm/huge_memory: add and use normal_or_softleaf_folio_pmd()")

复现路径:在 x86 32 位 + THP 配置下,分配 huge_zero PMD → 触发 zap_huge_pmd() → pmd_special() 返回 false → __vm_normal_page() WARNING → RSS 误差累积 → reclaim 路径 Bad page state BUG。

如何做

单行改动,位于 include/linux/mm.hpmd_special() 的回退实现从 return false 改为 return is_huge_zero_pmd(pmd)is_huge_zero_pmd() 仅检查 PMD 的 PFN 是否等于 huge_zero_pfn,是轻量级操作。不引入新 Kconfig(如 CONFIG_ARCH_HAS_PMD_SPECIAL),采取最务实的方案。

收益

修复了 x86 32 位 + THP 配置下的三个级联问题(WARNING + Bad rss-counter BUG + Bad page state BUG),恢复 zap_huge_pmd() 路径的正确性。额外开销为零——is_huge_zero_pmd() 仅在 CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 未启用时被调用,不影响支持 PMD PFNMAP 的架构。


总结

性能优化

#
系列
量化数据
1
ARM64 per-CPU 页表优化
 [RFC v1, 11p]
内核构建 sys time 13%-18% 改善,wall time **3%-7%**;stress-ng mmapfork 15% 改善
2
KASAN HW Tags 跳过栈和页表
 [v4, 3p]
Thread benchmark 13.4% 更快;Pgtable benchmark 7.6% 更快。安全覆盖率不变
3
移除 READ_ONLY_THP_FOR_FS
 [v5, 14p]
可写文件可用 THP;struct address_space 减少 nr_thps 字段;配置简化
4
per-VMA 锁全配置可用
 [RFC v1, 6p]
净减 144 行,完全移除 CONFIG_PER_VMA_LOCK;新 API 无需回退路径
5
KHO 启动大页与 KHO 协作
 [v1, 12p]
Extended scratch 发现耗时 88us~22ms;回收 57~62G 可用内存;6 页覆盖 32 TiB

新机制 / 新接口

#
系列
要点
6
Deferred Inode Reclaim
 [RFC v1, 4p]
将复杂 inode 回收从 reclaim 路径卸载到 workqueue;I_DEFER_RECLAIM + EMA 节流 + tracepoint
7
PROCESS_MRELEASE_REAP_KILL
 [v2, 1p]
新增 UAPI 标志集成了 SIGKILL+reap 为原子操作;消除 Android LMKD 竞争窗口
8
DAMON 默认监控全部 System RAM
 [v1, 7p]
消除 NUMA 监控盲区;净减 38 行代码;零预期性能退化

Bug Fix

#
系列
影响
9
FLUSHING_CACHED_CHARGE 卡死
 [v1]
修复 isolated CPU 上 memcg per-CPU stock 标志永久置位。Fixes: 2d05068610a3
10
MGLRU flusher 延迟唤醒
 [v1]
修复跨批次累积计数器导致 flusher 跳过,可能触发 OOM。Fixes: 1bc542c6a0d14
11
MADV_COLLAPSE -EAGAIN
 [v1]
SCAN_PAGE_HAS_PRIVATE 从 -EINVAL 改为 -EAGAIN,使临时失败可重试
12
MADV_DONTNEED 保留 uprobe
 [v1]
防止 MADV_DONTNEED 静默清除 uprobe 断点,消除数据损坏
13
vmemmap PMD 释放泄漏
 [v2]
修复每次释放泄漏 ~2 MB 内存。Fixes: bf9e4e30f353,Cc: stable
14
RCU 锁不平衡
 [v3]
修复 cgroup rebinding 导致 rcu_read_unlock() 无配对。Fixes: 8285917d6f38
15
pmd_special huge_zero
 [v1]
修复 x86 32 位 THP 的三级联错误(WARNING + RSS BUG + page state BUG)。Fixes: d80a9cb1a64a

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-04 06:44:06 HTTP/2.0 GET : https://f.mffb.com.cn/a/490285.html
  2. 运行时间 : 0.121170s [ 吞吐率:8.25req/s ] 内存消耗:5,010.38kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=9b4e83e170193e7e884fe45327f1b8ff
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000950s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001511s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000652s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.003433s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001426s ]
  6. SELECT * FROM `set` [ RunTime:0.000571s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001526s ]
  8. SELECT * FROM `article` WHERE `id` = 490285 LIMIT 1 [ RunTime:0.001173s ]
  9. UPDATE `article` SET `lasttime` = 1783118646 WHERE `id` = 490285 [ RunTime:0.011562s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000407s ]
  11. SELECT * FROM `article` WHERE `id` < 490285 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.018629s ]
  12. SELECT * FROM `article` WHERE `id` > 490285 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000726s ]
  13. SELECT * FROM `article` WHERE `id` < 490285 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001428s ]
  14. SELECT * FROM `article` WHERE `id` < 490285 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002258s ]
  15. SELECT * FROM `article` WHERE `id` < 490285 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.002497s ]
0.122719s