Linux Kernel/页缓存

按文件偏移查找页缓存

页缓存用 XArray 把文件页索引映射到 folio,支持稀疏条目和多页 folio。

v6.12缓存与复用核验 2026-10-08
相关概念

工程问题#

大文件通常只有部分内容驻留内存;读写路径需要按偏移查缓存,还要区分未命中、正在变化的条目及特殊值。

实际实现#

address_space 的 i_pages 是 XArray。filemap_get_entry 使用 xas_load 读取条目,并配合 RCU、引用获取和重试确认对象仍有效。

处理流程#

  1. 把文件偏移换算为页索引
  2. 从 i_pages 读取条目
  3. 获取引用并校验,必要时重试
  4. 返回 folio、特殊条目或未命中,由上层决定后续读取或缺页处理

源码片段#

固定版本 · 原文摘录
mm/filemap.cv6.12 · L1839–L1860
查看原文件
1839	rcu_read_lock();1840repeat:1841	xas_reset(&xas);1842	folio = xas_load(&xas);1843	if (xas_retry(&xas, folio))1844		goto repeat;1845	/*1846	 * A shadow entry of a recently evicted page, or a swap entry from1847	 * shmem/tmpfs.  Return it without attempting to raise page count.1848	 */1849	if (!folio || xa_is_value(folio))1850		goto out;18511852	if (!folio_try_get(folio))1853		goto repeat;18541855	if (unlikely(folio != xas_reload(&xas))) {1856		folio_put(folio);1857		goto repeat;1858	}1859out:1860	rcu_read_unlock();
filemap_get_entry

RCU 临界区内读取 XArray;特殊值直接返回路径处理,普通 folio 必须成功获取引用,并用 xas_reload 确认条目未被替换,否则释放引用后重试。XA_STATE 在本段上方绑定 mapping->i_pages 和页索引。

连续截取查找、引用校验和 RCU 解锁部分;函数的 XA_STATE 声明和最终 return 在相邻上下文。

收益与取舍#

工程分析

带来的收益

  • 为稀疏文件索引按需分配元数据
  • 同一索引支持查找与有序扫描

付出的代价

  • 工程分析:树节点消耗额外内存
  • 无锁读取仍需要引用校验与重试协议

可比较的选择

普通哈希表点查找直接,但有序扫描和多索引范围表示需额外设计。

版本与适用范围#

对应页缓存索引;XArray 不负责页缓存的全部淘汰策略,也不等同于磁盘文件系统索引。

参考来源#

源码、官方文档与原始论文
01
linux · filemap_get_entry

mm/filemap.c · filemap_get_entry

源码v6.12
4 个匹配案例