diff options
author | Tejun Heo <tj@kernel.org> | 2011-12-13 18:33:38 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2011-12-13 18:33:38 -0500 |
commit | 283287a52e3c3f7f8f9da747f4b8c5202740d776 (patch) | |
tree | b5b145bcdcefc24deb68cd91bb16582286dce171 | |
parent | 09ac46c429464c919d04bb737b27edd84d944f02 (diff) |
block, cfq: misc updates to cfq_io_context
Make the following changes to prepare for ioc/cic management cleanup.
* Add cic->q so that ioc can determine the associated queue without
querying cfq. This will eventually replace ->key.
* Factor out cfq_release_cic() from cic_free_func(). This function
assumes that the caller handled locking.
* Rename __cfq_exit_single_io_context() to cfq_exit_cic() and make it
take only @cic.
* Restructure cfq_cic_link() for future updates.
This patch doesn't introduce any functional changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | block/cfq-iosched.c | 58 | ||||
-rw-r--r-- | include/linux/iocontext.h | 1 |
2 files changed, 33 insertions, 26 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index d42d89ccce1b..a612ca65f371 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -2709,21 +2709,26 @@ static void cfq_cic_free(struct cfq_io_context *cic) | |||
2709 | call_rcu(&cic->rcu_head, cfq_cic_free_rcu); | 2709 | call_rcu(&cic->rcu_head, cfq_cic_free_rcu); |
2710 | } | 2710 | } |
2711 | 2711 | ||
2712 | static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) | 2712 | static void cfq_release_cic(struct cfq_io_context *cic) |
2713 | { | 2713 | { |
2714 | unsigned long flags; | 2714 | struct io_context *ioc = cic->ioc; |
2715 | unsigned long dead_key = (unsigned long) cic->key; | 2715 | unsigned long dead_key = (unsigned long) cic->key; |
2716 | 2716 | ||
2717 | BUG_ON(!(dead_key & CIC_DEAD_KEY)); | 2717 | BUG_ON(!(dead_key & CIC_DEAD_KEY)); |
2718 | |||
2719 | spin_lock_irqsave(&ioc->lock, flags); | ||
2720 | radix_tree_delete(&ioc->radix_root, dead_key >> CIC_DEAD_INDEX_SHIFT); | 2718 | radix_tree_delete(&ioc->radix_root, dead_key >> CIC_DEAD_INDEX_SHIFT); |
2721 | hlist_del_rcu(&cic->cic_list); | 2719 | hlist_del_rcu(&cic->cic_list); |
2722 | spin_unlock_irqrestore(&ioc->lock, flags); | ||
2723 | |||
2724 | cfq_cic_free(cic); | 2720 | cfq_cic_free(cic); |
2725 | } | 2721 | } |
2726 | 2722 | ||
2723 | static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) | ||
2724 | { | ||
2725 | unsigned long flags; | ||
2726 | |||
2727 | spin_lock_irqsave(&ioc->lock, flags); | ||
2728 | cfq_release_cic(cic); | ||
2729 | spin_unlock_irqrestore(&ioc->lock, flags); | ||
2730 | } | ||
2731 | |||
2727 | /* | 2732 | /* |
2728 | * Must be called with rcu_read_lock() held or preemption otherwise disabled. | 2733 | * Must be called with rcu_read_lock() held or preemption otherwise disabled. |
2729 | * Only two callers of this - ->dtor() which is called with the rcu_read_lock(), | 2734 | * Only two callers of this - ->dtor() which is called with the rcu_read_lock(), |
@@ -2773,9 +2778,9 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
2773 | cfq_put_queue(cfqq); | 2778 | cfq_put_queue(cfqq); |
2774 | } | 2779 | } |
2775 | 2780 | ||
2776 | static void __cfq_exit_single_io_context(struct cfq_data *cfqd, | 2781 | static void cfq_exit_cic(struct cfq_io_context *cic) |
2777 | struct cfq_io_context *cic) | ||
2778 | { | 2782 | { |
2783 | struct cfq_data *cfqd = cic_to_cfqd(cic); | ||
2779 | struct io_context *ioc = cic->ioc; | 2784 | struct io_context *ioc = cic->ioc; |
2780 | 2785 | ||
2781 | list_del_init(&cic->queue_list); | 2786 | list_del_init(&cic->queue_list); |
@@ -2823,7 +2828,7 @@ static void cfq_exit_single_io_context(struct io_context *ioc, | |||
2823 | */ | 2828 | */ |
2824 | smp_read_barrier_depends(); | 2829 | smp_read_barrier_depends(); |
2825 | if (cic->key == cfqd) | 2830 | if (cic->key == cfqd) |
2826 | __cfq_exit_single_io_context(cfqd, cic); | 2831 | cfq_exit_cic(cic); |
2827 | 2832 | ||
2828 | spin_unlock_irqrestore(q->queue_lock, flags); | 2833 | spin_unlock_irqrestore(q->queue_lock, flags); |
2829 | } | 2834 | } |
@@ -3161,28 +3166,29 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, | |||
3161 | int ret; | 3166 | int ret; |
3162 | 3167 | ||
3163 | ret = radix_tree_preload(gfp_mask); | 3168 | ret = radix_tree_preload(gfp_mask); |
3164 | if (!ret) { | 3169 | if (ret) |
3165 | cic->ioc = ioc; | 3170 | goto out; |
3166 | cic->key = cfqd; | ||
3167 | 3171 | ||
3168 | spin_lock_irqsave(&ioc->lock, flags); | 3172 | cic->ioc = ioc; |
3169 | ret = radix_tree_insert(&ioc->radix_root, cfqd->queue->id, cic); | 3173 | cic->key = cfqd; |
3170 | if (!ret) | 3174 | cic->q = cfqd->queue; |
3171 | hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list); | 3175 | |
3172 | spin_unlock_irqrestore(&ioc->lock, flags); | 3176 | spin_lock_irqsave(&ioc->lock, flags); |
3177 | ret = radix_tree_insert(&ioc->radix_root, cfqd->queue->id, cic); | ||
3178 | if (!ret) | ||
3179 | hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list); | ||
3180 | spin_unlock_irqrestore(&ioc->lock, flags); | ||
3173 | 3181 | ||
3174 | radix_tree_preload_end(); | 3182 | radix_tree_preload_end(); |
3175 | 3183 | ||
3176 | if (!ret) { | 3184 | if (!ret) { |
3177 | spin_lock_irqsave(cfqd->queue->queue_lock, flags); | 3185 | spin_lock_irqsave(cfqd->queue->queue_lock, flags); |
3178 | list_add(&cic->queue_list, &cfqd->cic_list); | 3186 | list_add(&cic->queue_list, &cfqd->cic_list); |
3179 | spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); | 3187 | spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); |
3180 | } | ||
3181 | } | 3188 | } |
3182 | 3189 | out: | |
3183 | if (ret) | 3190 | if (ret) |
3184 | printk(KERN_ERR "cfq: cic link failed!\n"); | 3191 | printk(KERN_ERR "cfq: cic link failed!\n"); |
3185 | |||
3186 | return ret; | 3192 | return ret; |
3187 | } | 3193 | } |
3188 | 3194 | ||
@@ -3922,7 +3928,7 @@ static void cfq_exit_queue(struct elevator_queue *e) | |||
3922 | struct cfq_io_context, | 3928 | struct cfq_io_context, |
3923 | queue_list); | 3929 | queue_list); |
3924 | 3930 | ||
3925 | __cfq_exit_single_io_context(cfqd, cic); | 3931 | cfq_exit_cic(cic); |
3926 | } | 3932 | } |
3927 | 3933 | ||
3928 | cfq_put_async_queues(cfqd); | 3934 | cfq_put_async_queues(cfqd); |
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index 28bb621ef5a2..079aea8fd8a8 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h | |||
@@ -15,6 +15,7 @@ struct cfq_ttime { | |||
15 | 15 | ||
16 | struct cfq_io_context { | 16 | struct cfq_io_context { |
17 | void *key; | 17 | void *key; |
18 | struct request_queue *q; | ||
18 | 19 | ||
19 | struct cfq_queue *cfqq[2]; | 20 | struct cfq_queue *cfqq[2]; |
20 | 21 | ||