vsprintf: factorize "(null)" string
[safe/jmp/linux-2.6] / block / cfq-iosched.c
index 063dcbb..cfb0b2f 100644 (file)
@@ -287,6 +287,7 @@ struct cfq_data {
 
        /* List of cfq groups being managed on this device*/
        struct hlist_head cfqg_list;
+       struct rcu_head rcu;
 };
 
 static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd);
@@ -960,7 +961,7 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
        unsigned int major, minor;
 
        /* Do we need to take this reference */
-       if (!css_tryget(&blkcg->css))
+       if (!blkiocg_css_tryget(blkcg))
                return NULL;;
 
        cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
@@ -993,7 +994,7 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
        hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list);
 
 done:
-       css_put(&blkcg->css);
+       blkiocg_css_put(blkcg);
        return cfqg;
 }
 
@@ -1795,7 +1796,8 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
                return false;
 
        /* We do for queues that were marked with idle window flag. */
-       if (cfq_cfqq_idle_window(cfqq))
+       if (cfq_cfqq_idle_window(cfqq) &&
+          !(blk_queue_nonrot(cfqd->queue) && cfqd->hw_tag))
                return true;
 
        /*
@@ -2366,7 +2368,7 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
 static void cfq_put_queue(struct cfq_queue *cfqq)
 {
        struct cfq_data *cfqd = cfqq->cfqd;
-       struct cfq_group *cfqg;
+       struct cfq_group *cfqg, *orig_cfqg;
 
        BUG_ON(atomic_read(&cfqq->ref) <= 0);
 
@@ -2377,6 +2379,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
        BUG_ON(rb_first(&cfqq->sort_list));
        BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]);
        cfqg = cfqq->cfqg;
+       orig_cfqg = cfqq->orig_cfqg;
 
        if (unlikely(cfqd->active_queue == cfqq)) {
                __cfq_slice_expired(cfqd, cfqq, 0);
@@ -2386,8 +2389,8 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
        BUG_ON(cfq_cfqq_on_rr(cfqq));
        kmem_cache_free(cfq_pool, cfqq);
        cfq_put_cfqg(cfqg);
-       if (cfqq->orig_cfqg)
-               cfq_put_cfqg(cfqq->orig_cfqg);
+       if (orig_cfqg)
+               cfq_put_cfqg(orig_cfqg);
 }
 
 /*
@@ -3314,7 +3317,8 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
                         * only if we processed at least one !rq_noidle request
                         */
                        if (cfqd->serving_type == SYNC_WORKLOAD
-                           || cfqd->noidle_tree_requires_idle)
+                           || cfqd->noidle_tree_requires_idle
+                           || cfqq->cfqg->nr_cfqq == 1)
                                cfq_arm_slice_timer(cfqd);
                }
        }
@@ -3599,6 +3603,11 @@ static void cfq_put_async_queues(struct cfq_data *cfqd)
                cfq_put_queue(cfqd->async_idle_cfqq);
 }
 
+static void cfq_cfqd_free(struct rcu_head *head)
+{
+       kfree(container_of(head, struct cfq_data, rcu));
+}
+
 static void cfq_exit_queue(struct elevator_queue *e)
 {
        struct cfq_data *cfqd = e->elevator_data;
@@ -3628,8 +3637,7 @@ static void cfq_exit_queue(struct elevator_queue *e)
        cfq_shutdown_timer_wq(cfqd);
 
        /* Wait for cfqg->blkg->key accessors to exit their grace periods. */
-       synchronize_rcu();
-       kfree(cfqd);
+       call_rcu(&cfqd->rcu, cfq_cfqd_free);
 }
 
 static void *cfq_init_queue(struct request_queue *q)
@@ -3704,6 +3712,7 @@ static void *cfq_init_queue(struct request_queue *q)
        cfqd->cfq_group_isolation = 0;
        cfqd->hw_tag = -1;
        cfqd->last_end_sync_rq = jiffies;
+       INIT_RCU_HEAD(&cfqd->rcu);
        return cfqd;
 }
 
@@ -3852,6 +3861,17 @@ static struct elevator_type iosched_cfq = {
        .elevator_owner =       THIS_MODULE,
 };
 
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+static struct blkio_policy_type blkio_policy_cfq = {
+       .ops = {
+               .blkio_unlink_group_fn =        cfq_unlink_blkio_group,
+               .blkio_update_group_weight_fn = cfq_update_blkio_group_weight,
+       },
+};
+#else
+static struct blkio_policy_type blkio_policy_cfq;
+#endif
+
 static int __init cfq_init(void)
 {
        /*
@@ -3866,6 +3886,7 @@ static int __init cfq_init(void)
                return -ENOMEM;
 
        elv_register(&iosched_cfq);
+       blkio_policy_register(&blkio_policy_cfq);
 
        return 0;
 }
@@ -3873,6 +3894,7 @@ static int __init cfq_init(void)
 static void __exit cfq_exit(void)
 {
        DECLARE_COMPLETION_ONSTACK(all_gone);
+       blkio_policy_unregister(&blkio_policy_cfq);
        elv_unregister(&iosched_cfq);
        ioc_gone = &all_gone;
        /* ioc_gone's update must be visible before reading ioc_count */