lkml.org 
[lkml]   [1999]   [Feb]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subjectplug_device and unplu_device question

Hi,

This question is about the plug_device and unplug_device routines in
lnux/drivers/block/ll_rw_blk.c

1. I cannot find the place where linux fills up the dev->plug structure
apart from the initilizing routine. But in unplug_device routine
dev->plug.next is used. Also in plug device
dev->current_request =&dev->plug is done.
Where is the contents from dev->plug coming from ?

2. The plug_device is called when there is a request to the device but
dev->current_request is currently empty.(in make request).
However my understanding is that the request is actually attached to the
request queue of the device in add_request routine which is called after
the task is scheduled. What happens is the dev->req_fn() is called before
add_request can schdule the requests ? Or is this possible ?

3. If some one can explain how the plug_device and the unplug_device works
with the ide disk drives that will be the answer I am looking for.

Some help on these questions is very much appreciated.

Thanx
Ravi

***************************************************************************
plug_device and unplug_device fit in as follows

*****************************************************************************
The initialising is done here


blk_dev_init()
{
.....

for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {
dev->request_fn = NULL;
dev->current_request = NULL;
dev->plug.rq_status = RQ_INACTIVE;
dev->plug.cmd = -1;
dev->plug.next = NULL;
dev->plug_tq.routine = &unplug_device;
dev->plug_tq.data = dev;
}

.......
}


The calling is done in

static void make_request(int major,int rw, struct buffer_head * bh)
{
......

req = blk_dev[major].current_request;

if (!req) {
/* MD and loop can't handle plugging without deadlocking
*/
if (major != MD_MAJOR && major != LOOP_MAJOR)
plug_device(blk_dev + major);
} else switch (major) {

.............
}


and the two routines are as follows


static inline void plug_device(struct blk_dev_struct * dev)
{
dev->current_request = &dev->plug;
queue_task_irq_off(&dev->plug_tq, &tq_disk);
}



void unplug_device(void * data)
{
struct blk_dev_struct * dev = (struct blk_dev_struct *) data;
unsigned long flags;

save_flags(flags);
cli();
if (dev->current_request == &dev->plug) {
struct request * next = dev->plug.next;
dev->current_request = next;
if (next) {
dev->plug.next = NULL;
(dev->request_fn)();
}
}
restore_flags(flags);
}



**********************************************************************


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:50    [W:0.034 / U:0.688 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site