From: Tejun Heo <tj@kernel.org>
To: axboe@kernel.dk, vgoyal@redhat.com
Cc: ctalbott@google.com, rni@google.com,
linux-kernel@vger.kernel.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH 09/10] block, cfq: restructure io_cq creation path for io_context interface cleanup
Date: Sat, 29 Oct 2011 16:49:46 -0700 [thread overview]
Message-ID: <1319932187-7631-10-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1319932187-7631-1-git-send-email-tj@kernel.org>
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>
Cc: Jens Axboe <axboe@kernel.dk>
---
block/cfq-iosched.c | 94 ++++++++++++++++++++--------------------------
include/linux/elevator.h | 2 +
2 files changed, 43 insertions(+), 53 deletions(-)
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index f6d3155..11f49d0 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -59,7 +59,6 @@ static const int cfq_hist_divisor = 4;
#define RQ_CFQG(rq) (struct cfq_group *) ((rq)->elv.priv[1])
static struct kmem_cache *cfq_pool;
-static struct kmem_cache *cfq_icq_pool;
#define CFQ_PRIO_LISTS IOPRIO_BE_NR
#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)
cfq_put_queue(cfqq);
}
+static void cfq_init_icq(struct io_cq *icq)
+{
+ struct cfq_io_cq *cic = icq_to_cic(icq);
+
+ cic->ttime.last_end_request = jiffies;
+}
+
static void cfq_exit_icq(struct io_cq *icq)
{
struct cfq_io_cq *cic = icq_to_cic(icq);
@@ -2723,21 +2729,6 @@ static void cfq_exit_icq(struct io_cq *icq)
}
}
-static struct cfq_io_cq *cfq_alloc_cic(struct cfq_data *cfqd, gfp_t gfp_mask)
-{
- struct cfq_io_cq *cic;
-
- cic = kmem_cache_alloc_node(cfq_icq_pool, gfp_mask | __GFP_ZERO,
- cfqd->queue->node);
- if (cic) {
- cic->ttime.last_end_request = jiffies;
- INIT_LIST_HEAD(&cic->icq.q_node);
- INIT_HLIST_NODE(&cic->icq.ioc_node);
- }
-
- return cic;
-}
-
static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc)
{
struct task_struct *tsk = current;
@@ -2945,64 +2936,62 @@ cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct io_context *ioc,
}
/**
- * cfq_create_cic - create and link a cfq_io_cq
- * @cfqd: cfqd of interest
+ * ioc_create_icq - create and link io_cq
+ * @q: request_queue of interest
* @gfp_mask: allocation mask
*
- * Make sure cfq_io_cq linking %current->io_context and @cfqd exists. If
- * ioc and/or cic doesn't exist, they will be created using @gfp_mask.
+ * Make sure io_cq linking %current->io_context and @q exists. If either
+ * io_context and/or icq don't exist, they will be created using @gfp_mask.
+ *
+ * The caller is responsible for ensuring @ioc won't go away and @q is
+ * alive and will stay alive until this function returns.
*/
-static int cfq_create_cic(struct cfq_data *cfqd, gfp_t gfp_mask)
+static struct io_cq *ioc_create_icq(struct request_queue *q, gfp_t gfp_mask)
{
- struct request_queue *q = cfqd->queue;
- struct io_cq *icq = NULL;
- struct cfq_io_cq *cic;
+ struct elevator_type *et = q->elevator->type;
struct io_context *ioc;
- int ret = -ENOMEM;
-
- might_sleep_if(gfp_mask & __GFP_WAIT);
+ struct io_cq *icq;
/* allocate stuff */
ioc = create_io_context(current, gfp_mask, q->node);
if (!ioc)
- goto out;
+ return NULL;
- cic = cfq_alloc_cic(cfqd, gfp_mask);
- if (!cic)
- goto out;
- icq = &cic->icq;
+ icq = kmem_cache_alloc_node(et->icq_cache, gfp_mask | __GFP_ZERO,
+ q->node);
+ if (!icq)
+ return NULL;
- ret = radix_tree_preload(gfp_mask);
- if (ret)
- goto out;
+ if (radix_tree_preload(gfp_mask) < 0) {
+ kmem_cache_free(et->icq_cache, icq);
+ return NULL;
+ }
icq->ioc = ioc;
- icq->q = cfqd->queue;
+ icq->q = q;
+ INIT_LIST_HEAD(&icq->q_node);
+ INIT_HLIST_NODE(&icq->ioc_node);
/* lock both q and ioc and try to link @icq */
spin_lock_irq(q->queue_lock);
spin_lock(&ioc->lock);
- ret = radix_tree_insert(&ioc->icq_tree, q->id, icq);
- if (likely(!ret)) {
+ if (likely(!radix_tree_insert(&ioc->icq_tree, q->id, icq))) {
hlist_add_head(&icq->ioc_node, &ioc->icq_list);
list_add(&icq->q_node, &q->icq_list);
- icq = NULL;
- } else if (ret == -EEXIST) {
- /* someone else already did it */
- ret = 0;
+ if (et->ops.elevator_init_icq_fn)
+ et->ops.elevator_init_icq_fn(icq);
+ } else {
+ kmem_cache_free(et->icq_cache, icq);
+ icq = ioc_lookup_icq(ioc, q);
+ if (!icq)
+ printk(KERN_ERR "cfq: icq link failed!\n");
}
spin_unlock(&ioc->lock);
spin_unlock_irq(q->queue_lock);
-
radix_tree_preload_end();
-out:
- if (ret)
- printk(KERN_ERR "cfq: icq link failed!\n");
- if (icq)
- kmem_cache_free(cfq_icq_pool, icq);
- return ret;
+ return icq;
}
/**
@@ -3022,7 +3011,6 @@ static struct cfq_io_cq *cfq_get_cic(struct cfq_data *cfqd, gfp_t gfp_mask)
struct request_queue *q = cfqd->queue;
struct cfq_io_cq *cic = NULL;
struct io_context *ioc;
- int err;
lockdep_assert_held(q->queue_lock);
@@ -3037,9 +3025,9 @@ static struct cfq_io_cq *cfq_get_cic(struct cfq_data *cfqd, gfp_t gfp_mask)
/* slow path - unlock, create missing ones and retry */
spin_unlock_irq(q->queue_lock);
- err = cfq_create_cic(cfqd, gfp_mask);
+ cic = icq_to_cic(ioc_create_icq(q, gfp_mask));
spin_lock_irq(q->queue_lock);
- if (err)
+ if (!cic)
return NULL;
}
@@ -3975,6 +3963,7 @@ static struct elevator_type iosched_cfq = {
.elevator_completed_req_fn = cfq_completed_request,
.elevator_former_req_fn = elv_rb_former_request,
.elevator_latter_req_fn = elv_rb_latter_request,
+ .elevator_init_icq_fn = cfq_init_icq,
.elevator_exit_icq_fn = cfq_exit_icq,
.elevator_set_req_fn = cfq_set_request,
.elevator_put_req_fn = cfq_put_request,
@@ -4028,7 +4017,6 @@ static int __init cfq_init(void)
kmem_cache_destroy(cfq_pool);
return ret;
}
- cfq_icq_pool = iosched_cfq.icq_cache;
blkio_policy_register(&blkio_policy_cfq);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 06e4dd56..c8f1e67 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
typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
typedef int (elevator_may_queue_fn) (struct request_queue *, int);
+typedef void (elevator_init_icq_fn) (struct io_cq *);
typedef void (elevator_exit_icq_fn) (struct io_cq *);
typedef int (elevator_set_req_fn) (struct request_queue *, struct request *, gfp_t);
typedef void (elevator_put_req_fn) (struct request *);
@@ -59,6 +60,7 @@ struct elevator_ops
elevator_request_list_fn *elevator_former_req_fn;
elevator_request_list_fn *elevator_latter_req_fn;
+ elevator_init_icq_fn *elevator_init_icq_fn;
elevator_exit_icq_fn *elevator_exit_icq_fn;
elevator_set_req_fn *elevator_set_req_fn;
--
1.7.3.1
next prev parent reply other threads:[~2011-10-29 23:50 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-29 23:49 [PATCHSET block:for-3.2/core] cleanup io_context interface Tejun Heo
2011-10-29 23:49 ` [PATCH 01/10] block, cfq: replace current_io_context() with create_io_context() Tejun Heo
2011-10-29 23:49 ` [PATCH 02/10] block: reorder elevator switch sequence Tejun Heo
2011-10-29 23:49 ` [PATCH 03/10] block: remove elevator_queue->ops Tejun Heo
2011-10-29 23:49 ` [PATCH 04/10] block, cfq: reorganize cfq_io_context into generic and cfq specific parts Tejun Heo
2011-10-29 23:49 ` [PATCH 05/10] block, cfq: move cfqd->icq_list to request_queue and add request->elv.icq Tejun Heo
2011-10-29 23:49 ` [PATCH 06/10] block, cfq: move io_cq lookup to blk-ioc.c Tejun Heo
2011-10-29 23:49 ` [PATCH 07/10] block, cfq: move icq cache management to block core Tejun Heo
2011-10-29 23:49 ` [PATCH 08/10] block, cfq: move io_cq exit/release to blk-ioc.c Tejun Heo
2011-10-29 23:49 ` Tejun Heo [this message]
2011-10-29 23:49 ` [PATCH 10/10] block, cfq: move icq creation and rq->elv.icq association to block core Tejun Heo
2011-11-03 15:08 ` [PATCHSET block:for-3.2/core] cleanup io_context interface Tejun Heo
2011-11-04 9:16 ` Jens Axboe
2011-11-04 14:22 ` Tejun Heo
2011-11-04 14:29 ` Jens Axboe
2011-11-14 17:40 ` Tejun Heo
2011-11-14 17:52 ` Jens Axboe
2011-11-14 17:58 ` Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1319932187-7631-10-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=axboe@kernel.dk \
--cc=ctalbott@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=rni@google.com \
--cc=vgoyal@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.