Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


access is to be made to sectormwithin the partition, a request must be created to access sector
m+nof the block device. The correct offset for the partition is held in thepartsarray of the
gendiskinstance associated with the queue.
❑ q->make_request_fngenerates arequestby reference to thebioand forwards it to the device
driver. The kernel standard function (__make_request) is invoked for most devices.

Perform statistics acccounting

submit_bio

generic_make_request

_ _generic_make_request

bdev_get_queue

blk_partition_remap

queue->make_request_fn

Figure 6-16: Code flow diagram forsubmit_bio.

I have announced above that this approach can cause problems, and they manifest themselves exactly
at this point. Some block drivers in the kernel — MD and the device mapper — cannot use the
standard function supplied by the kernel and implement their own functions. These, however, call
generic_make_requestrecursively!


While recursive function calls are no problem in userspace, they can become problematic in the kernel
since only very limited stack space is available. Therefore a way to limit the maximal recursion depth to
a sane value needs to be devised. To understand how this is done, observe first that thetask_struct,
which represents central data for each process (refer to Chapter 2), also contains two elements related to
BIO handling:


<sched.h>
struct task_struct {
...
/* stacked block device info */
struct bio *bio_list, **bio_tail;
...
}

The pointers are used to limit the maximal recursion depth to one — without losing any of the submitted
BIOs,naturally.Ifgeneric_make_requestor some subfunction callsgeneric_make_request,thecode
flow will return before the next recursive call to
generic_make_request. To understand how, we
need to take a look at the implementation ofgeneric_make_request(recall thatcurrentpoints to the
task_structinstance of the currently running process).


block/ll_rw_blk.c
void generic_make_request(struct bio *bio)
{
if (current->bio_tail) {
/* make_request is active */
Free download pdf