Linux缓存机制之页缓存

发表于:2012-2-29 10:24

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:bullbat    来源:51Testing软件测试网采编

分享:

  页面缓存的实现基于基数树,缓存属于内核中性能要求最苛刻的部分之一,而且广泛用于内核的所有子系统,实现也比较简单。举两个例子,其他的暂时不做分析了。

  分配页面用于加入地址空间

  1. /*从伙伴系统中分配页面,页面的标志根据地址空间中的标志进行设置*/  
  2. static inline struct page *page_cache_alloc(struct address_space *x)  
  3. {  
  4.     return __page_cache_alloc(mapping_gfp_mask(x));  
  5. }

  分配完了添加到基数树中

  1. /* 
  2.  * Like add_to_page_cache_locked, but used to add newly allocated pages: 
  3.  * the page is new, so we can just run __set_page_locked() against it. 
  4.  */  
  5. static inline int add_to_page_cache(struct page *page,  
  6.         struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask)  
  7. {  
  8.     int error;  
  9.   
  10.     __set_page_locked(page);  
  11.     /*实际的添加工作*/  
  12.     error = add_to_page_cache_locked(page, mapping, offset, gfp_mask);  
  13.     if (unlikely(error))  
  14.         __clear_page_locked(page);  
  15.     return error;  
  16. }

  1. /** 
  2.  * add_to_page_cache_locked - add a locked page to the pagecache 
  3.  * @page:   page to add 
  4.  * @mapping:    the page's address_space 
  5.  * @offset: page index 
  6.  * @gfp_mask:   page allocation mode 
  7.  * 
  8.  * This function is used to add a page to the pagecache. It must be locked. 
  9.  * This function does not add the page to the LRU.  The caller must do that. 
  10.  */  
  11. int add_to_page_cache_locked(struct page *page, struct address_space *mapping,  
  12.         pgoff_t offset, gfp_t gfp_mask)  
  13. {  
  14.     int error;  
  15.   
  16.     VM_BUG_ON(!PageLocked(page));  
  17.   
  18.     error = mem_cgroup_cache_charge(page, current->mm,  
  19.                     gfp_mask & GFP_RECLAIM_MASK);  
  20.     if (error)  
  21.         goto out;  
  22.     /*树的相关结构申请*/  
  23.     error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);  
  24.     if (error == 0) {  
  25.         page_cache_get(page);/*使用计数加一*/  
  26.         page->mapping = mapping;  
  27.         page->index = offset;  
  28.       
  29.         spin_lock_irq(&mapping->tree_lock);  
  30.         /*实际的插入操作*/  
  31.         error = radix_tree_insert(&mapping->page_tree, offset, page);  
  32.         if (likely(!error)) {  
  33.             mapping->nrpages++;  
  34.             __inc_zone_page_state(page, NR_FILE_PAGES);  
  35.             if (PageSwapBacked(page))  
  36.                 __inc_zone_page_state(page, NR_SHMEM);  
  37.             spin_unlock_irq(&mapping->tree_lock);  
  38.         } else {  
  39.             page->mapping = NULL;  
  40.             spin_unlock_irq(&mapping->tree_lock);  
  41.             mem_cgroup_uncharge_cache_page(page);  
  42.             page_cache_release(page);  
  43.         }  
  44.         radix_tree_preload_end();  
  45.     } else  
  46.         mem_cgroup_uncharge_cache_page(page);  
  47. out:  
  48.     return error;  
  49. }

33/3<123
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号