Page cache

定义

PageCache 是一个逻辑上的概念,指定是用于缓存disk数据到内存中的内存页。

数据结构

Page cache的核心结构体是**address_space**。

它是连接文件(inode)和内存页面(page)的桥梁 。每个打开的文件都有一个对应的 address_space,它管理该文件在内存中的所有缓存页。

在include/linux/fs.h文件中

cpp 复制代码
// PageCache 的核心数据结构
struct address_space {
    struct inode        *host;     // 所属文件
    struct xarray       i_pages;   // cache page们
    struct rw_semaphore invalidate_lock;
    gfp_t           gfp_mask;
    atomic_t        i_mmap_writable; /* 可写映射计数 */
#ifdef CONFIG_READ_ONLY_THP_FOR_FS
    /* number of thp, only for non-shmem files */
    atomic_t        nr_thps;
#endif
    struct rb_root_cached   i_mmap; /* 私有映射树 */
    struct rw_semaphore i_mmap_rwsem;
    unsigned long       nrpages;    /* 页面总数 */
    pgoff_t         writeback_index;
    const struct address_space_operations *a_ops; /* 操作函数 */
    unsigned long       flags;
    errseq_t        wb_err;
    spinlock_t      private_lock;
    struct list_head    private_list;
    void            *private_data;
} __attribute__((aligned(sizeof(long)))) __randomize_layout;

如何关联起来:

复制代码
一个文件 (inode)
    ↓
一个 address_space
    ↓
管理该文件的所有page cache (通过 i_pages)
cpp 复制代码
struct inode {
    // ...
    struct address_space *i_mapping;  // 文件的主要映射
    struct address_space i_data;      // 文件的地址空间
};
cpp 复制代码
// PageCache 页面在内存中的状态 
struct page { 
    struct address_space *mapping; // 属于哪个 PageCache 
    pgoff_t index; // 在文件中的偏移 
    struct list_head lru; // ← 链接到 LRU 链表 
    // ... 
};
cpp 复制代码
struct task_struct
    ↓ 通过mm_struct
struct mm_struct
    ↓ 通过VMA链表
struct vm_area_struct     // 虚拟内存区域
    ↓ vm_file指向
struct file
    ↓ f_mapping指向
struct address_space      // ← 我们关注的
    ↓ host指向  
struct inode             // 文件inode
    ↓ i_pages指向
struct address_space     // 其实是同一个
    ↓ page_tree包含
struct page              // 物理页面
    ↓ lru指向
LRU 链表管理
    ├── LRU_INACTIVE_FILE 链表
    └── LRU_ACTIVE_FILE 链表

PageCache 页面的生命周期

复制代码
首次访问文件页
    ↓
分配物理页struct page(Buddy System)
    ↓
读入磁盘数据
    ↓
加入 PageCache(address_space)
    ↓
加入 LRU_INACTIVE_FILE
    ↓
再次访问 → 移到 LRU_ACTIVE_FILE
    ↓
内存压力 → 页面回收
    ├── 干净页 → 直接释放
    └── 脏页   → 写回后释放
相关推荐
2401_892070982 天前
【Linux C++ 日志系统实战】LogFile 日志文件管理核心:滚动策略、线程安全与方法全解析
linux·c++·日志系统·日志滚动
lwx9148522 天前
Linux-Shell算术运算
linux·运维·服务器
somi72 天前
ARM-驱动-02-Linux 内核开发环境搭建与编译
linux·运维·arm开发
双份浓缩馥芮白2 天前
【Docker】Linux 迁移 docker 目录(软链接)
linux·docker
黄昏晓x2 天前
Linux ---- UDP和TCP
linux·tcp/ip·udp
路溪非溪2 天前
Linux驱动开发中的常用接口总结(一)
linux·运维·驱动开发
此刻觐神2 天前
IMX6ULL开发板学习-01(Linux文件目录和目录相关命令)
linux·服务器·学习
2401_892070982 天前
【Linux C++ 日志系统实战】高性能文件写入 AppendFile 核心方法解析
linux·c++·日志系统·文件写对象
航Hang*2 天前
第3章:Linux系统安全管理——第2节:部署代理服务
linux·运维·服务器·开发语言·笔记·系统安全
-ONLY-¥2 天前
PostgreSQL运维全攻略:从基础操作到远程配置
linux