Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=15c31be4d5bd2402c6f5a288d56a24edc9252b71
Commit:     15c31be4d5bd2402c6f5a288d56a24edc9252b71
Parent:     72d3a38ee083a96c09032e608a4c7e047ce26760
Author:     Jens Axboe <[EMAIL PROTECTED]>
AuthorDate: Tue Jul 10 13:43:25 2007 +0200
Committer:  Jens Axboe <[EMAIL PROTECTED]>
CommitDate: Tue Jul 10 13:43:25 2007 +0200

    cfq-iosched: fix async queue behaviour
    
    With the cfq_queue hash removal, we inadvertently got rid of the
    async queue sharing. This was not intentional, in fact CFQ purposely
    shares the async queue per priority level to get good merging for
    async writes.
    
    So put some logic in cfq_get_queue() to track the shared queues.
    
    Signed-off-by: Jens Axboe <[EMAIL PROTECTED]>
---
 block/cfq-iosched.c    |   39 ++++++++++++++++++++++++++++++++++++---
 include/linux/ioprio.h |    6 ++++--
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index baef5fc..e0aa4da 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -92,6 +92,8 @@ struct cfq_data {
        struct cfq_queue *active_queue;
        struct cfq_io_context *active_cic;
 
+       struct cfq_queue *async_cfqq[IOPRIO_BE_NR];
+
        struct timer_list idle_class_timer;
 
        sector_t last_position;
@@ -1351,8 +1353,8 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
 }
 
 static struct cfq_queue *
-cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
-             gfp_t gfp_mask)
+cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync,
+                    struct task_struct *tsk, gfp_t gfp_mask)
 {
        struct cfq_queue *cfqq, *new_cfqq = NULL;
        struct cfq_io_context *cic;
@@ -1405,12 +1407,35 @@ retry:
        if (new_cfqq)
                kmem_cache_free(cfq_pool, new_cfqq);
 
-       atomic_inc(&cfqq->ref);
 out:
        WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq);
        return cfqq;
 }
 
+static struct cfq_queue *
+cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
+             gfp_t gfp_mask)
+{
+       const int ioprio = task_ioprio(tsk);
+       struct cfq_queue *cfqq = NULL;
+
+       if (!is_sync)
+               cfqq = cfqd->async_cfqq[ioprio];
+       if (!cfqq)
+               cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
+
+       /*
+        * pin the queue now that it's allocated, scheduler exit will prune it
+        */
+       if (!is_sync && !cfqd->async_cfqq[ioprio]) {
+               atomic_inc(&cfqq->ref);
+               cfqd->async_cfqq[ioprio] = cfqq;
+       }
+
+       atomic_inc(&cfqq->ref);
+       return cfqq;
+}
+
 /*
  * We drop cfq io contexts lazily, so we may find a dead one.
  */
@@ -2019,6 +2044,7 @@ static void cfq_exit_queue(elevator_t *e)
 {
        struct cfq_data *cfqd = e->elevator_data;
        request_queue_t *q = cfqd->queue;
+       int i;
 
        cfq_shutdown_timer_wq(cfqd);
 
@@ -2035,6 +2061,13 @@ static void cfq_exit_queue(elevator_t *e)
                __cfq_exit_single_io_context(cfqd, cic);
        }
 
+       /*
+        * Put the async queues
+        */
+       for (i = 0; i < IOPRIO_BE_NR; i++)
+               if (cfqd->async_cfqq[i])        
+                       cfq_put_queue(cfqd->async_cfqq[i]);
+
        spin_unlock_irq(q->queue_lock);
 
        cfq_shutdown_timer_wq(cfqd);
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
index 8e2042b..2eaa142 100644
--- a/include/linux/ioprio.h
+++ b/include/linux/ioprio.h
@@ -47,8 +47,10 @@ enum {
 #define IOPRIO_NORM    (4)
 static inline int task_ioprio(struct task_struct *task)
 {
-       WARN_ON(!ioprio_valid(task->ioprio));
-       return IOPRIO_PRIO_DATA(task->ioprio);
+       if (ioprio_valid(task->ioprio))
+               return IOPRIO_PRIO_DATA(task->ioprio);
+
+       return IOPRIO_NORM;
 }
 
 static inline int task_nice_ioprio(struct task_struct *task)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to