Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'nvme-5.16-2021-10-21' of git://git.infradead.org/nvme into for-5.16/drivers

Pull NVMe updates from Christoph:

"nvme updates for Linux 5.16

- fix a multipath partition scanning deadlock (Hannes Reinecke)
- generate uevent once a multipath namespace is operational again
(Hannes Reinecke)
- support unique discovery controller NQNs (Hannes Reinecke)
- fix use-after-free when a port is removed (Israel Rukshin)
- clear shadow doorbell memory on resets (Keith Busch)
- use struct_size (Len Baker)
- add error handling support for add_disk (Luis Chamberlain)
- limit the maximal queue size for RDMA controllers (Max Gurtovoy)
- use a few more symbolic names (Max Gurtovoy)
- fix error code in nvme_rdma_setup_ctrl (Max Gurtovoy)
- add support for ->map_queues on FC (Saurav Kashyap)"

* tag 'nvme-5.16-2021-10-21' of git://git.infradead.org/nvme: (23 commits)
nvmet: use struct_size over open coded arithmetic
nvme: drop scan_lock and always kick requeue list when removing namespaces
nvme-pci: clear shadow doorbell memory on resets
nvme-rdma: fix error code in nvme_rdma_setup_ctrl
nvme-multipath: add error handling support for add_disk()
nvmet: use macro definitions for setting cmic value
nvmet: use macro definition for setting nmic value
nvme: display correct subsystem NQN
nvme: Add connect option 'discovery'
nvme: expose subsystem type in sysfs attribute 'subsystype'
nvmet: set 'CNTRLTYPE' in the identify controller data
nvmet: add nvmet_is_disc_subsys() helper
nvme: add CNTRLTYPE definitions for 'identify controller'
nvmet: make discovery NQN configurable
nvmet-rdma: implement get_max_queue_size controller op
nvmet: add get_max_queue_size op for controllers
nvme-rdma: limit the maximal queue size for RDMA controllers
nvmet-tcp: fix use-after-free when a port is removed
nvmet-rdma: fix use-after-free when a port is removed
nvmet: fix use-after-free when a port is removed
...

