Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


6.5.7 Submitting Requests


In this section, I discuss the mechanism that the kernel provides to submit data requests to peripheral
devices. This also involves buffering and reordering requests to reduce disk head seek movements, for
example, or to boost performance by bundling operations. Also covered are the operation of the device
driver, which interacts with the specific hardware in order to process requests, and the general code of the
virtual filesystem that is associated with device files and therefore with user applications and other parts
of the kernel. As you will see in Chapters 16 and 8, the kernel employs caches to retain data already read
from block devices for future reuse if the same request is submitted repeatedly. We are not interested
in this particular aspect here. Instead, we will examine how the kernel goes about submitting a physical
request to a device to read or write data.

The kernel submits a request in two steps.

❑ It creates abioinstance to describe the request and then embeds the instance in a request that is
placed on a request queue.
❑ It processes the request queue and carries out the actions described by thebio.

Creating a newbioinstance is not particularly interesting as all it involves is filling the desired locations
on a block device and providing page frames to hold and transfer the relevant data. I won’t bother with
the details.

Once a BIO has been created,make_request_fnis invoked to generate a new request for insertion on the
request queue.^12 The requests are submitted byrequest_fn.

The implementation of these actions reside inblock/ll_rw_blk.cup to kernel 2.6.24. The strange-
sounding filename is an abbreviation oflow level read write handling for block devices. Later kernels split
the implementation into a number of smaller files named by the schemeblock/blk-*.c.

Creating Requests


submit_biois the key function that creates a new request based on a passedbioinstance and finally
places it on the request queue of the driver usingmake_request_fn. Figure 6-16 shows the associated
code flow diagram. Let’s consider a simplified version first, but come back later to address some problems
that can arise in certain cases, and how the kernel solves them with a little trick.

The function is invoked at various places in the kernel to initiate physical data transfers.submit_bio
simply updates the kernel statistics, the actual work being delegated to__generic_make_requestafter
adetourovergeneric_make_request, which is explained below. The work is done in three steps after
a few sanity checks have been performed (one such check establishes, for example, whether the request
exceeds the physical capabilities of the device).

❑ The request queue of the block device to which the request refers is found using
bdev_get_queue.
❑ If the device is partitioned, the request is remapped withblk_partition_remapto ensure that
the correct area is read or written. This enables the remaining kernel to treat individual partitions
in the same way as independent, non-partitioned devices. If a partition starts at sectornand

(^12) Or to store the request elsewhere if the driver has explicitlyreplaced the default implementation with its own function.

Free download pdf