Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


queue_headis the central list head used to construct a doubly linked list of requests — each element is
of the data typerequestdiscussed below and stands for a request to the block device to read or fetch
data. The kernel rearranges the list to achieve better I/O performance (several algorithms are provided
to perform I/O scheduler tasks as described below). As there are various ways of resorting requests, the
elevatorelement^8 groups the required functions together in the form of function pointers. I shall come
back to this structure further below.

rqserves as a cache forrequestinstances.struct request_listis used as a data type; in addition to the
cache itself, it provides two counters to record the number of available free input and output requests.

The next block in the structure contains a whole series of function pointers and represents the central
request handling area. The parameter settings and return type of the function are defined bytypedef
macros (struct biomanages the transferred data and is discussed below).

<blkdev.h>
typedef void (request_fn_proc) (struct request_queue *q);
typedef int (make_request_fn) (struct request_queue *q, struct bio *bio);
typedef int (prep_rq_fn) (struct request_queue *, struct request *);
typedef void (unplug_fn) (struct request_queue *);

typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *);
typedef void (prepare_flush_fn) (struct request_queue *, struct request *);
typedef void (softirq_done_fn)(struct request *);

The kernel provides standard implementations of these functions that can be used by most device drivers.
However, each driver must implement its ownrequest_fnfunction because this represents the main link
between the request queue management and the low-level functionality of each device — it is invoked
when the kernel processes the current queue in order to perform pending read and write operations.

The first four functions are responsible to manage the request queue:

❑ request_fnis the standard interface for adding new requests to the queue. The function is auto-
matically called by the kernel when the driver is supposed to perform some work like reading
data from or writing data to the underlying device. In kernel nomenclature, this function is also
referred to asstrategy routine.
❑ make_request_fncreates new requests. The standard kernel implementation of this function
adds the request to the request list as you will see below. When there are enough requests in the
list, the driver-specificrequest_fnfunction is invoked to process them together.
The kernel allows device drivers to define their ownmake_request_fnfunctions because some
devices (RAM disks, for example) do not make use of queues as data can be accessed in any
sequence without impairing performance, orthey might know better than the kernel how to
deal with requests and would not benefit from the standard methods (volume managers, for
example). However, this practice is rare.
❑ prep_rq_fnis a request preparation function. It is not used by most drivers and is therefore set
toNULL. If it is implemented, it generates the hardware commands needed to prepare a request
before the actual request is sent. The auxiliary functionblk_queue_prep_rqsetsprep_rq_fnin a
given queue.

(^8) This term is slightly confusing because none of the algorithms used by the kernel implements the classic elevator method. Never-
theless, the basic objective is similar to that of elevators.

Free download pdf