项目要在内核做和页高速缓存相类似缓存机制,在写内核代码之前必须先搞清楚页高速缓存源码是什么情况。 之前有一篇博客分析过了页高速缓存的基础,但是远远没有达到动手写代码的基础。这几天端午节假期集中精力,搞懂整个框架 与 在内核中的应用。
其他类别的博客也不会停止更新。
谨以此祭奠逝去的时间。
前言
基于内核版本 4.4.4
- Linux 基数树(radix tree)是将指针与long整数键值相关联的机制,它存储有效率,并且可快速查询,用于指针与整数值的映射(如:IDR机制)、内存管理等。
- IDR(ID Radix)机制是将对象的身份鉴别号整数值ID与对象指针建立关联表,完成从ID与指针之间的相互转换。IDR机制使用radix树状结构作为由id进行索引获取指针的稀疏数组,通过使用位图可以快速分配新的ID,IDR机制避免了使用固定尺寸的数组存放指针。IDR机制的API函数在lib/idr.c中实现,这里不加分析。
基于页高速缓存基础这篇博客我们已经知道:
-
页高速缓存的核心数据结构是 address_space.
-
每个inode表示的文件里面都有一个i_mapping字段。真正的对象就在 i_data字段。
struct address_space *i_mapping;
struct address_space i_data;
- 每个页描述符都包括把页链接到页高速缓存的两个字段mapping和index。
struct page {
/* First double word block */
unsigned long flags; /* Atomic flags, some possibly
* updated asynchronously */
union {
struct address_space *mapping; /* If low bit clear, points to
* inode address_space, or NULL.
* If page mapped as anonymous
* memory, low bit is set, and
* it points to anon_vma object:
* see PAGE_MAPPING_ANON below.
*/
void *s_mem; /* slab first object */
};
/* Second double word */
struct {
union {
pgoff_t index; /* Our offset within mapping. */
void *freelist; /* sl[aou]b first free object */
};
....
....
...
};
- address_space对象字段中, host 指向其所有者的索引对象 inode。 但真正的数据保存在 page_tree 里面。
struct address_space {
struct inode *host; /* owner: inode, block_device 指向拥有该对象的索引节点的指针*/
struct radix_tree_root page_tree; /* radix tree of all pages 表示拥有者页的基数radix tree 的根*/
spinlock_t tree_lock; /* and lock protecting it 保护基树的自旋锁 */
atomic_t i_mmap_writable;/* count VM_SHARED mappings 地址空间中共享内存映射的个数*/
struct rb_root i_mmap; /* tree of private and shared mappings radix优先搜索树的根 */
struct rw_semaphore i_mmap_rwsem; /* protect tree, count, list */
/* Protected by tree_lock together with the radix tree */
unsigned long nrpages; /* number of total pages */
unsigned long nrshadows; /* number of shadow entries */
pgoff_t writeback_index;/* writeback starts here */
const struct address_space_operations *a_ops; /* methods */
unsigned long flags; /* error bits/gfp mask */
spinlock_t private_lock; /* for use by the address_space */
struct list_head private_list; /* ditto */
void *private_data; /* ditto */
}
现在就把重点放在 radix_tree_root这个数据结构:
Radix Tree
linux 内存管理通过radix树管理映射到地址空间上的核心页,该树允许内存管理代码快速查找标识为dirty或