Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 16: Page and Buffer Cache


pages, the kernel employspage_cache_sync_readaheadto read in 8 pages in a row — the number
is just an example that does not comply with reality. The first page is immediately available for
do_generic_mapping_read.^8 Pages selected to be read in before they are actually required are said to be
in areadaheadwindow.

The process now continues to read in pages and behaves linearly as expected. When the sixth page
is accessed (notice that the page was already contained in the page cache before the process issued
a corresponding request),do_generic_mapping_readnotices that the page was equipped with the
PG_Readaheadbit in the synchronous read pass.^9 This triggers anasynchronousoperation that reads in
anumberofpagesin the background. Since two more pages are left in the page cache, there is no need
to hurry; thus a synchronous operation is not required. However, the I/O performed in the background
will ensure that the pages are present when the process makes further progress in the file. If the kernel
would not adopt this scheme, then readahead could only start after a process has experienced a page
fault. While the required page (and some more pages for readahead) could be then brought into the page
cache synchronously, this would introduce delays, which are clearly undesired.

This scheme is now repeated further. Sincepage_cache_async_read— which is responsible to issue the
asynchronous read request — has again marked a page in the readahead window with thePG_Readahead
bit, the kernel will start asynchronous readahead again when the process comes to this page, and so on.

So much fordo_generic_readahead. The differences in howfilemap_faulthandles things are twofold:
Asynchronous, adaptive readahead is only performed if a sequential read hint is set. If no readahead hint
is given, thendo_page_cache_readaheaddoes a single-shot readahead without settingPG_Readahead,
and also without updating the file’s readahead state tracking information.

Several functions are used to implement the readahead mechanism. Figure 16-5 shows how they are
connected with each other.

VFS, Memory management

fadvise,madvise,
readahead system calls

force_page_cache_readahead do_page_cache_readahead ondemand_readahead ra_submit

page_cache_sync_readahead

_ _do_page_cache_readahed
Bring pages into page cache

page_cache_async_readahead

Figure 16-5: Functions used to implement readahead. Note that the figure shows the connections
between the functions, but is not a proper code flow diagram.

(^8) Actually, the termsynchronousas adopted by the kernel is a bit misleading here. No effort is made to wait on completion of the read
operation submitted bypage_cache_sync_readahed, so it is not synchronous in the usual sense of the word. However, since
reading in one page is fast, chances are very good that the page will usually have arrived whenpage_cache_sync_readahead
returns to the caller. Nevertheless, the caller has to make precautions for the case in which the page is not yet available.
(^9) Since the readahead state for each file is separately tracked, the kernel would essentially not require this special flag because the
corresponding information could also be obtained otherwise. However, it is required when multiple concurrent readers act on a file.

Free download pdf