页高速缓存处理函数

本文详细介绍了Linux内核中页高速缓存的处理函数,包括查找、增加、删除和更新页的操作。重点讲解了find_get_page()、add_to_page_cache()和remove_from_page_cache()函数的工作原理,以及基树的标记如何加速脏页和写回页的查找。此外,还提到了radix_tree_*系列函数在页高速缓存管理中的作用。
摘要由CSDN通过智能技术生成

好了,在了解了页高速缓存相关的数据结构以后,我们来介绍一下基本的页高速缓存处理函数:

 

对页高速缓存操作的基本高级函数有查找、增加和删除页。在以上函数的基础上还有另一个函数确保高速缓存包含指定页的最新版本。

 

1 查找页

 

函数find_get_page()接收的参数为指向address_space对象的指针和偏移量。它获取地址空间的自旋锁,并调用radix_tree_lookup()函数搜索拥有指定偏移量的基树的叶子节点:
struct page * find_get_page(struct address_space *mapping, unsigned long offset)
{
      struct page *page;

      read_lock_irq(&mapping->tree_lock);
      page = radix_tree_lookup(&mapping->page_tree, offset);
      if (page)
            page_cache_get(page);
      read_unlock_irq(&mapping->tree_lock);
      return page;
}


函数radix_tree_lookup根据偏移量值中的位依次从树根开始并向下搜索,如上节所述。如果遇到空指针,函数返回NULL;否则,返回叶子节点的地址,也就是所需要的页描述符指针。如果找到了所需要的页,find_get_page()函数就增加该页的使用计数器,释放自旋锁,并返回该页的地址;否则,函数就释放自旋锁并返回NULL:
void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
{
      void **slot;

      slot = __lookup_slot(root, index);
      return slot != NULL ? *slot : NULL;
}


static inline void **__lookup_slot(struct radix_tree_root *root,
                           unsigned long index)
{
      unsigned int height, shift;
      struct radix_tree_node **slot;

      height = root->height;

      if (index > radix_tree_maxindex(height))
            return NULL;

      if (height == 0 && root->rnode)
            return (void **)&root->rnode;

      shift = (height-1) * RADIX_TREE_MAP_SHIFT;
      slot = &root->rnode;

      while (height > 0) {
            if (*slot == NULL)
                  return NULL;

            slot = (struct radix_tree_node **)
                  ((*slot)->slots +
                        ((index >> shift) & RADIX_TREE_MAP_MASK));
            shift -= RADIX_TREE_MAP_SHIFT;
            height--;
      }

      return (void **)slot;
}


函数find_get_pages()与find_get_page()类似,但它实现在高速缓存中查找一组具有相邻索引的页。它接收的参数是:指向address_space对象的指针、地址空间中相对于搜索起始位置的偏移量、所检索到页的最大数量、指向由该函数赋值的页描述符数组的指针。find_get_pages()依赖radix_tree_gang_lookup()函数实现查找操作,radix_tree_gang_lookup()函数为指针数组赋值并返回找到的页数。尽管由于一些页可能不在页高速缓存中而会出现空缺的页索引,但所返回的页还是递增的索引值。

 

还有另外几个函数实现页高速缓存上的查找操作。例如,find_lock_page()函数与find_get_page()类似,但它增加返回页的使用记数器,并调用lock_page()设置PG_locked标志,从而当函数返回时调用者能够以互斥的方式访问返回的页。随后,如果页已经被加锁,lock_Page()函数就阻塞当前进程。最后,它在PG_locked位置位时调用__wait_on_bit_lock()函数。后面的函数把当前进程置为TASK_UNINTERRUPTIBLE状态,把进程描述符存入等待队列,执行address_space对象的sync_page方法以取消文件所在块设备的请求队列,最后调用schedule()函数来挂起进程,直到把PG_locked标志清0。内核使用unlock_page()函数对页进行解锁,并唤醒在等待队列上睡眠的进程。

 

函数find_trylock_page()与find_lock_page()类似,仅有一点不

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值