* blk-mq updates, V3
@ 2014-04-02 14:57 Christoph Hellwig
2014-04-02 14:57 ` [PATCH 1/5] blk-mq: initialize resid_len Christoph Hellwig
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Christoph Hellwig @ 2014-04-02 14:57 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi
The first two patches are unchanged from the last two iterations of
the series.
Patches 3 and 4 are new: 3 is a preparation for 4 and other future work,
and patch 4 makes sure that drivers don't have to implement special
workarounds for the magic flush request. Patch 5 is an updated version
of the earlier init/exit_request versions which should make everyone
happy now as there are no special NULL hardware contexts or negative
request numbers due to patch 4 sorting out the flush_rq mess.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/5] blk-mq: initialize resid_len
2014-04-02 14:57 blk-mq updates, V3 Christoph Hellwig
@ 2014-04-02 14:57 ` Christoph Hellwig
2014-04-02 14:57 ` [PATCH 2/5] blk-mq: fix blk_mq_end_io_partial Christoph Hellwig
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2014-04-02 14:57 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-mq.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index b1bcc61..44f738e 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -350,6 +350,8 @@ static void blk_mq_start_request(struct request *rq, bool last)
trace_block_rq_issue(q, rq);
+ rq->resid_len = blk_rq_bytes(rq);
+
/*
* Just mark start time and set the started bit. Due to memory
* ordering, we know we'll see the correct deadline as long as
--
1.7.10.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/5] blk-mq: fix blk_mq_end_io_partial
2014-04-02 14:57 blk-mq updates, V3 Christoph Hellwig
2014-04-02 14:57 ` [PATCH 1/5] blk-mq: initialize resid_len Christoph Hellwig
@ 2014-04-02 14:57 ` Christoph Hellwig
2014-04-02 14:57 ` [PATCH 3/5] blk-mq: do not initialize req->special Christoph Hellwig
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2014-04-02 14:57 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi
We need to pass the actual nr_bytes instead of all bytes in the request.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-mq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 44f738e..4274ee0 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -285,7 +285,7 @@ void blk_mq_free_request(struct request *rq)
bool blk_mq_end_io_partial(struct request *rq, int error, unsigned int nr_bytes)
{
- if (blk_update_request(rq, error, blk_rq_bytes(rq)))
+ if (blk_update_request(rq, error, nr_bytes))
return true;
blk_account_io_done(rq);
--
1.7.10.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/5] blk-mq: do not initialize req->special
2014-04-02 14:57 blk-mq updates, V3 Christoph Hellwig
2014-04-02 14:57 ` [PATCH 1/5] blk-mq: initialize resid_len Christoph Hellwig
2014-04-02 14:57 ` [PATCH 2/5] blk-mq: fix blk_mq_end_io_partial Christoph Hellwig
@ 2014-04-02 14:57 ` Christoph Hellwig
2014-04-02 14:57 ` [PATCH 4/5] blk-mq: make ->flush_rq fully transparent to drivers Christoph Hellwig
2014-04-02 14:57 ` [PATCH 5/5] blk-mq: add ->init_request and ->exit_request methods Christoph Hellwig
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2014-04-02 14:57 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi
Drivers can reach their private data easily using the blk_mq_rq_to_pdu
helper and don't need req->special. By not initializing it code can
be simplified nicely, and we also shave off a few more instructions from
the I/O path.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-flush.c | 10 ++--------
block/blk-mq.c | 15 ++-------------
block/blk-mq.h | 1 -
drivers/block/null_blk.c | 4 ++--
drivers/block/virtio_blk.c | 6 +++---
5 files changed, 9 insertions(+), 27 deletions(-)
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 43e6b47..9a0c427 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -306,22 +306,16 @@ static bool blk_kick_flush(struct request_queue *q)
*/
q->flush_pending_idx ^= 1;
+ blk_rq_init(q, q->flush_rq);
if (q->mq_ops) {
- struct blk_mq_ctx *ctx = first_rq->mq_ctx;
- struct blk_mq_hw_ctx *hctx = q->mq_ops->map_queue(q, ctx->cpu);
-
- blk_mq_rq_init(hctx, q->flush_rq);
- q->flush_rq->mq_ctx = ctx;
-
/*
* Reuse the tag value from the fist waiting request,
* with blk-mq the tag is generated during request
* allocation and drivers can rely on it being inside
* the range they asked for.
*/
+ q->flush_rq->mq_ctx = first_rq->mq_ctx;
q->flush_rq->tag = first_rq->tag;
- } else {
- blk_rq_init(q, q->flush_rq);
}
q->flush_rq->cmd_type = REQ_TYPE_FS;
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 4274ee0..871acd6 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -248,24 +248,13 @@ struct request *blk_mq_alloc_reserved_request(struct request_queue *q, int rw,
}
EXPORT_SYMBOL(blk_mq_alloc_reserved_request);
-/*
- * Re-init and set pdu, if we have it
- */
-void blk_mq_rq_init(struct blk_mq_hw_ctx *hctx, struct request *rq)
-{
- blk_rq_init(hctx->queue, rq);
-
- if (hctx->cmd_size)
- rq->special = blk_mq_rq_to_pdu(rq);
-}
-
static void __blk_mq_free_request(struct blk_mq_hw_ctx *hctx,
struct blk_mq_ctx *ctx, struct request *rq)
{
const int tag = rq->tag;
struct request_queue *q = rq->q;
- blk_mq_rq_init(hctx, rq);
+ blk_rq_init(hctx->queue, rq);
blk_mq_put_tag(hctx->tags, tag);
blk_mq_queue_exit(q);
@@ -1139,7 +1128,7 @@ static int blk_mq_init_rq_map(struct blk_mq_hw_ctx *hctx,
left -= to_do * rq_size;
for (j = 0; j < to_do; j++) {
hctx->rqs[i] = p;
- blk_mq_rq_init(hctx, hctx->rqs[i]);
+ blk_rq_init(hctx->queue, hctx->rqs[i]);
p += rq_size;
i++;
}
diff --git a/block/blk-mq.h b/block/blk-mq.h
index ebbe6ba..238379a 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -27,7 +27,6 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async);
void blk_mq_init_flush(struct request_queue *q);
void blk_mq_drain_queue(struct request_queue *q);
void blk_mq_free_queue(struct request_queue *q);
-void blk_mq_rq_init(struct blk_mq_hw_ctx *hctx, struct request *rq);
/*
* CPU hotplug helpers
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index 091b9ea..71df69d 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -226,7 +226,7 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd)
static void null_softirq_done_fn(struct request *rq)
{
- end_cmd(rq->special);
+ end_cmd(blk_mq_rq_to_pdu(rq));
}
static inline void null_handle_cmd(struct nullb_cmd *cmd)
@@ -311,7 +311,7 @@ static void null_request_fn(struct request_queue *q)
static int null_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq)
{
- struct nullb_cmd *cmd = rq->special;
+ struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq);
cmd->rq = rq;
cmd->nq = hctx->driver_data;
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 0eace43..11e8f4b 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -112,7 +112,7 @@ static int __virtblk_add_req(struct virtqueue *vq,
static inline void virtblk_request_done(struct request *req)
{
- struct virtblk_req *vbr = req->special;
+ struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
int error = virtblk_result(vbr);
if (req->cmd_type == REQ_TYPE_BLOCK_PC) {
@@ -154,7 +154,7 @@ static void virtblk_done(struct virtqueue *vq)
static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req)
{
struct virtio_blk *vblk = hctx->queue->queuedata;
- struct virtblk_req *vbr = req->special;
+ struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
unsigned long flags;
unsigned int num;
const bool last = (req->cmd_flags & REQ_END) != 0;
@@ -494,7 +494,7 @@ static int virtblk_init_vbr(void *data, struct blk_mq_hw_ctx *hctx,
struct request *rq, unsigned int nr)
{
struct virtio_blk *vblk = data;
- struct virtblk_req *vbr = rq->special;
+ struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq);
sg_init_table(vbr->sg, vblk->sg_elems);
return 0;
--
1.7.10.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/5] blk-mq: make ->flush_rq fully transparent to drivers
2014-04-02 14:57 blk-mq updates, V3 Christoph Hellwig
` (2 preceding siblings ...)
2014-04-02 14:57 ` [PATCH 3/5] blk-mq: do not initialize req->special Christoph Hellwig
@ 2014-04-02 14:57 ` Christoph Hellwig
2014-04-02 14:57 ` [PATCH 5/5] blk-mq: add ->init_request and ->exit_request methods Christoph Hellwig
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2014-04-02 14:57 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi
Drivers shouldn't have to care about the block layer setting aside a
request to implement the flush state machine. We already override the
mq context and tag to make it more transparent, but so far haven't deal
with the driver private data in the request. Make sure to override this
as well, and while we're at it add a proper helper sitting in blk-mq.c
that implements the full impersonation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-flush.c | 12 ++----------
block/blk-mq.c | 20 ++++++++++++++++++++
block/blk-mq.h | 2 ++
3 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 9a0c427..b218f61 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -307,16 +307,8 @@ static bool blk_kick_flush(struct request_queue *q)
q->flush_pending_idx ^= 1;
blk_rq_init(q, q->flush_rq);
- if (q->mq_ops) {
- /*
- * Reuse the tag value from the fist waiting request,
- * with blk-mq the tag is generated during request
- * allocation and drivers can rely on it being inside
- * the range they asked for.
- */
- q->flush_rq->mq_ctx = first_rq->mq_ctx;
- q->flush_rq->tag = first_rq->tag;
- }
+ if (q->mq_ops)
+ blk_mq_clone_flush_request(q->flush_rq, first_rq);
q->flush_rq->cmd_type = REQ_TYPE_FS;
q->flush_rq->cmd_flags = WRITE_FLUSH | REQ_FLUSH_SEQ;
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 871acd6..289b7e5 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -272,6 +272,26 @@ void blk_mq_free_request(struct request *rq)
__blk_mq_free_request(hctx, ctx, rq);
}
+/*
+ * Clone all relevant state from a request that has been put on hold in
+ * the flush state machine into the preallocated flush request that hangs
+ * off the request queue.
+ *
+ * For a driver the flush request should be invisible, that's why we are
+ * impersonating the original request here.
+ */
+void blk_mq_clone_flush_request(struct request *flush_rq,
+ struct request *orig_rq)
+{
+ struct blk_mq_hw_ctx *hctx =
+ orig_rq->q->mq_ops->map_queue(orig_rq->q, orig_rq->mq_ctx->cpu);
+
+ flush_rq->mq_ctx = orig_rq->mq_ctx;
+ flush_rq->tag = orig_rq->tag;
+ memcpy(blk_mq_rq_to_pdu(flush_rq), blk_mq_rq_to_pdu(orig_rq),
+ hctx->cmd_size);
+}
+
bool blk_mq_end_io_partial(struct request *rq, int error, unsigned int nr_bytes)
{
if (blk_update_request(rq, error, nr_bytes))
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 238379a..7964dad 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -27,6 +27,8 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async);
void blk_mq_init_flush(struct request_queue *q);
void blk_mq_drain_queue(struct request_queue *q);
void blk_mq_free_queue(struct request_queue *q);
+void blk_mq_clone_flush_request(struct request *flush_rq,
+ struct request *orig_rq);
/*
* CPU hotplug helpers
--
1.7.10.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 5/5] blk-mq: add ->init_request and ->exit_request methods
2014-04-02 14:57 blk-mq updates, V3 Christoph Hellwig
` (3 preceding siblings ...)
2014-04-02 14:57 ` [PATCH 4/5] blk-mq: make ->flush_rq fully transparent to drivers Christoph Hellwig
@ 2014-04-02 14:57 ` Christoph Hellwig
4 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2014-04-02 14:57 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel, linux-scsi
The current blk_mq_init_commands/blk_mq_free_commands interface has a two
problems:
1) Because only the constructor is passed to blk_mq_init_commands there
is no easy way to clean up when a comman initialization failed. The
current code simply leaks the allocations done in the constructor.
2) There is no good place to call blk_mq_free_commands: before
blk_cleanup_queue there is no guarantee that all outstanding commands
have completed, so we can't free them yet. After blk_cleanup_queue
the queue has usually been freed. This can be worked around by
grabbing an unconditional reference before calling blk_cleanup_queue
and dropping it after blk_mq_free_commands is done, although that's
not exatly pretty and driver writers are guaranteed to get it wrong
sooner or later.
Both issues are easily fixed by making the request constructor and
destructor normal blk_mq_ops methods.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-mq.c | 105 ++++++++++++++------------------------------
drivers/block/virtio_blk.c | 23 +++++-----
include/linux/blk-mq.h | 14 +++++-
3 files changed, 55 insertions(+), 87 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 289b7e5..e0b65c4 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1005,74 +1005,20 @@ static void blk_mq_hctx_notify(void *data, unsigned long action,
blk_mq_put_ctx(ctx);
}
-static int blk_mq_init_hw_commands(struct blk_mq_hw_ctx *hctx,
- int (*init)(void *, struct blk_mq_hw_ctx *,
- struct request *, unsigned int),
- void *data)
+static void blk_mq_free_rq_map(struct blk_mq_hw_ctx *hctx, void *driver_data)
{
- unsigned int i;
- int ret = 0;
-
- for (i = 0; i < hctx->queue_depth; i++) {
- struct request *rq = hctx->rqs[i];
-
- ret = init(data, hctx, rq, i);
- if (ret)
- break;
- }
-
- return ret;
-}
-
-int blk_mq_init_commands(struct request_queue *q,
- int (*init)(void *, struct blk_mq_hw_ctx *,
- struct request *, unsigned int),
- void *data)
-{
- struct blk_mq_hw_ctx *hctx;
- unsigned int i;
- int ret = 0;
-
- queue_for_each_hw_ctx(q, hctx, i) {
- ret = blk_mq_init_hw_commands(hctx, init, data);
- if (ret)
- break;
- }
-
- return ret;
-}
-EXPORT_SYMBOL(blk_mq_init_commands);
-
-static void blk_mq_free_hw_commands(struct blk_mq_hw_ctx *hctx,
- void (*free)(void *, struct blk_mq_hw_ctx *,
- struct request *, unsigned int),
- void *data)
-{
- unsigned int i;
+ struct page *page;
- for (i = 0; i < hctx->queue_depth; i++) {
- struct request *rq = hctx->rqs[i];
+ if (hctx->rqs && hctx->queue->mq_ops->exit_request) {
+ int i;
- free(data, hctx, rq, i);
+ for (i = 0; i < hctx->queue_depth; i++) {
+ if (!hctx->rqs[i])
+ continue;
+ hctx->queue->mq_ops->exit_request(driver_data, hctx,
+ hctx->rqs[i], i);
+ }
}
-}
-
-void blk_mq_free_commands(struct request_queue *q,
- void (*free)(void *, struct blk_mq_hw_ctx *,
- struct request *, unsigned int),
- void *data)
-{
- struct blk_mq_hw_ctx *hctx;
- unsigned int i;
-
- queue_for_each_hw_ctx(q, hctx, i)
- blk_mq_free_hw_commands(hctx, free, data);
-}
-EXPORT_SYMBOL(blk_mq_free_commands);
-
-static void blk_mq_free_rq_map(struct blk_mq_hw_ctx *hctx)
-{
- struct page *page;
while (!list_empty(&hctx->page_list)) {
page = list_first_entry(&hctx->page_list, struct page, lru);
@@ -1097,10 +1043,12 @@ static size_t order_to_size(unsigned int order)
}
static int blk_mq_init_rq_map(struct blk_mq_hw_ctx *hctx,
- unsigned int reserved_tags, int node)
+ struct blk_mq_reg *reg, void *driver_data, int node)
{
+ unsigned int reserved_tags = reg->reserved_tags;
unsigned int i, j, entries_per_page, max_order = 4;
size_t rq_size, left;
+ int error;
INIT_LIST_HEAD(&hctx->page_list);
@@ -1149,14 +1097,23 @@ static int blk_mq_init_rq_map(struct blk_mq_hw_ctx *hctx,
for (j = 0; j < to_do; j++) {
hctx->rqs[i] = p;
blk_rq_init(hctx->queue, hctx->rqs[i]);
+ if (reg->ops->init_request) {
+ error = reg->ops->init_request(driver_data,
+ hctx, hctx->rqs[i], i);
+ if (error)
+ goto err_rq_map;
+ }
+
p += rq_size;
i++;
}
}
- if (i < (reserved_tags + BLK_MQ_TAG_MIN))
+ if (i < (reserved_tags + BLK_MQ_TAG_MIN)) {
+ error = -ENOMEM;
goto err_rq_map;
- else if (i != hctx->queue_depth) {
+ }
+ if (i != hctx->queue_depth) {
hctx->queue_depth = i;
pr_warn("%s: queue depth set to %u because of low memory\n",
__func__, i);
@@ -1164,12 +1121,14 @@ static int blk_mq_init_rq_map(struct blk_mq_hw_ctx *hctx,
hctx->tags = blk_mq_init_tags(hctx->queue_depth, reserved_tags, node);
if (!hctx->tags) {
-err_rq_map:
- blk_mq_free_rq_map(hctx);
- return -ENOMEM;
+ error = -ENOMEM;
+ goto err_rq_map;
}
return 0;
+err_rq_map:
+ blk_mq_free_rq_map(hctx, driver_data);
+ return error;
}
static int blk_mq_init_hw_queues(struct request_queue *q,
@@ -1202,7 +1161,7 @@ static int blk_mq_init_hw_queues(struct request_queue *q,
blk_mq_hctx_notify, hctx);
blk_mq_register_cpu_notifier(&hctx->cpu_notifier);
- if (blk_mq_init_rq_map(hctx, reg->reserved_tags, node))
+ if (blk_mq_init_rq_map(hctx, reg, driver_data, node))
break;
/*
@@ -1242,7 +1201,7 @@ static int blk_mq_init_hw_queues(struct request_queue *q,
reg->ops->exit_hctx(hctx, j);
blk_mq_unregister_cpu_notifier(&hctx->cpu_notifier);
- blk_mq_free_rq_map(hctx);
+ blk_mq_free_rq_map(hctx, driver_data);
kfree(hctx->ctxs);
}
@@ -1419,7 +1378,7 @@ void blk_mq_free_queue(struct request_queue *q)
queue_for_each_hw_ctx(q, hctx, i) {
kfree(hctx->ctx_map);
kfree(hctx->ctxs);
- blk_mq_free_rq_map(hctx);
+ blk_mq_free_rq_map(hctx, q->queuedata);
blk_mq_unregister_cpu_notifier(&hctx->cpu_notifier);
if (q->mq_ops->exit_hctx)
q->mq_ops->exit_hctx(hctx, i);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 11e8f4b..87447c1f 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -474,11 +474,22 @@ static const struct device_attribute dev_attr_cache_type_rw =
__ATTR(cache_type, S_IRUGO|S_IWUSR,
virtblk_cache_type_show, virtblk_cache_type_store);
+static int virtblk_init_request(void *data, struct blk_mq_hw_ctx *hctx,
+ struct request *rq, unsigned int nr)
+{
+ struct virtio_blk *vblk = data;
+ struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq);
+
+ sg_init_table(vbr->sg, vblk->sg_elems);
+ return 0;
+}
+
static struct blk_mq_ops virtio_mq_ops = {
.queue_rq = virtio_queue_rq,
.map_queue = blk_mq_map_queue,
.alloc_hctx = blk_mq_alloc_single_hw_queue,
.free_hctx = blk_mq_free_single_hw_queue,
+ .init_request = virtblk_init_request,
.complete = virtblk_request_done,
};
@@ -490,16 +501,6 @@ static struct blk_mq_reg virtio_mq_reg = {
.flags = BLK_MQ_F_SHOULD_MERGE,
};
-static int virtblk_init_vbr(void *data, struct blk_mq_hw_ctx *hctx,
- struct request *rq, unsigned int nr)
-{
- struct virtio_blk *vblk = data;
- struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq);
-
- sg_init_table(vbr->sg, vblk->sg_elems);
- return 0;
-}
-
static int virtblk_probe(struct virtio_device *vdev)
{
struct virtio_blk *vblk;
@@ -563,8 +564,6 @@ static int virtblk_probe(struct virtio_device *vdev)
goto out_put_disk;
}
- blk_mq_init_commands(q, virtblk_init_vbr, vblk);
-
q->queuedata = vblk;
virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN);
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 0120451..897ca1a 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -66,6 +66,10 @@ typedef struct blk_mq_hw_ctx *(alloc_hctx_fn)(struct blk_mq_reg *,unsigned int);
typedef void (free_hctx_fn)(struct blk_mq_hw_ctx *, unsigned int);
typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int);
typedef void (exit_hctx_fn)(struct blk_mq_hw_ctx *, unsigned int);
+typedef int (init_request_fn)(void *, struct blk_mq_hw_ctx *,
+ struct request *, unsigned int);
+typedef void (exit_request_fn)(void *, struct blk_mq_hw_ctx *,
+ struct request *, unsigned int);
struct blk_mq_ops {
/*
@@ -98,6 +102,14 @@ struct blk_mq_ops {
*/
init_hctx_fn *init_hctx;
exit_hctx_fn *exit_hctx;
+
+ /*
+ * Called for every command allocated by the block layer to allow
+ * the driver to set up driver specific data.
+ * Ditto for exit/teardown.
+ */
+ init_request_fn *init_request;
+ exit_request_fn *exit_request;
};
enum {
@@ -117,8 +129,6 @@ enum {
struct request_queue *blk_mq_init_queue(struct blk_mq_reg *, void *);
int blk_mq_register_disk(struct gendisk *);
void blk_mq_unregister_disk(struct gendisk *);
-int blk_mq_init_commands(struct request_queue *, int (*init)(void *data, struct blk_mq_hw_ctx *, struct request *, unsigned int), void *data);
-void blk_mq_free_commands(struct request_queue *, void (*free)(void *data, struct blk_mq_hw_ctx *, struct request *, unsigned int), void *data);
void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule);
--
1.7.10.4
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-04-02 14:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-02 14:57 blk-mq updates, V3 Christoph Hellwig
2014-04-02 14:57 ` [PATCH 1/5] blk-mq: initialize resid_len Christoph Hellwig
2014-04-02 14:57 ` [PATCH 2/5] blk-mq: fix blk_mq_end_io_partial Christoph Hellwig
2014-04-02 14:57 ` [PATCH 3/5] blk-mq: do not initialize req->special Christoph Hellwig
2014-04-02 14:57 ` [PATCH 4/5] blk-mq: make ->flush_rq fully transparent to drivers Christoph Hellwig
2014-04-02 14:57 ` [PATCH 5/5] blk-mq: add ->init_request and ->exit_request methods Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®