--- ./drivers/block/cfq-iosched.c.cfqfix	2007-01-29 03:56:45.000000000 +0300
+++ ./drivers/block/cfq-iosched.c	2007-01-29 06:24:12.000000000 +0300
@@ -50,6 +50,7 @@ static mempool_t *cfq_mpool;
 
 struct cfq_data {
 	struct list_head rr_list;
+	struct list_head cur_rr;
 	struct list_head *dispatch;
 	struct list_head *cfq_hash;
 
@@ -67,6 +68,7 @@ struct cfq_data {
 	 */
 	unsigned int cfq_quantum;
 	unsigned int cfq_queued;
+	struct cfq_queue *active_cfqq;
 };
 
 struct cfq_queue {
@@ -82,6 +84,7 @@ struct cfq_queue {
 	 */
 	int io_prio
 #endif
+	unsigned long slice_end;
 };
 
 struct cfq_rq {
@@ -368,20 +371,59 @@ __cfq_dispatch_requests(request_queue_t 
 	cfq_dispatch_sort(cfqd, cfqq, crq);
 }
 
+static inline int cfq_cfqq_expired(struct cfq_queue *cfqq)
+{
+	return cfqq->slice_end > jiffies ? 1 : 0;
+}
+
+static inline void cfq_expire_cfqq(struct cfq_data *cfqd,
+					struct cfq_queue *cfqq)
+{
+	list_move_tail(&cfqq->cfq_list, &cfqd->rr_list);
+	cfqd->active_cfqq = NULL;
+}
+
+#define TIME_SLICE (HZ / 10)
+
+static inline void cfq_set_active_queue(struct cfq_data *cfqd,
+						struct cfq_queue *cfqq)
+{
+	cfqd->active_cfqq = cfqq;
+	cfqq->slice_end = jiffies + TIME_SLICE;
+}
+
+static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
+{
+	struct cfq_queue *cfqq;
+
+	cfqq = cfqd->active_cfqq;
+	if (cfqq) {
+		if (!cfq_cfqq_expired(cfqq))
+			return cfqq;
+		else
+			cfq_expire_cfqq(cfqd, cfqq);
+	}
+
+	if (list_empty(&cfqd->cur_rr))
+		list_splice_init(&cfqd->rr_list, &cfqd->cur_rr);
+
+	cfqq = list_entry_cfqq(cfqd->cur_rr.next);
+	cfq_set_active_queue(cfqd, cfqq);
+	return cfqq;
+}
+
 static int cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd)
 {
 	struct cfq_queue *cfqq;
-	struct list_head *entry, *tmp;
 	int ret, queued, good_queues;
 
-	if (list_empty(&cfqd->rr_list))
+	if (list_empty(&cfqd->rr_list) && list_empty(&cfqd->cur_rr))
 		return 0;
 
 	queued = ret = 0;
 restart:
 	good_queues = 0;
-	list_for_each_safe(entry, tmp, &cfqd->rr_list) {
-		cfqq = list_entry_cfqq(entry);
+	cfqq = cfq_select_queue(cfqd);
 
 		BUG_ON(RB_EMPTY(&cfqq->sort_list));
 
@@ -394,7 +436,6 @@ restart:
 
 		queued++;
 		ret = 1;
-	}
 
 	if ((queued < cfqd->cfq_quantum) && good_queues)
 		goto restart;
@@ -450,6 +491,10 @@ static struct cfq_queue *cfq_find_cfq_ha
 
 static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
+
+	if (cfqq == cfqd->active_cfqq)
+		cfqd->active_cfqq = NULL;
+
 	cfqd->busy_queues--;
 	list_del(&cfqq->cfq_list);
 	list_del(&cfqq->cfq_hash);
@@ -478,6 +523,7 @@ retry:
 		} else
 			return NULL;
 
+		cfqq->slice_end = 0;
 		INIT_LIST_HEAD(&cfqq->cfq_hash);
 		INIT_LIST_HEAD(&cfqq->cfq_list);
 		RB_CLEAR_ROOT(&cfqq->sort_list);
@@ -564,7 +610,8 @@ static int cfq_queue_empty(request_queue
 {
 	struct cfq_data *cfqd = q->elevator.elevator_data;
 
-	if (list_empty(cfqd->dispatch) && list_empty(&cfqd->rr_list))
+	if (list_empty(cfqd->dispatch) && list_empty(&cfqd->rr_list)
+					&& list_empty(&cfqd->cur_rr))
 		return 1;
 
 	return 0;
@@ -701,6 +748,7 @@ static int cfq_init(request_queue_t *q, 
 
 	memset(cfqd, 0, sizeof(*cfqd));
 	INIT_LIST_HEAD(&cfqd->rr_list);
+	INIT_LIST_HEAD(&cfqd->cur_rr);
 
 	cfqd->crq_hash = kmalloc(sizeof(struct list_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL);
 	if (!cfqd->crq_hash)
