diff options
author | Mike Snitzer <snitzer@redhat.com> | 2016-05-24 21:16:51 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2016-06-10 15:16:02 -0400 |
commit | e83068a5faafb8ca65d3b58bd1e1e3959ce1ddce (patch) | |
tree | 9158ec7acad94d7035153f84e8ff53205caf7315 /drivers/md/dm-rq.c | |
parent | bf661be1fcf9b1da8abc81a56ff41ce5964ce896 (diff) | |
download | linux-stable-e83068a5faafb8ca65d3b58bd1e1e3959ce1ddce.tar.gz linux-stable-e83068a5faafb8ca65d3b58bd1e1e3959ce1ddce.tar.bz2 linux-stable-e83068a5faafb8ca65d3b58bd1e1e3959ce1ddce.zip |
dm mpath: add optional "queue_mode" feature
Allow a user to specify an optional feature 'queue_mode <mode>' where
<mode> may be "bio", "rq" or "mq" -- which corresponds to bio-based,
request_fn rq-based, and blk-mq rq-based respectively.
If the queue_mode feature isn't specified the default for the
"multipath" target is still "rq" but if dm_mod.use_blk_mq is set to Y
it'll default to mode "mq".
This new queue_mode feature introduces the ability for each multipath
device to have its own queue_mode (whereas before this feature all
multipath devices effectively had to have the same queue_mode).
This commit also goes a long way to eliminate the awkward (ab)use of
DM_TYPE_*, the associated filter_md_type() and other relatively fragile
and difficult to maintain code.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-rq.c')
-rw-r--r-- | drivers/md/dm-rq.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index 787c81b16a26..266f7b674108 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -230,7 +230,14 @@ static void free_rq_clone(struct request *clone) blk_rq_unprep_clone(clone); - if (md->type == DM_TYPE_MQ_REQUEST_BASED) + /* + * It is possible for a clone_old_rq() allocated clone to + * get passed in -- it may not yet have a request_queue. + * This is known to occur if the error target replaces + * a multipath target that has a request_fn queue stacked + * on blk-mq queue(s). + */ + if (clone->q && clone->q->mq_ops) /* stacked on blk-mq queue(s) */ tio->ti->type->release_clone_rq(clone); else if (!md->queue->mq_ops) @@ -561,7 +568,7 @@ static struct dm_rq_target_io *dm_old_prep_tio(struct request *rq, * Must clone a request if this .request_fn DM device * is stacked on .request_fn device(s). */ - if (!dm_table_mq_request_based(table)) { + if (!dm_table_all_blk_mq_devices(table)) { if (!clone_old_rq(rq, md, tio, gfp_mask)) { dm_put_live_table(md, srcu_idx); free_old_rq_tio(tio); @@ -711,7 +718,7 @@ ssize_t dm_attr_rq_based_seq_io_merge_deadline_store(struct mapped_device *md, { unsigned deadline; - if (!dm_request_based(md) || md->use_blk_mq) + if (dm_get_md_type(md) != DM_TYPE_REQUEST_BASED) return count; if (kstrtouint(buf, 10, &deadline)) @@ -886,12 +893,13 @@ static struct blk_mq_ops dm_mq_ops = { .init_request = dm_mq_init_request, }; -int dm_mq_init_request_queue(struct mapped_device *md, struct dm_target *immutable_tgt) +int dm_mq_init_request_queue(struct mapped_device *md, struct dm_table *t) { struct request_queue *q; + struct dm_target *immutable_tgt; int err; - if (dm_get_md_type(md) == DM_TYPE_REQUEST_BASED) { + if (!dm_table_all_blk_mq_devices(t)) { DMERR("request-based dm-mq may only be stacked on blk-mq device(s)"); return -EINVAL; } @@ -908,6 +916,7 @@ int dm_mq_init_request_queue(struct mapped_device *md, struct dm_target *immutab md->tag_set->driver_data = md; md->tag_set->cmd_size = sizeof(struct dm_rq_target_io); + immutable_tgt = dm_table_get_immutable_target(t); if (immutable_tgt && immutable_tgt->per_io_data_size) { /* any target-specific per-io data is immediately after the tio */ md->tag_set->cmd_size += immutable_tgt->per_io_data_size; |