Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 16: Page and Buffer Cache


the entire page back to the block device because most of the page data in memory are still synchronized
with the data on the block device. To save time, the kernel divides each page in the cache into smaller
units known asbuffersduring write operations. When data are synchronized, the kernel is able to restrict
writeback to the smaller units that have actually been modified. As a result, the basically sound idea of
page caching is not compromised in any way.

16.2 Structure of the Buffer Cache


A page-oriented method has not always been used inthe Linux kernel to bear the main caching burden.
Earlier versions included only the buffer cache to speed file operations and to enhance system perfor-
mance. This was a legacy of otherUnixlook-alikes with the same structure. Blocks from the underlying
block devices were kept in main memory buffers to make read and write operations faster. The imple-
mentation is contained infs/buffers.c.

In contrast to pages in memory, blocks are not only (mostly) smaller but vary in size depending on the
block device in use (or on the filesystem, as demonstrated in Chapter 9).

As a result of the ever increasing trend toward generic file access methods implemented by means of
page-based operations, the buffer cache has lost much of its importance as a central system cache, and the
main caching burden is now placed firmly on the page cache. Additionally, the standard data structure
for block-based I/O is not a buffer anymore, butstruct bioas discussed in Chapter 6.

Buffers are kept for small I/O transfers with block size granularity. This is often required by filesystems
to handle their metadata. Transfer of raw data is done in a page-centric fashion, and the implementation
of buffers is also on top of the page cache.^3

The buffer cache consists of two structural units:


  1. Abuffer headholds all management data relating to the state of the buffer including informa-
    tion on block number, block size, access counter, and so on, discussed below. These data are
    notstored directly after the buffer head but in a separate area of RAM memory indicated by
    a corresponding pointer in the buffer head structure.

  2. The useful data are held in specially reserved pages that may also reside in the page cache.
    This further subdivides the page cache as illustrated in Figure 16-2; in our example, the page
    is split into four identically sized parts, each of which is described by its own buffer head.
    The buffer heads are held in memory areas unrelated to the areas where the useful data are
    stored.
    This enables the page to be subdivided into smaller sections because no gaps arise as a result
    of prefixing the buffer data with header data. As a buffer consists of at least 512 bytes, there
    may be up to a maximum ofMAX_BUF_PER_PAGEbuffers per page; the constant is defined as
    a function of the page size:
    #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)


(^3) This contrasts kernels before and including the 2.2 series that used separate caches for buffers and pages. Having two distinct
caching possibilities requires enormous efforts to synchronize both, so the kernel developers chose to unify the caching scheme many
years ago.

Free download pdf