Skip to content

Commit

Permalink
block: internal dequeue shouldn't start timer
Browse files Browse the repository at this point in the history
blkdev_dequeue_request() and elv_dequeue_request() are equivalent and
both start the timeout timer.  Barrier code dequeues the original
barrier request but doesn't passes the request itself to lower level
driver, only broken down proxy requests; however, as the original
barrier code goes through the same dequeue path and timeout timer is
started on it.  If barrier sequence takes long enough, this timer
expires but the low level driver has no idea about this request and
oops follows.

Timeout timer shouldn't have been started on the original barrier
request as it never goes through actual IO.  This patch unexports
elv_dequeue_request(), which has no external user anyway, and makes it
operate on elevator proper w/o adding the timer and make
blkdev_dequeue_request() call elv_dequeue_request() and add timer.
Internal users which don't pass the request to driver - barrier code
and end_that_request_last() - are converted to use
elv_dequeue_request().

Signed-off-by: Tejun Heo <[email protected]>
Cc: Mike Anderson <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
htejun authored and Jens Axboe committed Dec 3, 2008
1 parent bf91db1 commit 53a0880
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 15 deletions.
4 changes: 2 additions & 2 deletions block/blk-barrier.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static inline struct request *start_ordered(struct request_queue *q,
/*
* Prep proxy barrier request.
*/
blkdev_dequeue_request(rq);
elv_dequeue_request(q, rq);
q->orig_bar_rq = rq;
rq = &q->bar_rq;
blk_rq_init(q, rq);
Expand Down Expand Up @@ -219,7 +219,7 @@ int blk_do_ordered(struct request_queue *q, struct request **rqp)
* This can happen when the queue switches to
* ORDERED_NONE while this request is on it.
*/
blkdev_dequeue_request(rq);
elv_dequeue_request(q, rq);
if (__blk_end_request(rq, -EOPNOTSUPP,
blk_rq_bytes(rq)))
BUG();
Expand Down
24 changes: 23 additions & 1 deletion block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,28 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
}
EXPORT_SYMBOL_GPL(blk_insert_cloned_request);

/**
* blkdev_dequeue_request - dequeue request and start timeout timer
* @req: request to dequeue
*
* Dequeue @req and start timeout timer on it. This hands off the
* request to the driver.
*
* Block internal functions which don't want to start timer should
* call elv_dequeue_request().
*/
void blkdev_dequeue_request(struct request *req)
{
elv_dequeue_request(req->q, req);

/*
* We are now handing the request to the hardware, add the
* timeout handler.
*/
blk_add_timer(req);
}
EXPORT_SYMBOL(blkdev_dequeue_request);

/**
* __end_that_request_first - end I/O on a request
* @req: the request being processed
Expand Down Expand Up @@ -1774,7 +1796,7 @@ static void end_that_request_last(struct request *req, int error)
blk_queue_end_tag(req->q, req);

if (blk_queued_rq(req))
blkdev_dequeue_request(req);
elv_dequeue_request(req->q, req);

if (unlikely(laptop_mode) && blk_fs_request(req))
laptop_io_completion();
Expand Down
7 changes: 0 additions & 7 deletions block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,14 +844,7 @@ void elv_dequeue_request(struct request_queue *q, struct request *rq)
*/
if (blk_account_rq(rq))
q->in_flight++;

/*
* We are now handing the request to the hardware, add the
* timeout handler.
*/
blk_add_timer(rq);
}
EXPORT_SYMBOL(elv_dequeue_request);

int elv_queue_empty(struct request_queue *q)
{
Expand Down
7 changes: 2 additions & 5 deletions include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,8 @@ static inline void blk_run_address_space(struct address_space *mapping)
blk_run_backing_dev(mapping->backing_dev_info, NULL);
}

extern void blkdev_dequeue_request(struct request *req);

/*
* blk_end_request() and friends.
* __blk_end_request() and end_request() must be called with
Expand Down Expand Up @@ -820,11 +822,6 @@ extern void blk_update_request(struct request *rq, int error,
extern unsigned int blk_rq_bytes(struct request *rq);
extern unsigned int blk_rq_cur_bytes(struct request *rq);

static inline void blkdev_dequeue_request(struct request *req)
{
elv_dequeue_request(req->q, req);
}

/*
* Access functions for manipulating queue properties
*/
Expand Down

0 comments on commit 53a0880

Please sign in to comment.