aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-12-13 18:33:42 -0500
committerJens Axboe <axboe@kernel.dk>2011-12-13 18:33:42 -0500
commit9b84cacd013996f244d85b3d873287c2a8f88658 (patch)
treea11b850f9c8b182a7a8141276244a831aaae5291
parent7e5a8794492e43e9eebb68a98a23be055888ccd0 (diff)
block, cfq: restructure io_cq creation path for io_context interface cleanup
Add elevator_ops->elevator_init_icq_fn() and restructure cfq_create_cic() and rename it to ioc_create_icq(). The new function expects its caller to pass in io_context, uses elevator_type->icq_cache, handles generic init, calls the new elevator operation for elevator specific initialization, and returns pointer to created or looked up icq. This leaves cfq_icq_pool variable without any user. Removed. This prepares for io_context interface cleanup and doesn't introduce any functional difference. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--block/cfq-iosched.c94
-rw-r--r--include/linux/elevator.h2
2 files changed, 43 insertions, 53 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index f6d315551496..11f49d036845 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -59,7 +59,6 @@ static const int cfq_hist_divisor = 4;
59#define RQ_CFQG(rq) (struct cfq_group *) ((rq)->elv.priv[1]) 59#define RQ_CFQG(rq) (struct cfq_group *) ((rq)->elv.priv[1])
60 60
61static struct kmem_cache *cfq_pool; 61static struct kmem_cache *cfq_pool;
62static struct kmem_cache *cfq_icq_pool;
63 62
64#define CFQ_PRIO_LISTS IOPRIO_BE_NR 63#define CFQ_PRIO_LISTS IOPRIO_BE_NR
65#define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) 64#define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
@@ -2707,6 +2706,13 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
2707 cfq_put_queue(cfqq); 2706 cfq_put_queue(cfqq);
2708} 2707}
2709 2708
2709static void cfq_init_icq(struct io_cq *icq)
2710{
2711 struct cfq_io_cq *cic = icq_to_cic(icq);
2712
2713 cic->ttime.last_end_request = jiffies;
2714}
2715
2710static void cfq_exit_icq(struct io_cq *icq) 2716static void cfq_exit_icq(struct io_cq *icq)
2711{ 2717{
2712 struct cfq_io_cq *cic = icq_to_cic(icq); 2718 struct cfq_io_cq *cic = icq_to_cic(icq);
@@ -2723,21 +2729,6 @@ static void cfq_exit_icq(struct io_cq *icq)
2723 } 2729 }
2724} 2730}
2725 2731
2726static struct cfq_io_cq *cfq_alloc_cic(struct cfq_data *cfqd, gfp_t gfp_mask)
2727{
2728 struct cfq_io_cq *cic;
2729
2730 cic = kmem_cache_alloc_node(cfq_icq_pool, gfp_mask | __GFP_ZERO,
2731 cfqd->queue->node);
2732 if (cic) {
2733 cic->ttime.last_end_request = jiffies;
2734 INIT_LIST_HEAD(&cic->icq.q_node);
2735 INIT_HLIST_NODE(&cic->icq.ioc_node);
2736 }
2737
2738 return cic;
2739}
2740
2741static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc) 2732static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc)
2742{ 2733{
2743 struct task_struct *tsk = current; 2734 struct task_struct *tsk = current;
@@ -2945,64 +2936,62 @@ cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct io_context *ioc,
2945} 2936}
2946 2937
2947/** 2938/**
2948 * cfq_create_cic - create and link a cfq_io_cq 2939 * ioc_create_icq - create and link io_cq
2949 * @cfqd: cfqd of interest 2940 * @q: request_queue of interest
2950 * @gfp_mask: allocation mask 2941 * @gfp_mask: allocation mask
2951 * 2942 *
2952 * Make sure cfq_io_cq linking %current->io_context and @cfqd exists. If 2943 * Make sure io_cq linking %current->io_context and @q exists. If either
2953 * ioc and/or cic doesn't exist, they will be created using @gfp_mask. 2944 * io_context and/or icq don't exist, they will be created using @gfp_mask.
2945 *
2946 * The caller is responsible for ensuring @ioc won't go away and @q is
2947 * alive and will stay alive until this function returns.
2954 */ 2948 */
2955static int cfq_create_cic(struct cfq_data *cfqd, gfp_t gfp_mask) 2949static struct io_cq *ioc_create_icq(struct request_queue *q, gfp_t gfp_mask)
2956{ 2950{
2957 struct request_queue *q = cfqd->queue; 2951 struct elevator_type *et = q->elevator->type;
2958 struct io_cq *icq = NULL;
2959 struct cfq_io_cq *cic;
2960 struct io_context *ioc; 2952 struct io_context *ioc;
2961 int ret = -ENOMEM; 2953 struct io_cq *icq;
2962
2963 might_sleep_if(gfp_mask & __GFP_WAIT);
2964 2954
2965 /* allocate stuff */ 2955 /* allocate stuff */
2966 ioc = create_io_context(current, gfp_mask, q->node); 2956 ioc = create_io_context(current, gfp_mask, q->node);
2967 if (!ioc) 2957 if (!ioc)
2968 goto out; 2958 return NULL;
2969 2959
2970 cic = cfq_alloc_cic(cfqd, gfp_mask); 2960 icq = kmem_cache_alloc_node(et->icq_cache, gfp_mask | __GFP_ZERO,
2971 if (!cic) 2961 q->node);
2972 goto out; 2962 if (!icq)
2973 icq = &cic->icq; 2963 return NULL;
2974 2964
2975 ret = radix_tree_preload(gfp_mask); 2965 if (radix_tree_preload(gfp_mask) < 0) {
2976 if (ret) 2966 kmem_cache_free(et->icq_cache, icq);
2977 goto out; 2967 return NULL;
2968 }
2978 2969
2979 icq->ioc = ioc; 2970 icq->ioc = ioc;
2980 icq->q = cfqd->queue; 2971 icq->q = q;
2972 INIT_LIST_HEAD(&icq->q_node);
2973 INIT_HLIST_NODE(&icq->ioc_node);
2981 2974
2982 /* lock both q and ioc and try to link @icq */ 2975 /* lock both q and ioc and try to link @icq */
2983 spin_lock_irq(q->queue_lock); 2976 spin_lock_irq(q->queue_lock);
2984 spin_lock(&ioc->lock); 2977 spin_lock(&ioc->lock);
2985 2978
2986 ret = radix_tree_insert(&ioc->icq_tree, q->id, icq); 2979 if (likely(!radix_tree_insert(&ioc->icq_tree, q->id, icq))) {
2987 if (likely(!ret)) {
2988 hlist_add_head(&icq->ioc_node, &ioc->icq_list); 2980 hlist_add_head(&icq->ioc_node, &ioc->icq_list);
2989 list_add(&icq->q_node, &q->icq_list); 2981 list_add(&icq->q_node, &q->icq_list);
2990 icq = NULL; 2982 if (et->ops.elevator_init_icq_fn)
2991 } else if (ret == -EEXIST) { 2983 et->ops.elevator_init_icq_fn(icq);
2992 /* someone else already did it */ 2984 } else {
2993 ret = 0; 2985 kmem_cache_free(et->icq_cache, icq);
2986 icq = ioc_lookup_icq(ioc, q);
2987 if (!icq)
2988 printk(KERN_ERR "cfq: icq link failed!\n");
2994 } 2989 }
2995 2990
2996 spin_unlock(&ioc->lock); 2991 spin_unlock(&ioc->lock);
2997 spin_unlock_irq(q->queue_lock); 2992 spin_unlock_irq(q->queue_lock);
2998
2999 radix_tree_preload_end(); 2993 radix_tree_preload_end();
3000out: 2994 return icq;
3001 if (ret)
3002 printk(KERN_ERR "cfq: icq link failed!\n");
3003 if (icq)
3004 kmem_cache_free(cfq_icq_pool, icq);
3005 return ret;
3006} 2995}
3007 2996
3008/** 2997/**
@@ -3022,7 +3011,6 @@ static struct cfq_io_cq *cfq_get_cic(struct cfq_data *cfqd, gfp_t gfp_mask)
3022 struct request_queue *q = cfqd->queue; 3011 struct request_queue *q = cfqd->queue;
3023 struct cfq_io_cq *cic = NULL; 3012 struct cfq_io_cq *cic = NULL;
3024 struct io_context *ioc; 3013 struct io_context *ioc;
3025 int err;
3026 3014
3027 lockdep_assert_held(q->queue_lock); 3015 lockdep_assert_held(q->queue_lock);
3028 3016
@@ -3037,9 +3025,9 @@ static struct cfq_io_cq *cfq_get_cic(struct cfq_data *cfqd, gfp_t gfp_mask)
3037 3025
3038 /* slow path - unlock, create missing ones and retry */ 3026 /* slow path - unlock, create missing ones and retry */
3039 spin_unlock_irq(q->queue_lock); 3027 spin_unlock_irq(q->queue_lock);
3040 err = cfq_create_cic(cfqd, gfp_mask); 3028 cic = icq_to_cic(ioc_create_icq(q, gfp_mask));
3041 spin_lock_irq(q->queue_lock); 3029 spin_lock_irq(q->queue_lock);
3042 if (err) 3030 if (!cic)
3043 return NULL; 3031 return NULL;
3044 } 3032 }
3045 3033
@@ -3975,6 +3963,7 @@ static struct elevator_type iosched_cfq = {
3975 .elevator_completed_req_fn = cfq_completed_request, 3963 .elevator_completed_req_fn = cfq_completed_request,
3976 .elevator_former_req_fn = elv_rb_former_request, 3964 .elevator_former_req_fn = elv_rb_former_request,
3977 .elevator_latter_req_fn = elv_rb_latter_request, 3965 .elevator_latter_req_fn = elv_rb_latter_request,
3966 .elevator_init_icq_fn = cfq_init_icq,
3978 .elevator_exit_icq_fn = cfq_exit_icq, 3967 .elevator_exit_icq_fn = cfq_exit_icq,
3979 .elevator_set_req_fn = cfq_set_request, 3968 .elevator_set_req_fn = cfq_set_request,
3980 .elevator_put_req_fn = cfq_put_request, 3969 .elevator_put_req_fn = cfq_put_request,
@@ -4028,7 +4017,6 @@ static int __init cfq_init(void)
4028 kmem_cache_destroy(cfq_pool); 4017 kmem_cache_destroy(cfq_pool);
4029 return ret; 4018 return ret;
4030 } 4019 }
4031 cfq_icq_pool = iosched_cfq.icq_cache;
4032 4020
4033 blkio_policy_register(&blkio_policy_cfq); 4021 blkio_policy_register(&blkio_policy_cfq);
4034 4022
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 06e4dd568717..c8f1e67a8ebe 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -26,6 +26,7 @@ typedef struct request *(elevator_request_list_fn) (struct request_queue *, stru
26typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *); 26typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
27typedef int (elevator_may_queue_fn) (struct request_queue *, int); 27typedef int (elevator_may_queue_fn) (struct request_queue *, int);
28 28
29typedef void (elevator_init_icq_fn) (struct io_cq *);
29typedef void (elevator_exit_icq_fn) (struct io_cq *); 30typedef void (elevator_exit_icq_fn) (struct io_cq *);
30typedef int (elevator_set_req_fn) (struct request_queue *, struct request *, gfp_t); 31typedef int (elevator_set_req_fn) (struct request_queue *, struct request *, gfp_t);
31typedef void (elevator_put_req_fn) (struct request *); 32typedef void (elevator_put_req_fn) (struct request *);
@@ -59,6 +60,7 @@ struct elevator_ops
59 elevator_request_list_fn *elevator_former_req_fn; 60 elevator_request_list_fn *elevator_former_req_fn;
60 elevator_request_list_fn *elevator_latter_req_fn; 61 elevator_request_list_fn *elevator_latter_req_fn;
61 62
63 elevator_init_icq_fn *elevator_init_icq_fn;
62 elevator_exit_icq_fn *elevator_exit_icq_fn; 64 elevator_exit_icq_fn *elevator_exit_icq_fn;
63 65
64 elevator_set_req_fn *elevator_set_req_fn; 66 elevator_set_req_fn *elevator_set_req_fn;