+266 -29
+35 -1
drivers/nvme/host/core.c
··· 222 222 static void nvme_do_delete_ctrl(struct nvme_ctrl *ctrl) 223 223 { 224 224 dev_info(ctrl->device, 225 - "Removing ctrl: NQN \"%s\"\n", ctrl->opts->subsysnqn); 225 + "Removing ctrl: NQN \"%s\"\n", nvmf_ctrl_subsysnqn(ctrl)); 226 226 227 227 flush_work(&ctrl->reset_work); 228 228 nvme_stop_ctrl(ctrl); ··· 2620 2620 } 2621 2621 static SUBSYS_ATTR_RO(subsysnqn, S_IRUGO, nvme_subsys_show_nqn); 2622 2622 2623 + static ssize_t nvme_subsys_show_type(struct device *dev, 2624 + struct device_attribute *attr, 2625 + char *buf) 2626 + { 2627 + struct nvme_subsystem *subsys = 2628 + container_of(dev, struct nvme_subsystem, dev); 2629 + 2630 + switch (subsys->subtype) { 2631 + case NVME_NQN_DISC: 2632 + return sysfs_emit(buf, "discovery\n"); 2633 + case NVME_NQN_NVME: 2634 + return sysfs_emit(buf, "nvm\n"); 2635 + default: 2636 + return sysfs_emit(buf, "reserved\n"); 2637 + } 2638 + } 2639 + static SUBSYS_ATTR_RO(subsystype, S_IRUGO, nvme_subsys_show_type); 2640 + 2623 2641 #define nvme_subsys_show_str_function(field) \ 2624 2642 static ssize_t subsys_##field##_show(struct device *dev, \ 2625 2643 struct device_attribute *attr, char *buf) \ ··· 2658 2640 &subsys_attr_serial.attr, 2659 2641 &subsys_attr_firmware_rev.attr, 2660 2642 &subsys_attr_subsysnqn.attr, 2643 + &subsys_attr_subsystype.attr, 2661 2644 #ifdef CONFIG_NVME_MULTIPATH 2662 2645 &subsys_attr_iopolicy.attr, 2663 2646 #endif ··· 2729 2710 memcpy(subsys->firmware_rev, id->fr, sizeof(subsys->firmware_rev)); 2730 2711 subsys->vendor_id = le16_to_cpu(id->vid); 2731 2712 subsys->cmic = id->cmic; 2713 + 2714 + /* Versions prior to 1.4 don't necessarily report a valid type */ 2715 + if (id->cntrltype == NVME_CTRL_DISC || 2716 + !strcmp(subsys->subnqn, NVME_DISC_SUBSYS_NAME)) 2717 + subsys->subtype = NVME_NQN_DISC; 2718 + else 2719 + subsys->subtype = NVME_NQN_NVME; 2720 + 2721 + if (nvme_discovery_ctrl(ctrl) && subsys->subtype != NVME_NQN_DISC) { 2722 + dev_err(ctrl->device, 2723 + "Subsystem %s is not a discovery controller", 2724 + subsys->subnqn); 2725 + kfree(subsys); 2726 + return -EINVAL; 2727 + } 2732 2728 subsys->awupf = le16_to_cpu(id->awupf); 2733 2729 #ifdef CONFIG_NVME_MULTIPATH 2734 2730 subsys->iopolicy = NVME_IOPOLICY_NUMA;
+5 -1
drivers/nvme/host/fabrics.c
··· 548 548 { NVMF_OPT_NR_POLL_QUEUES, "nr_poll_queues=%d" }, 549 549 { NVMF_OPT_TOS, "tos=%d" }, 550 550 { NVMF_OPT_FAIL_FAST_TMO, "fast_io_fail_tmo=%d" }, 551 + { NVMF_OPT_DISCOVERY, "discovery" }, 551 552 { NVMF_OPT_ERR, NULL } 552 553 }; 553 554 ··· 824 823 } 825 824 opts->tos = token; 826 825 break; 826 + case NVMF_OPT_DISCOVERY: 827 + opts->discovery_nqn = true; 828 + break; 827 829 default: 828 830 pr_warn("unknown parameter or missing value '%s' in ctrl creation request\n", 829 831 p); ··· 953 949 #define NVMF_ALLOWED_OPTS (NVMF_OPT_QUEUE_SIZE | NVMF_OPT_NR_IO_QUEUES | \ 954 950 NVMF_OPT_KATO | NVMF_OPT_HOSTNQN | \ 955 951 NVMF_OPT_HOST_ID | NVMF_OPT_DUP_CONNECT |\ 956 - NVMF_OPT_DISABLE_SQFLOW |\ 952 + NVMF_OPT_DISABLE_SQFLOW | NVMF_OPT_DISCOVERY |\ 957 953 NVMF_OPT_FAIL_FAST_TMO) 958 954 959 955 static struct nvme_ctrl *
+8
drivers/nvme/host/fabrics.h
··· 67 67 NVMF_OPT_TOS = 1 << 19, 68 68 NVMF_OPT_FAIL_FAST_TMO = 1 << 20, 69 69 NVMF_OPT_HOST_IFACE = 1 << 21, 70 + NVMF_OPT_DISCOVERY = 1 << 22, 70 71 }; 71 72 72 73 /** ··· 177 176 return false; 178 177 179 178 return true; 179 + } 180 + 181 + static inline char *nvmf_ctrl_subsysnqn(struct nvme_ctrl *ctrl) 182 + { 183 + if (!ctrl->subsys) 184 + return ctrl->opts->subsysnqn; 185 + return ctrl->subsys->subnqn; 180 186 } 181 187 182 188 int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val);
+25 -1
drivers/nvme/host/fc.c
··· 16 16 #include <linux/nvme-fc.h> 17 17 #include "fc.h" 18 18 #include <scsi/scsi_transport_fc.h> 19 + #include <linux/blk-mq-pci.h> 19 20 20 21 /* *************************** Data Structures/Defines ****************** */ 21 22 ··· 2842 2841 nvme_fc_ctrl_put(ctrl); 2843 2842 } 2844 2843 2844 + static int nvme_fc_map_queues(struct blk_mq_tag_set *set) 2845 + { 2846 + struct nvme_fc_ctrl *ctrl = set->driver_data; 2847 + int i; 2848 + 2849 + for (i = 0; i < set->nr_maps; i++) { 2850 + struct blk_mq_queue_map *map = &set->map[i]; 2851 + 2852 + if (!map->nr_queues) { 2853 + WARN_ON(i == HCTX_TYPE_DEFAULT); 2854 + continue; 2855 + } 2856 + 2857 + /* Call LLDD map queue functionality if defined */ 2858 + if (ctrl->lport->ops->map_queues) 2859 + ctrl->lport->ops->map_queues(&ctrl->lport->localport, 2860 + map); 2861 + else 2862 + blk_mq_map_queues(map); 2863 + } 2864 + return 0; 2865 + } 2845 2866 2846 2867 static const struct blk_mq_ops nvme_fc_mq_ops = { 2847 2868 .queue_rq = nvme_fc_queue_rq, ··· 2872 2849 .exit_request = nvme_fc_exit_request, 2873 2850 .init_hctx = nvme_fc_init_hctx, 2874 2851 .timeout = nvme_fc_timeout, 2852 + .map_queues = nvme_fc_map_queues, 2875 2853 }; 2876 2854 2877 2855 static int ··· 3596 3572 3597 3573 dev_info(ctrl->ctrl.device, 3598 3574 "NVME-FC{%d}: new ctrl: NQN \"%s\"\n", 3599 - ctrl->cnum, ctrl->ctrl.opts->subsysnqn); 3575 + ctrl->cnum, nvmf_ctrl_subsysnqn(&ctrl->ctrl)); 3600 3576 3601 3577 return &ctrl->ctrl; 3602 3578
+21 -9
drivers/nvme/host/multipath.c
··· 105 105 106 106 down_read(&ctrl->namespaces_rwsem); 107 107 list_for_each_entry(ns, &ctrl->namespaces, list) { 108 - if (ns->head->disk) 109 - kblockd_schedule_work(&ns->head->requeue_work); 108 + if (!ns->head->disk) 109 + continue; 110 + kblockd_schedule_work(&ns->head->requeue_work); 111 + if (ctrl->state == NVME_CTRL_LIVE) 112 + disk_uevent(ns->head->disk, KOBJ_CHANGE); 110 113 } 111 114 up_read(&ctrl->namespaces_rwsem); 112 115 } ··· 146 143 { 147 144 struct nvme_ns *ns; 148 145 149 - mutex_lock(&ctrl->scan_lock); 150 146 down_read(&ctrl->namespaces_rwsem); 151 - list_for_each_entry(ns, &ctrl->namespaces, list) 152 - if (nvme_mpath_clear_current_path(ns)) 153 - kblockd_schedule_work(&ns->head->requeue_work); 147 + list_for_each_entry(ns, &ctrl->namespaces, list) { 148 + nvme_mpath_clear_current_path(ns); 149 + kblockd_schedule_work(&ns->head->requeue_work); 150 + } 154 151 up_read(&ctrl->namespaces_rwsem); 155 - mutex_unlock(&ctrl->scan_lock); 156 152 } 157 153 158 154 void nvme_mpath_revalidate_paths(struct nvme_ns *ns) ··· 508 506 static void nvme_mpath_set_live(struct nvme_ns *ns) 509 507 { 510 508 struct nvme_ns_head *head = ns->head; 509 + int rc; 511 510 512 511 if (!head->disk) 513 512 return; 514 513 514 + /* 515 + * test_and_set_bit() is used because it is protecting against two nvme 516 + * paths simultaneously calling device_add_disk() on the same namespace 517 + * head. 518 + */ 515 519 if (!test_and_set_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { 516 - device_add_disk(&head->subsys->dev, head->disk, 517 - nvme_ns_id_attr_groups); 520 + rc = device_add_disk(&head->subsys->dev, head->disk, 521 + nvme_ns_id_attr_groups); 522 + if (rc) { 523 + clear_bit(NVME_NSHEAD_DISK_LIVE, &ns->flags); 524 + return; 525 + } 518 526 nvme_add_ns_head_cdev(head); 519 527 } 520 528
+1
drivers/nvme/host/nvme.h
··· 372 372 char model[40]; 373 373 char firmware_rev[8]; 374 374 u8 cmic; 375 + enum nvme_subsys_type subtype; 375 376 u16 vendor_id; 376 377 u16 awupf; /* 0's based awupf value. */ 377 378 struct ida ns_ida;
+8 -1
drivers/nvme/host/pci.c
··· 245 245 { 246 246 unsigned int mem_size = nvme_dbbuf_size(dev); 247 247 248 - if (dev->dbbuf_dbs) 248 + if (dev->dbbuf_dbs) { 249 + /* 250 + * Clear the dbbuf memory so the driver doesn't observe stale 251 + * values from the previous instantiation. 252 + */ 253 + memset(dev->dbbuf_dbs, 0, mem_size); 254 + memset(dev->dbbuf_eis, 0, mem_size); 249 255 return 0; 256 + } 250 257 251 258 dev->dbbuf_dbs = dma_alloc_coherent(dev->dev, mem_size, 252 259 &dev->dbbuf_dbs_dma_addr,
+10 -1
drivers/nvme/host/rdma.c
··· 1096 1096 return ret; 1097 1097 1098 1098 if (ctrl->ctrl.icdoff) { 1099 + ret = -EOPNOTSUPP; 1099 1100 dev_err(ctrl->ctrl.device, "icdoff is not supported!\n"); 1100 1101 goto destroy_admin; 1101 1102 } 1102 1103 1103 1104 if (!(ctrl->ctrl.sgls & (1 << 2))) { 1105 + ret = -EOPNOTSUPP; 1104 1106 dev_err(ctrl->ctrl.device, 1105 1107 "Mandatory keyed sgls are not supported!\n"); 1106 1108 goto destroy_admin; ··· 1112 1110 dev_warn(ctrl->ctrl.device, 1113 1111 "queue_size %zu > ctrl sqsize %u, clamping down\n", 1114 1112 ctrl->ctrl.opts->queue_size, ctrl->ctrl.sqsize + 1); 1113 + } 1114 + 1115 + if (ctrl->ctrl.sqsize + 1 > NVME_RDMA_MAX_QUEUE_SIZE) { 1116 + dev_warn(ctrl->ctrl.device, 1117 + "ctrl sqsize %u > max queue size %u, clamping down\n", 1118 + ctrl->ctrl.sqsize + 1, NVME_RDMA_MAX_QUEUE_SIZE); 1119 + ctrl->ctrl.sqsize = NVME_RDMA_MAX_QUEUE_SIZE - 1; 1115 1120 } 1116 1121 1117 1122 if (ctrl->ctrl.sqsize + 1 > ctrl->ctrl.maxcmd) { ··· 2395 2386 goto out_uninit_ctrl; 2396 2387 2397 2388 dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISpcs\n", 2398 - ctrl->ctrl.opts->subsysnqn, &ctrl->addr); 2389 + nvmf_ctrl_subsysnqn(&ctrl->ctrl), &ctrl->addr); 2399 2390 2400 2391 mutex_lock(&nvme_rdma_ctrl_mutex); 2401 2392 list_add_tail(&ctrl->list, &nvme_rdma_ctrl_list);
+1 -1
drivers/nvme/host/tcp.c
··· 2582 2582 goto out_uninit_ctrl; 2583 2583 2584 2584 dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISp\n", 2585 - ctrl->ctrl.opts->subsysnqn, &ctrl->addr); 2585 + nvmf_ctrl_subsysnqn(&ctrl->ctrl), &ctrl->addr); 2586 2586 2587 2587 mutex_lock(&nvme_tcp_ctrl_mutex); 2588 2588 list_add_tail(&ctrl->list, &nvme_tcp_ctrl_list);
+11 -5
drivers/nvme/target/admin-cmd.c
··· 278 278 u16 status; 279 279 280 280 status = NVME_SC_INTERNAL; 281 - desc = kmalloc(sizeof(struct nvme_ana_group_desc) + 282 - NVMET_MAX_NAMESPACES * sizeof(__le32), GFP_KERNEL); 281 + desc = kmalloc(struct_size(desc, nsids, NVMET_MAX_NAMESPACES), 282 + GFP_KERNEL); 283 283 if (!desc) 284 284 goto out; 285 285 ··· 374 374 375 375 id->rab = 6; 376 376 377 + if (nvmet_is_disc_subsys(ctrl->subsys)) 378 + id->cntrltype = NVME_CTRL_DISC; 379 + else 380 + id->cntrltype = NVME_CTRL_IO; 381 + 377 382 /* 378 383 * XXX: figure out how we can assign a IEEE OUI, but until then 379 384 * the safest is to leave it as zeroes. 380 385 */ 381 386 382 387 /* we support multiple ports, multiples hosts and ANA: */ 383 - id->cmic = (1 << 0) | (1 << 1) | (1 << 3); 388 + id->cmic = NVME_CTRL_CMIC_MULTI_PORT | NVME_CTRL_CMIC_MULTI_CTRL | 389 + NVME_CTRL_CMIC_ANA; 384 390 385 391 /* Limit MDTS according to transport capability */ 386 392 if (ctrl->ops->get_mdts) ··· 542 536 * Our namespace might always be shared. Not just with other 543 537 * controllers, but also with any other user of the block device. 544 538 */ 545 - id->nmic = (1 << 0); 539 + id->nmic = NVME_NS_NMIC_SHARED; 546 540 id->anagrpid = cpu_to_le32(req->ns->anagrpid); 547 541 548 542 memcpy(&id->nguid, &req->ns->nguid, sizeof(id->nguid)); ··· 1014 1008 1015 1009 if (nvme_is_fabrics(cmd)) 1016 1010 return nvmet_parse_fabrics_cmd(req); 1017 - if (nvmet_req_subsys(req)->type == NVME_NQN_DISC) 1011 + if (nvmet_is_disc_subsys(nvmet_req_subsys(req))) 1018 1012 return nvmet_parse_discovery_cmd(req); 1019 1013 1020 1014 ret = nvmet_check_ctrl_status(req);
+41
drivers/nvme/target/configfs.c
··· 1233 1233 } 1234 1234 CONFIGFS_ATTR(nvmet_subsys_, attr_model); 1235 1235 1236 + static ssize_t nvmet_subsys_attr_discovery_nqn_show(struct config_item *item, 1237 + char *page) 1238 + { 1239 + return snprintf(page, PAGE_SIZE, "%s\n", 1240 + nvmet_disc_subsys->subsysnqn); 1241 + } 1242 + 1243 + static ssize_t nvmet_subsys_attr_discovery_nqn_store(struct config_item *item, 1244 + const char *page, size_t count) 1245 + { 1246 + struct nvmet_subsys *subsys = to_subsys(item); 1247 + char *subsysnqn; 1248 + int len; 1249 + 1250 + len = strcspn(page, "\n"); 1251 + if (!len) 1252 + return -EINVAL; 1253 + 1254 + subsysnqn = kmemdup_nul(page, len, GFP_KERNEL); 1255 + if (!subsysnqn) 1256 + return -ENOMEM; 1257 + 1258 + /* 1259 + * The discovery NQN must be different from subsystem NQN. 1260 + */ 1261 + if (!strcmp(subsysnqn, subsys->subsysnqn)) { 1262 + kfree(subsysnqn); 1263 + return -EBUSY; 1264 + } 1265 + down_write(&nvmet_config_sem); 1266 + kfree(nvmet_disc_subsys->subsysnqn); 1267 + nvmet_disc_subsys->subsysnqn = subsysnqn; 1268 + up_write(&nvmet_config_sem); 1269 + 1270 + return count; 1271 + } 1272 + CONFIGFS_ATTR(nvmet_subsys_, attr_discovery_nqn); 1273 + 1236 1274 #ifdef CONFIG_BLK_DEV_INTEGRITY 1237 1275 static ssize_t nvmet_subsys_attr_pi_enable_show(struct config_item *item, 1238 1276 char *page) ··· 1300 1262 &nvmet_subsys_attr_attr_cntlid_min, 1301 1263 &nvmet_subsys_attr_attr_cntlid_max, 1302 1264 &nvmet_subsys_attr_attr_model, 1265 + &nvmet_subsys_attr_attr_discovery_nqn, 1303 1266 #ifdef CONFIG_BLK_DEV_INTEGRITY 1304 1267 &nvmet_subsys_attr_attr_pi_enable, 1305 1268 #endif ··· 1592 1553 { 1593 1554 struct nvmet_port *port = to_nvmet_port(item); 1594 1555 1556 + /* Let inflight controllers teardown complete */ 1557 + flush_scheduled_work(); 1595 1558 list_del(&port->global_entry); 1596 1559 1597 1560 kfree(port->ana_state);
+10 -7
drivers/nvme/target/core.c
··· 1140 1140 * should verify iosqes,iocqes are zeroed, however that 1141 1141 * would break backwards compatibility, so don't enforce it. 1142 1142 */ 1143 - if (ctrl->subsys->type != NVME_NQN_DISC && 1143 + if (!nvmet_is_disc_subsys(ctrl->subsys) && 1144 1144 (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES || 1145 1145 nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES)) { 1146 1146 ctrl->csts = NVME_CSTS_CFS; ··· 1205 1205 /* CC.EN timeout in 500msec units: */ 1206 1206 ctrl->cap |= (15ULL << 24); 1207 1207 /* maximum queue entries supported: */ 1208 - ctrl->cap |= NVMET_QUEUE_SIZE - 1; 1208 + if (ctrl->ops->get_max_queue_size) 1209 + ctrl->cap |= ctrl->ops->get_max_queue_size(ctrl) - 1; 1210 + else 1211 + ctrl->cap |= NVMET_QUEUE_SIZE - 1; 1209 1212 1210 1213 if (nvmet_is_passthru_subsys(ctrl->subsys)) 1211 1214 nvmet_passthrough_override_cap(ctrl); ··· 1281 1278 if (subsys->allow_any_host) 1282 1279 return true; 1283 1280 1284 - if (subsys->type == NVME_NQN_DISC) /* allow all access to disc subsys */ 1281 + if (nvmet_is_disc_subsys(subsys)) /* allow all access to disc subsys */ 1285 1282 return true; 1286 1283 1287 1284 list_for_each_entry(p, &subsys->hosts, entry) { ··· 1370 1367 mutex_init(&ctrl->lock); 1371 1368 1372 1369 ctrl->port = req->port; 1370 + ctrl->ops = req->ops; 1373 1371 1374 1372 INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); 1375 1373 INIT_LIST_HEAD(&ctrl->async_events); ··· 1409 1405 } 1410 1406 ctrl->cntlid = ret; 1411 1407 1412 - ctrl->ops = req->ops; 1413 - 1414 1408 /* 1415 1409 * Discovery controllers may use some arbitrary high value 1416 1410 * in order to cleanup stale discovery sessions 1417 1411 */ 1418 - if ((ctrl->subsys->type == NVME_NQN_DISC) && !kato) 1412 + if (nvmet_is_disc_subsys(ctrl->subsys) && !kato) 1419 1413 kato = NVMET_DISC_KATO_MS; 1420 1414 1421 1415 /* keep-alive timeout in seconds */ ··· 1493 1491 if (!port) 1494 1492 return NULL; 1495 1493 1496 - if (!strcmp(NVME_DISC_SUBSYS_NAME, subsysnqn)) { 1494 + if (!strcmp(NVME_DISC_SUBSYS_NAME, subsysnqn) || 1495 + !strcmp(nvmet_disc_subsys->subsysnqn, subsysnqn)) { 1497 1496 if (!kref_get_unless_zero(&nvmet_disc_subsys->ref)) 1498 1497 return NULL; 1499 1498 return nvmet_disc_subsys;
+2
drivers/nvme/target/discovery.c
··· 268 268 memcpy_and_pad(id->fr, sizeof(id->fr), 269 269 UTS_RELEASE, strlen(UTS_RELEASE), ' '); 270 270 271 + id->cntrltype = NVME_CTRL_DISC; 272 + 271 273 /* no limit on data transfer sizes for now */ 272 274 id->mdts = 0; 273 275 id->cntlid = cpu_to_le16(ctrl->cntlid);
+2 -1
drivers/nvme/target/fabrics-cmd.c
··· 221 221 goto out; 222 222 } 223 223 224 - pr_info("creating controller %d for subsystem %s for NQN %s%s.\n", 224 + pr_info("creating %s controller %d for subsystem %s for NQN %s%s.\n", 225 + nvmet_is_disc_subsys(ctrl->subsys) ? "discovery" : "nvm", 225 226 ctrl->cntlid, ctrl->subsys->subsysnqn, ctrl->hostnqn, 226 227 ctrl->pi_support ? " T10-PI is enabled" : ""); 227 228 req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid);
+6
drivers/nvme/target/nvmet.h
··· 309 309 u16 (*install_queue)(struct nvmet_sq *nvme_sq); 310 310 void (*discovery_chg)(struct nvmet_port *port); 311 311 u8 (*get_mdts)(const struct nvmet_ctrl *ctrl); 312 + u16 (*get_max_queue_size)(const struct nvmet_ctrl *ctrl); 312 313 }; 313 314 314 315 #define NVMET_MAX_INLINE_BIOVEC 8 ··· 575 574 static inline struct nvmet_subsys *nvmet_req_subsys(struct nvmet_req *req) 576 575 { 577 576 return req->sq->ctrl->subsys; 577 + } 578 + 579 + static inline bool nvmet_is_disc_subsys(struct nvmet_subsys *subsys) 580 + { 581 + return subsys->type == NVME_NQN_DISC; 578 582 } 579 583 580 584 #ifdef CONFIG_NVME_TARGET_PASSTHRU
+30
drivers/nvme/target/rdma.c
··· 1819 1819 mutex_unlock(&nvmet_rdma_queue_mutex); 1820 1820 } 1821 1821 1822 + static void nvmet_rdma_destroy_port_queues(struct nvmet_rdma_port *port) 1823 + { 1824 + struct nvmet_rdma_queue *queue, *tmp; 1825 + struct nvmet_port *nport = port->nport; 1826 + 1827 + mutex_lock(&nvmet_rdma_queue_mutex); 1828 + list_for_each_entry_safe(queue, tmp, &nvmet_rdma_queue_list, 1829 + queue_list) { 1830 + if (queue->port != nport) 1831 + continue; 1832 + 1833 + list_del_init(&queue->queue_list); 1834 + __nvmet_rdma_queue_disconnect(queue); 1835 + } 1836 + mutex_unlock(&nvmet_rdma_queue_mutex); 1837 + } 1838 + 1822 1839 static void nvmet_rdma_disable_port(struct nvmet_rdma_port *port) 1823 1840 { 1824 1841 struct rdma_cm_id *cm_id = xchg(&port->cm_id, NULL); 1825 1842 1826 1843 if (cm_id) 1827 1844 rdma_destroy_id(cm_id); 1845 + 1846 + /* 1847 + * Destroy the remaining queues, which are not belong to any 1848 + * controller yet. Do it here after the RDMA-CM was destroyed 1849 + * guarantees that no new queue will be created. 1850 + */ 1851 + nvmet_rdma_destroy_port_queues(port); 1828 1852 } 1829 1853 1830 1854 static int nvmet_rdma_enable_port(struct nvmet_rdma_port *port) ··· 2000 1976 return NVMET_RDMA_MAX_MDTS; 2001 1977 } 2002 1978 1979 + static u16 nvmet_rdma_get_max_queue_size(const struct nvmet_ctrl *ctrl) 1980 + { 1981 + return NVME_RDMA_MAX_QUEUE_SIZE; 1982 + } 1983 + 2003 1984 static const struct nvmet_fabrics_ops nvmet_rdma_ops = { 2004 1985 .owner = THIS_MODULE, 2005 1986 .type = NVMF_TRTYPE_RDMA, ··· 2016 1987 .delete_ctrl = nvmet_rdma_delete_ctrl, 2017 1988 .disc_traddr = nvmet_rdma_disc_port_addr, 2018 1989 .get_mdts = nvmet_rdma_get_mdts, 1990 + .get_max_queue_size = nvmet_rdma_get_max_queue_size, 2019 1991 }; 2020 1992 2021 1993 static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data)
+16
drivers/nvme/target/tcp.c
··· 1737 1737 return ret; 1738 1738 } 1739 1739 1740 + static void nvmet_tcp_destroy_port_queues(struct nvmet_tcp_port *port) 1741 + { 1742 + struct nvmet_tcp_queue *queue; 1743 + 1744 + mutex_lock(&nvmet_tcp_queue_mutex); 1745 + list_for_each_entry(queue, &nvmet_tcp_queue_list, queue_list) 1746 + if (queue->port == port) 1747 + kernel_sock_shutdown(queue->sock, SHUT_RDWR); 1748 + mutex_unlock(&nvmet_tcp_queue_mutex); 1749 + } 1750 + 1740 1751 static void nvmet_tcp_remove_port(struct nvmet_port *nport) 1741 1752 { 1742 1753 struct nvmet_tcp_port *port = nport->priv; ··· 1757 1746 port->sock->sk->sk_user_data = NULL; 1758 1747 write_unlock_bh(&port->sock->sk->sk_callback_lock); 1759 1748 cancel_work_sync(&port->accept_work); 1749 + /* 1750 + * Destroy the remaining queues, which are not belong to any 1751 + * controller yet. 1752 + */ 1753 + nvmet_tcp_destroy_port_queues(port); 1760 1754 1761 1755 sock_release(port->sock); 1762 1756 kfree(port);
+15
drivers/scsi/qla2xxx/qla_nvme.c
··· 8 8 #include <linux/delay.h> 9 9 #include <linux/nvme.h> 10 10 #include <linux/nvme-fc.h> 11 + #include <linux/blk-mq-pci.h> 12 + #include <linux/blk-mq.h> 11 13 12 14 static struct nvme_fc_port_template qla_nvme_fc_transport; 13 15 ··· 644 642 return rval; 645 643 } 646 644 645 + static void qla_nvme_map_queues(struct nvme_fc_local_port *lport, 646 + struct blk_mq_queue_map *map) 647 + { 648 + struct scsi_qla_host *vha = lport->private; 649 + int rc; 650 + 651 + rc = blk_mq_pci_map_queues(map, vha->hw->pdev, vha->irq_offset); 652 + if (rc) 653 + ql_log(ql_log_warn, vha, 0x21de, 654 + "pci map queue failed 0x%x", rc); 655 + } 656 + 647 657 static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport) 648 658 { 649 659 struct scsi_qla_host *vha = lport->private; ··· 690 676 .ls_abort = qla_nvme_ls_abort, 691 677 .fcp_io = qla_nvme_post_cmd, 692 678 .fcp_abort = qla_nvme_fcp_abort, 679 + .map_queues = qla_nvme_map_queues, 693 680 .max_hw_queues = 8, 694 681 .max_sgl_segments = 1024, 695 682 .max_dif_sgl_segments = 64,
+7
include/linux/nvme-fc-driver.h
··· 7 7 #define _NVME_FC_DRIVER_H 1 8 8 9 9 #include <linux/scatterlist.h> 10 + #include <linux/blk-mq.h> 10 11 11 12 12 13 /* ··· 498 497 int (*xmt_ls_rsp)(struct nvme_fc_local_port *localport, 499 498 struct nvme_fc_remote_port *rport, 500 499 struct nvmefc_ls_rsp *ls_rsp); 500 + void (*map_queues)(struct nvme_fc_local_port *localport, 501 + struct blk_mq_queue_map *map); 501 502 502 503 u32 max_hw_queues; 503 504 u16 max_sgl_segments; ··· 781 778 * The transport will always call the xmt_ls_rsp() routine for any 782 779 * LS received. 783 780 * Entrypoint is Mandatory. 781 + * 782 + * @map_queues: This functions lets the driver expose the queue mapping 783 + * to the block layer. 784 + * Entrypoint is Optional. 784 785 * 785 786 * @fcp_op: Called to perform a data transfer or transmit a response. 786 787 * The nvmefc_tgt_fcp_req structure is the same LLDD-supplied
+2
include/linux/nvme-rdma.h
··· 6 6 #ifndef _LINUX_NVME_RDMA_H 7 7 #define _LINUX_NVME_RDMA_H 8 8 9 + #define NVME_RDMA_MAX_QUEUE_SIZE 128 10 + 9 11 enum nvme_rdma_cm_fmt { 10 12 NVME_RDMA_CM_FMT_1_0 = 0x0, 11 13 };
+10 -1
include/linux/nvme.h
··· 31 31 NVME_NQN_NVME = 2, /* NVME type target subsystem */ 32 32 }; 33 33 34 + enum nvme_ctrl_type { 35 + NVME_CTRL_IO = 1, /* I/O controller */ 36 + NVME_CTRL_DISC = 2, /* Discovery controller */ 37 + NVME_CTRL_ADMIN = 3, /* Administrative controller */ 38 + }; 39 + 34 40 /* Address Family codes for Discovery Log Page entry ADRFAM field */ 35 41 enum { 36 42 NVMF_ADDR_FAMILY_PCI = 0, /* PCIe */ ··· 250 244 __le32 rtd3e; 251 245 __le32 oaes; 252 246 __le32 ctratt; 253 - __u8 rsvd100[28]; 247 + __u8 rsvd100[11]; 248 + __u8 cntrltype; 249 + __u8 fguid[16]; 254 250 __le16 crdt1; 255 251 __le16 crdt2; 256 252 __le16 crdt3; ··· 320 312 }; 321 313 322 314 enum { 315 + NVME_CTRL_CMIC_MULTI_PORT = 1 << 0, 323 316 NVME_CTRL_CMIC_MULTI_CTRL = 1 << 1, 324 317 NVME_CTRL_CMIC_ANA = 1 << 3, 325 318 NVME_CTRL_ONCS_COMPARE = 1 << 0,