From: Tejun Heo Date: Thu, 12 Jan 2006 14:39:26 +0000 (+0100) Subject: [PATCH] fix queue stalling while barrier sequencing X-Git-Tag: v2.6.16-rc1~282 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1bc691d357c646700b9523d2aeca02847d3fb3f4;p=linux-2.6 [PATCH] fix queue stalling while barrier sequencing If ordered tag isn't supported, request ordering for barrier sequencing is performed by queue draining, which basically hangs the request queue until elv_completed_request() reports completion of all previous fs requests. The condition check in elv_completed_request() was only performed for fs requests. If a special request is queued between the last to-be-drained request and the barrier sequence, draining is never completed and the queue is stalled forever. This patch moves the end-of-draining condition check such that it's performed for all requests. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- diff --git a/block/elevator.c b/block/elevator.c index 99a4d7b2f8..1d0759178e 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -610,23 +610,23 @@ void elv_completed_request(request_queue_t *q, struct request *rq) * request is released from the driver, io must be done */ if (blk_account_rq(rq)) { - struct request *first_rq = list_entry_rq(q->queue_head.next); - q->in_flight--; + if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn) + e->ops->elevator_completed_req_fn(q, rq); + } - /* - * Check if the queue is waiting for fs requests to be - * drained for flush sequence. - */ - if (q->ordseq && q->in_flight == 0 && + /* + * Check if the queue is waiting for fs requests to be + * drained for flush sequence. + */ + if (unlikely(q->ordseq)) { + struct request *first_rq = list_entry_rq(q->queue_head.next); + if (q->in_flight == 0 && blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN && blk_ordered_req_seq(first_rq) > QUEUE_ORDSEQ_DRAIN) { blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0); q->request_fn(q); } - - if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn) - e->ops->elevator_completed_req_fn(q, rq); } }