歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

Linux緩存機制之頁緩存

Linux運用一個功能廣泛的緩沖和緩存框架來提高系統的速度。緩沖和緩存利用一部分系統物理內存,確保最重要、最常使用的塊設備數據在操作時可直接從主內存獲取,而無需從低速設備讀取。物理內存還用於存儲從快設備讀取的數據,使得隨後對該數據的訪問可直接在物理內存進行,而無需從外部設備再次取用。考慮系統中多種因素然後延遲寫回在總體上改進了系統的性能。前面分析的部分,例如內存管理的slab緩存是一個內存到內存的緩存,其目地不是加速對低速設備的操作,而是對現有資源進行更簡單、更高效的使用。文件系統的Dentry緩存也用於減少對低速塊設備的訪問,但他無法推廣到通用場合,因為他是專門用於處理單一數據類型的。

內核為塊設備提供了兩種通用的緩存方案:

1) 頁緩存,針對以頁為單位的所有操作,並考慮了特定體系結構上的頁長度。一個主要的例子是內存映射技術。因為其他類型的文件訪問也是基於內核中的這一技術實現的。所以頁緩存實際上負責了塊設備的大部分緩存工作。

2) 塊緩存,以塊為操作單位。在進行I/O操作時,存取的單位是設備的各個塊,而不是整個內存頁。盡管頁長度對所有文件系統都是相同的,但塊長度取決於特定的文件系統或其設置。因而,塊緩存必須能夠處理不同長度的塊。

目前用於塊傳輸的標准數據結構已經演變為struct bio。用這種方式進行塊傳輸更為高效,因為他可以合並同一請求中後續的塊,加速處理的進行。在許多場合下,頁緩存和塊緩存是聯合使用的。例如,一個緩存的頁在寫操作期間可以劃分為不同的緩沖區,這樣可以在更細的力度下,識別出頁被修改的部分。好處在於,在將數據寫回時,只需要回寫被修改的部分,無需將這個頁面傳輸回底層的塊設備。

頁面緩存結構

[cpp]
  1. /*高速緩存的核心數據結構,對塊設備的讀寫操作都放在該結構體裡*/  
  2. struct address_space {  
  3.     /*與地址空間所管理的區域之間的關聯數據結構之一 
  4.     inode結構指定了後備存儲器*/  
  5.     struct inode        *host;      /* owner: inode, block_device */  
  6.     /*與地址空間所管理的區域之間的關聯之二 
  7.     ,page_tree列出了地址空間中所有的物理內存頁*/  
  8.     struct radix_tree_root  page_tree;  /* radix tree of all pages */  
  9.     spinlock_t      tree_lock;  /* and lock protecting it */  
  10.     /*所有用VM_SHARED屬性創建的映射*/  
  11.     unsigned int        i_mmap_writable;/* count VM_SHARED mappings */  
  12.     /*基數根節點,該樹包含了與該inode相關的所有 
  13.     普通內存映射。該樹的任務在於,支持查找包含了 
  14.     給定區間中至少一頁的所有內存區域*/  
  15.     struct prio_tree_root   i_mmap;     /* tree of private and shared mappings */  
  16.     /*包含所有在非線性映射中的頁*/  
  17.     struct list_head    i_mmap_nonlinear;/*list VM_NONLINEAR mappings */  
  18.     spinlock_t      i_mmap_lock;    /* protect tree, count, list */  
  19.     unsigned int        truncate_count; /* Cover race condition with truncate */  
  20.     /*緩存頁的總數*/  
  21.     unsigned long       nrpages;    /* number of total pages */  
  22.     pgoff_t         writeback_index;/* writeback starts here */  
  23.     const struct address_space_operations *a_ops;   /* methods */  
  24.     /*集主要用於保存映射頁所來自的GFP內存區 
  25.     的有關信息*/  
  26.     unsigned long       flags;      /* error bits/gfp mask */  
  27.     /*指向後備存儲器結構,該結構包含了與地址空間相關的 
  28.     後備存儲器的有關信息,後備存儲器是指與地址空間相關 
  29.     的外部設備,用做地址空間中信息的來源。他通常是塊設備 
  30.     */  
  31.     struct backing_dev_info *backing_dev_info; /* device readahead, etc */  
  32.     spinlock_t      private_lock;   /* for use by the address_space */  
  33.     /*用於將包含文件系統元數據(通常是間接塊)的buffer_head 
  34.     實例彼此連接起來*/  
  35.     struct list_head    private_list;   /* ditto */  
  36.     /*指向相關的地址空間的指針*/  
  37.     struct address_space    *assoc_mapping; /* ditto */  
  38. } __attribute__((aligned(sizeof(long))));  

後備存儲信息

[cpp]
  1. struct backing_dev_info {  
  2.     struct list_head bdi_list;  
  3.     struct rcu_head rcu_head;  
  4.     /*最大預讀數量,單位為PAGE_CACHE_SIZE*/  
  5.     unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */  
  6.     /*對該成員,總是使用原子操作,指定了後備存儲器的狀態*/  
  7.     unsigned long state;    /* Always use atomic bitops on this */  
  8.     /*設備能力*/  
  9.     unsigned int capabilities; /* Device capabilities */  
  10.     congested_fn *congested_fn; /* Function pointer if device is md/dm */  
  11.     void *congested_data;   /* Pointer to aux data for congested func */  
  12.     void (*unplug_io_fn)(struct backing_dev_info *, struct page *);  
  13.     void *unplug_io_data;  
  14.   
  15.     char *name;  
  16.   
  17.     struct percpu_counter bdi_stat[NR_BDI_STAT_ITEMS];  
  18.   
  19.     struct prop_local_percpu completions;  
  20.     int dirty_exceeded;  
  21.   
  22.     unsigned int min_ratio;  
  23.     unsigned int max_ratio, max_prop_frac;  
  24.   
  25.     struct bdi_writeback wb;  /* default writeback info for this bdi */  
  26.     spinlock_t wb_lock;   /* protects update side of wb_list */  
  27.     struct list_head wb_list; /* the flusher threads hanging off this bdi */  
  28.     unsigned long wb_mask;    /* bitmask of registered tasks */  
  29.     unsigned int wb_cnt;      /* number of registered tasks */  
  30.   
  31.     struct list_head work_list;  
  32.   
  33.     struct device *dev;  
  34.   
  35. #ifdef CONFIG_DEBUG_FS   
  36.     struct dentry *debug_dir;  
  37.     struct dentry *debug_stats;  
  38. #endif   
  39. };  

下圖為地址空間與內核其他部分的關聯。

Copyright © Linux教程網 All Rights Reserved