From axboe@suse.de Thu Mar 17 19:52:29 2005
Return-Path: <axboe@suse.de>
X-Original-To: con@kolivas.org
Delivered-To: con@kolivas.org
Received: from bhhdoa.org.au (bhhdoa.org.au [216.17.101.199])
	by mail.kolivas.org (Postfix) with ESMTP id F027CC5C97
	for <con@kolivas.org>; Thu, 17 Mar 2005 19:52:35 +1100 (EST)
Received: from virtualhost.dk (ns.virtualhost.dk [195.184.98.160])
	by bhhdoa.org.au (Postfix) with ESMTP id 44FFD5140F
	for <con@kolivas.org>; Thu, 17 Mar 2005 20:19:51 +1100 (EST)
Received: from [62.242.22.158] (helo=wiggum.home.kernel.dk)
	by virtualhost.dk with esmtp (Exim 3.36 #1)
	id 1DBqk3-0006DR-00
	for con@kolivas.org; Thu, 17 Mar 2005 09:52:31 +0100
Received: from axboe by wiggum.home.kernel.dk with local (Exim 4.44)
	id 1DBqk1-0000Cx-So
	for con@kolivas.org; Thu, 17 Mar 2005 09:52:30 +0100
Date: Thu, 17 Mar 2005 09:52:29 +0100
From: Jens Axboe <axboe@suse.de>
To: con@kolivas.org
Subject: [axboe@suse.de: [PATCH] cfq-iosched.c: fix soft hang with non-fs requests]
Message-ID: <20050317085229.GN7842@suse.de>
Mime-Version: 1.0
Content-Type: text/plain;
  charset=us-ascii
Content-Disposition: inline
X-UID: 803
X-Length: 3205
Status: R
X-Status: NC
X-KMail-EncryptionState:  
X-KMail-SignatureState:  
X-KMail-MDN-Sent:  
X-Spam-Checker-Version: SpamAssassin 3.0.0 (2004-09-13) on localhost
X-Spam-Level: 
X-Spam-Status: No, score=-0.7 required=5.0 tests=AWL,BAYES_00,
	FORGED_RCVD_HELO autolearn=ham version=3.0.0

Con,

Trying to keep you in sync with -mm cfq-ts, you should add this as well.
The hang is not easy to encounter, it was found during beta testing of
the suse kernel.

----- Forwarded message from Jens Axboe <axboe@suse.de> -----

From: Jens Axboe <axboe@suse.de>
Date: Thu, 17 Mar 2005 09:51:25 +0100
To: Andrew Morton <akpm@osdl.org>
Subject: [PATCH] cfq-iosched.c: fix soft hang with non-fs requests

Hi,

In several places cfq checks cfqd->busy_queues to see if we have pending
work, but that doesn't detect requests going directly to the dispatch
list since they don't end up in a queue and thus get ->busy_queues
incremented. Abstract the check into cfq_pending_work() and use that
throughout the code.

Signed-off-by: Jens Axboe <axboe@suse.de>

Index: linux-2.6.11-ck7/drivers/block/cfq-iosched.c
===================================================================
--- linux-2.6.11-ck7.orig/drivers/block/cfq-iosched.c	2005-05-01 10:36:05.000000000 +1000
+++ linux-2.6.11-ck7/drivers/block/cfq-iosched.c	2005-05-01 10:36:06.000000000 +1000
@@ -1723,11 +1723,16 @@ cfq_insert_request(request_queue_t *q, s
 	}
 }
 
+static inline int cfq_pending_requests(struct cfq_data *cfqd)
+{
+	return !list_empty(&cfqd->queue->queue_head) || cfqd->busy_queues;
+}
+
 static int cfq_queue_empty(request_queue_t *q)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
 
-	return list_empty(&q->queue_head) && !cfqd->busy_queues;
+	return !cfq_pending_requests(cfqd);
 }
 
 static void cfq_completed_request(request_queue_t *q, struct request *rq)
@@ -2048,7 +2053,7 @@ static void cfq_idle_slice_timer(unsigne
 		 * only expire and reinvoke request handler, if there are
 		 * other queues with pending requests
 		 */
-		if (!cfqd->busy_queues) {
+		if (!cfq_pending_requests(cfqd)) {
 			cfqd->idle_slice_timer.expires = min(now + cfqd->cfq_slice_idle, cfqq->slice_end);
 			add_timer(&cfqd->idle_slice_timer);
 			goto out_cont;
@@ -2065,7 +2070,7 @@ static void cfq_idle_slice_timer(unsigne
 expire:
 	cfq_slice_expired(cfqd, 0);
 out_kick:
-	if (cfqd->busy_queues)
+	if (cfq_pending_requests(cfqd))
 		kblockd_schedule_work(&cfqd->unplug_work);
 out_cont:
 	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
