Analysis of fast caching and writeback mechanism of Linux pages

Source: Internet
Author: User

References


"Linux kernel design and implementation"


*******************************************


Page cache is a major disk cache implemented by the Linux kernel, which is primarily used to reduce IO operations on disks, in detail by caching the data on the disk into physical memory, and turning access to the disk into physical memory. Why did you do it? One, the speed, the second temporary local principle. Regarding these two concepts, we believe that we are not too unfamiliar with the operating system. The page cache is made up of physical pages in RAM, and each page in the cache corresponds to multiple blocks in the disk. Whenever the kernel starts to run a page IO operation, it is first found in the fast cache. This can significantly reduce disk operations.
A physical page may consist of multiple discontinuous physical disk blocks. It is also because the mapped disk blocks in the page are not necessarily contiguous, so it becomes less easy to detect whether specific data has been cached in the page's fast cache. In addition, the Linux page cache is very wide defined for the range of cached pages. The target of the cache is whatever the page-based object, which includes various types of files and various types of memory mappings. To meet the requirements of universality, Linux uses structures defined in linux/fs.h to describe pages in the narrative page cache, such as the following: Address_space structure.

struct Address_space {struct inode *host;          /* Owning Inode */struct radix_tree_root page_tree;          /* Radix Tree of all pages */spinlock_t Tree_lock;    /* page_tree lock */unsigned int i_mmap_writable;             /* vm_shared ma count */struct prio_tree_root i_mmap;   /* List of all mappings */struct list_head i_mmap_nonlinear;        /* Vm_nonlinear MA list */spinlock_t i_mmap_lock;     /* I_MMAP Lock */atomic_t Truncate_count;            /* Truncate RE count */unsigned long nrpages;    /* Total number of pages */pgoff_t Writeback_index;   /* Writeback start offset */struct address_space_operations *a_ops;              /* Operations Table */unsigned long flags;  /* Gfp_mask and Error flags */struct backing_dev_info *backing_dev_info; /* Read-aheaD Information */spinlock_t Private_lock;       /* Private lock */struct list_head private_list;     /* Private list */struct address_space *assoc_mapping; /* Associated buffers */};

The I_mmap field is a priority search tree, and its search scope includes both private and shared pages in Address_sapce. Nrpages reflects the size of the address_space space. Address_space structures are often associated with certain kernel objects. Typically, an index node (inode) is associated with a host domain that points to that index node. Assuming that the associated object is not an index node, such as Address_space and Swapper, this is the host field that is set to null. The A_ops field points to an action function table in an address space object, similar to the VFS object and its action function table, which is defined in linux/fs.h and represented by address_space_operations, such as the following:
struct Address_space_operations {        int (*writepage) (struct page *, struct writeback_control *);        Int (*readpage) (struct file *, struct page *);        Int (*sync_page) (struct page *);        Int (*writepages) (struct address_space *, struct writeback_control *);        Int (*set_page_dirty) (struct page *);        Int (*readpages) (struct file *, struct address_space *,struct list_head *, unsigned);        Int (*prepare_write) (struct file *, struct page *, unsigned, unsigned);        Int (*commit_write) (struct file *, struct page *, unsigned, unsigned);        sector_t (*bmap) (struct address_space *, sector_t);        Int (*invalidatepage) (struct page *, unsigned long);        Int (*releasepage) (struct page *, int);        Int (*direct_io) (int, struct KIOCB *, const struct IOVEC *,loff_t, unsigned long);};

Background-color:rgb (255, 255, 255); " The two most important > in this area are Readpage () and Writepage (). For the Readpage () method, first, a Address_space object and an offset are passed to the method, and the two parameters are used to search for the required data in the page's fast cache:

page = find_get_page (mapping, index), mapping is the specified address space, and index is the specified location in the file. Assuming that the page you are searching for is not in the fast cache, the kernel assigns a new page and then adds it to the page cache, such as the following int error;cached_page = Page_cache_alloc_cold (mapping); if (!cached_ Page)/        * ERROR allocating memory */error = ADD_TO_PAGE_CACHE_LRU (cached_page, mapping, Index, Gfp_kernel); if (error) /        * Error adding page to page cache */


Finally, the required data is read from the disk, added to the page cache, and then returned to the User: Error = mapping->a_ops->readpage (file,page);
Write operations and read operations are slightly different. For file mappings, when the page is changed, the VM only needs to be called: Setpagedirty (page); The kernel writes the page out later through the Writepage () method. Writing to a particular file can be more complicated----its code in file mm/filemap.c, usually the write path consists of the following steps:
page = __grab_cache_page (mapping, Index, &cached_page, &lru_pvec); status = A_ops->prepare_write (file, page, Offset, offset+bytes);p age_fault = filemap_copy_from_user (page, offset, buf, bytes); status = A_ops->commit_write ( file, page, offset, offset+bytes);

First, searching for the required pages in the page cache, assuming that the required pages are not in the fast cache, the kernel allocates a new spare item in the fast cache, the next step, the Prepare_write () method is called, a write request is created, and the data is copied from the user space to the kernel buffer; The _write () function writes data to disk.


Since the kernel checks whether the page is already in the page cache before any page IO operation, such a check must be fast and efficient. Otherwise it is worth the candle. As already mentioned earlier, the fast cache is searched by two parameter Address_space objects and an offset. Each Address_space object has a unique Motoki (radix tree), which is guaranteed in the page_tree structure. Motoki is a binary tree, only to specify the file offset, you can quickly retrieve the base tree of the desired data, page cache search function find_get_
Page () to invoke the function Radix_tree_lookup (), the function searches the specified base tree for the specified page. The common form of the base tree core code can be found in the file lib/radix-tree.c, in addition to the use of the base tree, need to include the header file linux/radix_tree.h.


The dirty pages that accumulate in memory must be written back to disk, and in either case, the dirty pages will be written to disk:


1. When spare memory falls below a specific threshold, the kernel must write the dirty page back to the disk in order to free up memory.
2. When dirty pages reside in memory more than a certain threshold, the kernel must write the dirty pages that time out to disk to ensure that dirty pages do not reside in memory indefinitely.
Now all you need to know is that the 2.6 kernel uses the Pdflush background writeback routines to complete this work. So how do we do it in detail:


First, the Pdflush thread flushes the dirty page back to disk when the spare memory in the system falls below a specific threshold. The purpose of this background writeback routine is to free up dirty pages to get memory again when available physical memory is too low. The specific memory thresholds mentioned above can be set through the Dirty_background_ratio system call. Once the spare memory is more than this, the kernel calls the function Wakeup_bdflush () to wake up a pdflush thread, and then the Pdflush thread further calls the function Background_writeout () to start writing the dirty page to disk. The function background_writeout () requires a long integer parameter that specifies the number of pages to be written back. The function Background_writeout writes the data continuously until two conditions are met:


1. The minimum number of pages already specified is written back to disk.
2. The spare memory page has been picked up, exceeding the threshold value of dirty_background_ration.
Pdflush threads (in real-life mm/pdflush.c, the implementation code of the writeback mechanism is woken up periodically in files Mm/page-writeback.c and fs/fs-writeback.c) and the dirty pages that exceed a certain period are written back to disk. System administrators can set write-back related parameters in/proc/sys/vm, and they can be set by Sysctl system. The following table shows the amount that can be set:


Analysis of fast caching and writeback mechanism of Linux pages

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.