]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - block/cfq-iosched.c
[ARM] 4755/1: [AT91] NAND update
[linux-2.6-omap-h63xx.git] / block / cfq-iosched.c
index d148ccbc36d17efa03e93d5af68340a77e4db532..13553e015d7203f244db2e411884c56cbee1bc26 100644 (file)
@@ -71,7 +71,7 @@ struct cfq_rb_root {
  * Per block device queue structure
  */
 struct cfq_data {
-       request_queue_t *queue;
+       struct request_queue *queue;
 
        /*
         * rr list of queues with requests and the count of them
@@ -197,7 +197,7 @@ CFQ_CFQQ_FNS(slice_new);
 CFQ_CFQQ_FNS(sync);
 #undef CFQ_CFQQ_FNS
 
-static void cfq_dispatch_insert(request_queue_t *, struct request *);
+static void cfq_dispatch_insert(struct request_queue *, struct request *);
 static struct cfq_queue *cfq_get_queue(struct cfq_data *, int,
                                       struct task_struct *, gfp_t);
 static struct cfq_io_context *cfq_cic_rb_lookup(struct cfq_data *,
@@ -237,7 +237,7 @@ static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
                kblockd_schedule_work(&cfqd->unplug_work);
 }
 
-static int cfq_queue_empty(request_queue_t *q)
+static int cfq_queue_empty(struct request_queue *q)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
 
@@ -623,7 +623,7 @@ cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio)
        return NULL;
 }
 
-static void cfq_activate_request(request_queue_t *q, struct request *rq)
+static void cfq_activate_request(struct request_queue *q, struct request *rq)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
 
@@ -641,7 +641,7 @@ static void cfq_activate_request(request_queue_t *q, struct request *rq)
        cfqd->last_position = rq->hard_sector + rq->hard_nr_sectors;
 }
 
-static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
+static void cfq_deactivate_request(struct request_queue *q, struct request *rq)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
 
@@ -665,7 +665,8 @@ static void cfq_remove_request(struct request *rq)
        }
 }
 
-static int cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
+static int cfq_merge(struct request_queue *q, struct request **req,
+                    struct bio *bio)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct request *__rq;
@@ -679,7 +680,7 @@ static int cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
        return ELEVATOR_NO_MERGE;
 }
 
-static void cfq_merged_request(request_queue_t *q, struct request *req,
+static void cfq_merged_request(struct request_queue *q, struct request *req,
                               int type)
 {
        if (type == ELEVATOR_FRONT_MERGE) {
@@ -690,7 +691,7 @@ static void cfq_merged_request(request_queue_t *q, struct request *req,
 }
 
 static void
-cfq_merged_requests(request_queue_t *q, struct request *rq,
+cfq_merged_requests(struct request_queue *q, struct request *rq,
                    struct request *next)
 {
        /*
@@ -703,7 +704,7 @@ cfq_merged_requests(request_queue_t *q, struct request *rq,
        cfq_remove_request(next);
 }
 
-static int cfq_allow_merge(request_queue_t *q, struct request *rq,
+static int cfq_allow_merge(struct request_queue *q, struct request *rq,
                           struct bio *bio)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
@@ -788,6 +789,20 @@ static inline void cfq_slice_expired(struct cfq_data *cfqd, int timed_out)
                __cfq_slice_expired(cfqd, cfqq, timed_out);
 }
 
+static int start_idle_class_timer(struct cfq_data *cfqd)
+{
+       unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE;
+       unsigned long now = jiffies;
+
+       if (time_before(now, end) &&
+           time_after_eq(now, cfqd->last_end_request)) {
+               mod_timer(&cfqd->idle_class_timer, end);
+               return 1;
+       }
+
+       return 0;
+}
+
 /*
  * Get next queue for service. Unless we have a queue preemption,
  * we'll simply select the first cfqq in the service tree.
@@ -804,19 +819,14 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd)
        cfqq = rb_entry(n, struct cfq_queue, rb_node);
 
        if (cfq_class_idle(cfqq)) {
-               unsigned long end;
-
                /*
                 * if we have idle queues and no rt or be queues had
                 * pending requests, either allow immediate service if
                 * the grace period has passed or arm the idle grace
                 * timer
                 */
-               end = cfqd->last_end_request + CFQ_IDLE_GRACE;
-               if (time_before(jiffies, end)) {
-                       mod_timer(&cfqd->idle_class_timer, end);
+               if (start_idle_class_timer(cfqd))
                        cfqq = NULL;
-               }
        }
 
        return cfqq;
@@ -913,7 +923,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 /*
  * Move request from internal lists to the request queue dispatch list.
  */
-static void cfq_dispatch_insert(request_queue_t *q, struct request *rq)
+static void cfq_dispatch_insert(struct request_queue *q, struct request *rq)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct cfq_queue *cfqq = RQ_CFQQ(rq);
@@ -1093,7 +1103,7 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
        return dispatched;
 }
 
-static int cfq_dispatch_requests(request_queue_t *q, int force)
+static int cfq_dispatch_requests(struct request_queue *q, int force)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct cfq_queue *cfqq;
@@ -1214,7 +1224,7 @@ static void cfq_exit_single_io_context(struct cfq_io_context *cic)
        struct cfq_data *cfqd = cic->key;
 
        if (cfqd) {
-               request_queue_t *q = cfqd->queue;
+               struct request_queue *q = cfqd->queue;
 
                spin_lock_irq(q->queue_lock);
                __cfq_exit_single_io_context(cfqd, cic);
@@ -1442,8 +1452,11 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
                cfqq = *async_cfqq;
        }
 
