Linux+page+cache+里的几个函数的源码分析


page cache 在linux vfs 中是比较重要的一层,其功能就不详细介绍了。主要介绍了几个关键性函数,容易帮助了解page cache里的整体逻辑和流程

先看一下page 的结构体

  1. /* 
  2.  * Each physical page in the system has a struct page associated with 
  3.  * it to keep track of whatever it is we are using the page for at the 
  4.  * moment. Note that we have no way to track which tasks are using 
  5.  * a page. 
  6.  */  
  7. struct page {  
  8.     unsigned long flags;        /* Atomic flags, some possibly 
  9.                      * updated asynchronously */  
  10.     atomic_t _count;        /* Usage count, see below. */  
  11.     atomic_t _mapcount;     /* Count of ptes mapped in mms, 
  12.                      * to show when page is mapped 
  13.                      * & limit reverse map searches. 
  14.                      */  
  15.     union {  
  16.         struct {  
  17.         unsigned long private;      /* Mapping-private opaque data: 
  18.                          * usually used for buffer_heads 
  19.                          * if PagePrivate set; used for 
  20.                          * swp_entry_t if PageSwapCache; 
  21.                          * indicates order in the buddy 
  22.                          * system if PG_buddy is set. 
  23.                          */  
  24.         struct address_space *mapping;  /* If low bit clear, points to 
  25.                          * inode address_space, or NULL. 
  26.                          * If page mapped as anonymous 
  27.                          * memory, low bit is set, and 
  28.                          * it points to anon_vma object: 
  29.                          * see PAGE_MAPPING_ANON below. 
  30.                          */  
  31.         };  
  32. #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS   
  33.         spinlock_t ptl;  
  34. #endif   
  35.     };  
  36.     pgoff_t index;          /* Our offset within mapping. */  
  37.     struct list_head lru;       /* Pageout list, eg. active_list 
  38.                      * protected by zone->lru_lock ! 
  39.                      */  
  40.     /* 
  41.      * On machines where all RAM is mapped into kernel address space, 
  42.      * we can simply calculate the virtual address. On machines with 
  43.      * highmem some memory is mapped into kernel virtual memory 
  44.      * dynamically, so we need a place to store that address. 
  45.      * Note that this field could be 16 bits on x86 ... ;) 
  46.      * 
  47.      * Architectures with slow multiplication can define 
  48.      * WANT_PAGE_VIRTUAL in asm/page.h 
  49.      */  
  50. #if defined(WANT_PAGE_VIRTUAL)   
  51.     void *virtual;          /* Kernel virtual address (NULL if 
  52.                        not kmapped, ie. highmem) */  
  53. #endif /* WANT_PAGE_VIRTUAL */   
  54. };  

page_cache_get() 主要是调用函数get_page

  1. static inline void get_page(struct page *page)  
  2. {  
  3.     if (unlikely(PageCompound(page)))  
  4.         page = (struct page *)page_private(page);  
  5.     atomic_inc(&page->_count);  
  6. }  

主要page里的计数器+1,表示page引用的reference 次数 

page_cache_release() 的核心函数 put_page_testzero

  1. static inline int put_page_testzero(struct page *page)  
  2. {  
  3.     BUG_ON(atomic_read(&page->_count) == 0);  
  4.     return atomic_dec_and_test(&page->_count);  
  5. }  

显然是page的计数器-1, page的引用被释放 

  • 1
  • 2
  • 下一页

相关内容