Hi,

In Linux Device Drivers, chapter 16 about Block Devices, page 12-13, a
simple block device request() method is presented:

static void sbull_request(request_queue_t *q)
{
    struct request *req;
    while ((req = elv_next_request(q)) != NULL) {
        struct sbull_dev *dev = req->rq_disk->private_data;
        if (! blk_fs_request(req)) {
                printk (KERN_NOTICE "Skip non-fs request\n");
                end_request(req, 0);
                continue;
        }

        sbull_transfer(dev, req->sector, req->current_nr_sectors,
                       req->buffer, rq_data_dir(req));
        end_request(req, 1);
    }
}

This method uses the rq->buffer field of the struct request to get the
location of the information to be written (or the location at which
information read from the device should be stored).

From by understanding, this field is updated at each
end_request() by blk_recalc_rq_sectors(), so that at each iteration of
the loop, rq->buffer will be different. Is that correct ?

blk_recalc_rq_sectors() uses bio_data() to compute the address at which
the data should be read/written. But this bio_data() uses
page_address(), which only works if the page is in ZONE_NORMAL, not in
ZONE_HIGHMEM. This fact is highlighted in <linux/bio.h> :

/*
 * various member access, note that bio_data should of course not be used
 * on highmem page vectors
 */

So, who is doing the bounce buffering of the bio page when it's stored
in ZONE_HIGHMEM ? Is it safe for a block driver to blindly use
rq->buffer without knowing if the bio's page is in HIGHMEM or not ?

Thanks,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [EMAIL PROTECTED]
Please read the FAQ at http://kernelnewbies.org/FAQ

Reply via email to