-       if (!cfqq)
+       if (!cfqq) {
                cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
+               if (!cfqq)
+                       return NULL;
+       }
 
        /*
         * pin the queue now that it's allocated, scheduler exit will prune it
@@ -1775,7 +1788,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
        }
 }
 
-static void cfq_insert_request(request_queue_t *q, struct request *rq)
+static void cfq_insert_request(struct request_queue *q, struct request *rq)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct cfq_queue *cfqq = RQ_CFQQ(rq);
@@ -1789,7 +1802,7 @@ static void cfq_insert_request(request_queue_t *q, struct request *rq)
        cfq_rq_enqueued(cfqd, cfqq, rq);
 }
 
-static void cfq_completed_request(request_queue_t *q, struct request *rq)
+static void cfq_completed_request(struct request_queue *q, struct request *rq)
 {
        struct cfq_queue *cfqq = RQ_CFQQ(rq);
        struct cfq_data *cfqd = cfqq->cfqd;
@@ -1868,7 +1881,7 @@ static inline int __cfq_may_queue(struct cfq_queue *cfqq)
        return ELV_MQUEUE_MAY;
 }
 
-static int cfq_may_queue(request_queue_t *q, int rw)
+static int cfq_may_queue(struct request_queue *q, int rw)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct task_struct *tsk = current;
@@ -1922,7 +1935,7 @@ static void cfq_put_request(struct request *rq)
  * Allocate cfq data structures associated with this request.
  */
 static int
-cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask)
+cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct task_struct *tsk = current;
@@ -1974,7 +1987,7 @@ static void cfq_kick_queue(struct work_struct *work)
 {
        struct cfq_data *cfqd =
                container_of(work, struct cfq_data, unplug_work);
-       request_queue_t *q = cfqd->queue;
+       struct request_queue *q = cfqd->queue;
        unsigned long flags;
 
        spin_lock_irqsave(q->queue_lock, flags);
@@ -2032,17 +2045,14 @@ out_cont:
 static void cfq_idle_class_timer(unsigned long data)
 {
        struct cfq_data *cfqd = (struct cfq_data *) data;
-       unsigned long flags, end;
+       unsigned long flags;
 
        spin_lock_irqsave(cfqd->queue->queue_lock, flags);
 
        /*
         * race with a non-idle queue, reset timer
         */
-       end = cfqd->last_end_request + CFQ_IDLE_GRACE;
-       if (!time_after_eq(jiffies, end))
-               mod_timer(&cfqd->idle_class_timer, end);
-       else
+       if (!start_idle_class_timer(cfqd))
                cfq_schedule_dispatch(cfqd);
 
        spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
@@ -2052,7 +2062,7 @@ static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
 {
        del_timer_sync(&cfqd->idle_slice_timer);
        del_timer_sync(&cfqd->idle_class_timer);
-       blk_sync_queue(cfqd->queue);
+       kblockd_flush_work(&cfqd->unplug_work);
 }
 
 static void cfq_put_async_queues(struct cfq_data *cfqd)
@@ -2064,15 +2074,16 @@ static void cfq_put_async_queues(struct cfq_data *cfqd)
                        cfq_put_queue(cfqd->async_cfqq[0][i]);
                if (cfqd->async_cfqq[1][i])
                        cfq_put_queue(cfqd->async_cfqq[1][i]);
-               if (cfqd->async_idle_cfqq)
-                       cfq_put_queue(cfqd->async_idle_cfqq);
        }
+
+       if (cfqd->async_idle_cfqq)
+               cfq_put_queue(cfqd->async_idle_cfqq);
 }
 
 static void cfq_exit_queue(elevator_t *e)
 {
        struct cfq_data *cfqd = e->elevator_data;
-       request_queue_t *q = cfqd->queue;
+       struct request_queue *q = cfqd->queue;
 
        cfq_shutdown_timer_wq(cfqd);
 
@@ -2098,7 +2109,7 @@ static void cfq_exit_queue(elevator_t *e)
        kfree(cfqd);
 }
 
-static void *cfq_init_queue(request_queue_t *q)
+static void *cfq_init_queue(struct request_queue *q)
 {
        struct cfq_data *cfqd;
 
@@ -2121,6 +2132,7 @@ static void *cfq_init_queue(request_queue_t *q)
 
        INIT_WORK(&cfqd->unplug_work, cfq_kick_queue);
 
+       cfqd->last_end_request = jiffies;
        cfqd->cfq_quantum = cfq_quantum;
        cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
        cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1];
@@ -2267,8 +2279,6 @@ static struct elevator_type iosched_cfq = {
 
 static int __init cfq_init(void)
 {
-       int ret;
-
        /*
         * could be 0 on HZ < 1000 setups
         */
@@ -2280,11 +2290,9 @@ static int __init cfq_init(void)
        if (cfq_slab_setup())
                return -ENOMEM;
 
-       ret = elv_register(&iosched_cfq);
-       if (ret)
-               cfq_slab_kill();
+       elv_register(&iosched_cfq);
 
-       return ret;
+       return 0;
 }
 
 static void __exit cfq_exit(void)