Commit cd025384 authored by Mike Snitzer's avatar Mike Snitzer

dm mpath: implement NVMe bio-based support

This DM multipath NVMe bio-based support requires CONFIG_NVME_MULTIPATH
to not be set.  In the future hopefully NVMe multipath and DM multipath
can co-exist more seemlessly.  But as is, if CONFIG_NVME_MULTIPATH=Y
then all the individal NVMe paths will remain hidden to upper layers and
as such DM multipath will not be able to manage them.

Though NVMe's native multipathing doesn't multipath namespaces across
subsystems; so technically a user _could_ use CONFIG_NVME_MULTIPATH=Y
and also use DM multipath to multipath across subsystems.
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 1836df08
...@@ -221,14 +221,19 @@ static int alloc_multipath_stage2(struct dm_target *ti, struct multipath *m) ...@@ -221,14 +221,19 @@ static int alloc_multipath_stage2(struct dm_target *ti, struct multipath *m)
m->queue_mode = DM_TYPE_MQ_REQUEST_BASED; m->queue_mode = DM_TYPE_MQ_REQUEST_BASED;
else else
m->queue_mode = DM_TYPE_REQUEST_BASED; m->queue_mode = DM_TYPE_REQUEST_BASED;
} else if (m->queue_mode == DM_TYPE_BIO_BASED) {
} else if (m->queue_mode == DM_TYPE_BIO_BASED ||
m->queue_mode == DM_TYPE_NVME_BIO_BASED) {
INIT_WORK(&m->process_queued_bios, process_queued_bios); INIT_WORK(&m->process_queued_bios, process_queued_bios);
if (m->queue_mode == DM_TYPE_BIO_BASED) {
/* /*
* bio-based doesn't support any direct scsi_dh management; * bio-based doesn't support any direct scsi_dh management;
* it just discovers if a scsi_dh is attached. * it just discovers if a scsi_dh is attached.
*/ */
set_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags); set_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags);
} }
}
dm_table_set_type(ti->table, m->queue_mode); dm_table_set_type(ti->table, m->queue_mode);
...@@ -609,7 +614,8 @@ static void process_queued_io_list(struct multipath *m) ...@@ -609,7 +614,8 @@ static void process_queued_io_list(struct multipath *m)
{ {
if (m->queue_mode == DM_TYPE_MQ_REQUEST_BASED) if (m->queue_mode == DM_TYPE_MQ_REQUEST_BASED)
dm_mq_kick_requeue_list(dm_table_get_md(m->ti->table)); dm_mq_kick_requeue_list(dm_table_get_md(m->ti->table));
else if (m->queue_mode == DM_TYPE_BIO_BASED) else if (m->queue_mode == DM_TYPE_BIO_BASED ||
m->queue_mode == DM_TYPE_NVME_BIO_BASED)
queue_work(kmultipathd, &m->process_queued_bios); queue_work(kmultipathd, &m->process_queued_bios);
} }
...@@ -925,7 +931,8 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) ...@@ -925,7 +931,8 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m)
if (!hw_argc) if (!hw_argc)
return 0; return 0;
if (m->queue_mode == DM_TYPE_BIO_BASED) { if (m->queue_mode == DM_TYPE_BIO_BASED ||
m->queue_mode == DM_TYPE_NVME_BIO_BASED) {
dm_consume_args(as, hw_argc); dm_consume_args(as, hw_argc);
DMERR("bio-based multipath doesn't allow hardware handler args"); DMERR("bio-based multipath doesn't allow hardware handler args");
return 0; return 0;
...@@ -1014,6 +1021,8 @@ static int parse_features(struct dm_arg_set *as, struct multipath *m) ...@@ -1014,6 +1021,8 @@ static int parse_features(struct dm_arg_set *as, struct multipath *m)
if (!strcasecmp(queue_mode_name, "bio")) if (!strcasecmp(queue_mode_name, "bio"))
m->queue_mode = DM_TYPE_BIO_BASED; m->queue_mode = DM_TYPE_BIO_BASED;
else if (!strcasecmp(queue_mode_name, "nvme"))
m->queue_mode = DM_TYPE_NVME_BIO_BASED;
else if (!strcasecmp(queue_mode_name, "rq")) else if (!strcasecmp(queue_mode_name, "rq"))
m->queue_mode = DM_TYPE_REQUEST_BASED; m->queue_mode = DM_TYPE_REQUEST_BASED;
else if (!strcasecmp(queue_mode_name, "mq")) else if (!strcasecmp(queue_mode_name, "mq"))
...@@ -1114,7 +1123,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned argc, char **argv) ...@@ -1114,7 +1123,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned argc, char **argv)
ti->num_discard_bios = 1; ti->num_discard_bios = 1;
ti->num_write_same_bios = 1; ti->num_write_same_bios = 1;
ti->num_write_zeroes_bios = 1; ti->num_write_zeroes_bios = 1;
if (m->queue_mode == DM_TYPE_BIO_BASED) if (m->queue_mode == DM_TYPE_BIO_BASED || m->queue_mode == DM_TYPE_NVME_BIO_BASED)
ti->per_io_data_size = multipath_per_bio_data_size(); ti->per_io_data_size = multipath_per_bio_data_size();
else else
ti->per_io_data_size = sizeof(struct dm_mpath_io); ti->per_io_data_size = sizeof(struct dm_mpath_io);
...@@ -1660,6 +1669,9 @@ static void multipath_status(struct dm_target *ti, status_type_t type, ...@@ -1660,6 +1669,9 @@ static void multipath_status(struct dm_target *ti, status_type_t type,
case DM_TYPE_BIO_BASED: case DM_TYPE_BIO_BASED:
DMEMIT("queue_mode bio "); DMEMIT("queue_mode bio ");
break; break;
case DM_TYPE_NVME_BIO_BASED:
DMEMIT("queue_mode nvme ");
break;
case DM_TYPE_MQ_REQUEST_BASED: case DM_TYPE_MQ_REQUEST_BASED:
DMEMIT("queue_mode mq "); DMEMIT("queue_mode mq ");
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment