Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 16: Page and Buffer Cache


The kernel sources do, of course, provide functionsthat can be used as front ends to create and destroy
buffer heads.alloc_buffer_headgenerates a new buffer head, andfree_buffer_headdestroys an
existing head. Both functions are defined infs/buffer.c. As you might expect, they essentially consist
of straightforward gymnastics with memory management functions and statistics accounting and need
not be discussed here.

16.5.3 Interaction of Page and Buffer Cache


Buffer heads become much more interesting when used in conjunction with the useful data that they are
to hold in memory. This section examines the link between pages and buffer heads.

Linking of Pages and BufferHeads


How are buffers and pages interlinked? Recall that this approach was briefly discussed above. A page
is split into several data units (the actual number varies between architectures depending on page and
block size), but the buffer heads are held in a separate memory area that has nothing to do with the actual
data. The page contents arenotmodified by the interaction with buffers, as the latter simply provide a
new view of the page data.

Theprivateelement ofstruct pageis required to support interaction between a page and buffers. It is
of typeunsigned longand can therefore be used as a pointer to any positions in virtual address space
(the exact definition ofpageis given in Chapter 3):

<mm.h>
struct page {
...
unsigned long private; /* Mapping-private opaque data */
...
}

Theprivateelement can also be used for various other purposes that, depending on page use, need
have nothing to do with buffers.^10 However, its predominant use is to link buffers and pages. In this
case,privatepoints to the first buffer head used to split the page into smaller units. The various buffer
heads are linked in a cyclic list by means ofb_this_page. In this list, each pointer points to the next
buffer, and theb_this_pageelement of the last buffer head points to the first buffer. This enables
the kernel to easily scan allbuffer_headinstances associated with the page, starting from thepage
structure.

How is the association between thepageand thebuffer_headstructures established? The kernel pro-
vides thecreate_empty_buffersandlink_dev_buffersfunctions for this purpose, both of which
are implemented infs/buffer.c. The latter serves to associate an existing set of buffer heads with a
page, whereascreate_empty_buffersgenerates a completely new set of buffers for association with the
page. For example,create_empty_buffersis invoked when reading and writing complete pages with
block_read_full_pageand__block_write_full_page.

create_empty_buffersfirst invokesalloc_page_buffersto create the required number of buffer heads
(this number varies according to page and block size). It returns a pointer to the first element of a singly

(^10) If the page resides in the swap cache, an instance ofswp_entry_tis also stored in the cache. If the page is not in use, the element
holds the order in the buddy system.

Free download pdf