Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 16: Page and Buffer Cache..........................................


Caching is a kind of ‘‘reverse‘‘ swapping or paging operation (the latter are discussed in Chapter 18).
Whereas fast RAM is sacrificed for caching (so that there is no need for slow operations on block devices),
RAM memory is replaced virtually with slow block devices to implement swapping. The kernel must
therefore do its best to cater to both mechanisms to ensure that the advantages of the one method are not
canceled out by the disadvantages of the other — no easy feat.

Previous chapters discussed some of the means provided by the kernel for caching specific structures.
The slab cache is a memory-to-memory cache whose purpose is not to accelerate operations on slower
devices but to make simpler and more effective use of existing resources. The dentry cache is also used to
dispense with the need to access slow block devices but cannot be put to general use since it is specialized
to handle a single data type.

The kernel features two general caching options for block devices:


  1. Thepage cacheis intended for all operations in units of a page — and takes into account the
    page size on the specific architecture. A prime example is the memory-mapping technique
    discussed in many chapters. As other types of file access are also implemented on the basis
    of this technique in the kernel, the page cache is responsible for most caching work for block
    devices.

  2. Thebuffer cacheoperates with blocks. When I/O operations are performed, the access units
    used are the individual blocks of a device andnot whole pages. Whereas the page size is the
    same with all filesystems, the block size varies depending on the particular filesystem or its
    settings. The buffer cache must therefore be able to handle blocks of different sizes.
    While buffers used to be the traditional method to perform I/O operations with block
    devices, they are nowadays in this area only supported for very small read operations
    where the advanced methods are too bulky. The standard data structure used for block
    transfers has becomestruct bio, which is discussed in Chapter 6. It is much more efficient
    to perform block transfers this way because it allows for merging subsequent blocks in a
    request together that speeds things up.
    Nevertheless, buffers are still the method of choice to represent I/O operations on individual
    blocks, even if the underlying I/O is performed withbios. Especially systems often have to
    read metadata blockwise, and buffers are much easier to handle for this task than other more
    powerful structures. All in all, buffers still have their own identity and are not around solely
    for compatibility reasons.


In many scenarios, page and buffer caches are used in combination. For example, a cached page is divided
into various buffers during write operations so that the modified parts of the page can be more finely
grained. This has advantages when the data are written back because only the modified part of the page
and not the whole page need be transferred back to the underlying block device.

16.1 Structure of the Page Cache


As its name suggests, thepage cachedeals with memory pages that divide virtual memory and RAM
memory into small segments. This not only makes it easier for the kernel to manipulate the large address
space, but also supports a whole series of functions such as paging, demand loading, memory mapping,
and the like. The task of the page cache is to obtain some of the available physical page frames to speed
up the operations performed on block devices on a page basis. Of course, the way the page cache behaves
Free download pdf