Skip to content

Commit 47ca23c

Browse files
committed
Merge branch 'nvme-5.2' of git://git.infradead.org/nvme into for-5.2/block-post
Pull NVMe fixes from Christoph * 'nvme-5.2' of git://git.infradead.org/nvme: nvme: validate cntlid during controller initialisation nvme: change locking for the per-subsystem controller list nvme: trace all async notice events nvme: fix typos in nvme status code values nvme-fabrics: remove unused argument nvme-multipath: avoid crash on invalid subsystem cntlid enumeration nvme-fc: use separate work queue to avoid warning nvme-rdma: remove redundant reference between ib_device and tagset nvme-pci: mark expected switch fall-through nvme-pci: add known admin effects to augument admin effects log page nvme-pci: init shadow doorbell after each reset
2 parents 936b33f + 1b1031c commit 47ca23c

File tree

8 files changed

+64
-78
lines changed

8 files changed

+64
-78
lines changed

drivers/nvme/host/core.c

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,10 +1257,9 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
12571257
return 0;
12581258
}
12591259

1260+
effects |= nvme_known_admin_effects(opcode);
12601261
if (ctrl->effects)
12611262
effects = le32_to_cpu(ctrl->effects->acs[opcode]);
1262-
else
1263-
effects = nvme_known_admin_effects(opcode);
12641263

12651264
/*
12661265
* For simplicity, IO to all namespaces is quiesced even if the command
@@ -2342,20 +2341,35 @@ static const struct attribute_group *nvme_subsys_attrs_groups[] = {
23422341
NULL,
23432342
};
23442343

2345-
static int nvme_active_ctrls(struct nvme_subsystem *subsys)
2344+
static bool nvme_validate_cntlid(struct nvme_subsystem *subsys,
2345+
struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
23462346
{
2347-
int count = 0;
2348-
struct nvme_ctrl *ctrl;
2347+
struct nvme_ctrl *tmp;
2348+
2349+
lockdep_assert_held(&nvme_subsystems_lock);
2350+
2351+
list_for_each_entry(tmp, &subsys->ctrls, subsys_entry) {
2352+
if (ctrl->state == NVME_CTRL_DELETING ||
2353+
ctrl->state == NVME_CTRL_DEAD)
2354+
continue;
2355+
2356+
if (tmp->cntlid == ctrl->cntlid) {
2357+
dev_err(ctrl->device,
2358+
"Duplicate cntlid %u with %s, rejecting\n",
2359+
ctrl->cntlid, dev_name(tmp->device));
2360+
return false;
2361+
}
23492362

2350-
mutex_lock(&subsys->lock);
2351-
list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
2352-
if (ctrl->state != NVME_CTRL_DELETING &&
2353-
ctrl->state != NVME_CTRL_DEAD)
2354-
count++;
2363+
if ((id->cmic & (1 << 1)) ||
2364+
(ctrl->opts && ctrl->opts->discovery_nqn))
2365+
continue;
2366+
2367+
dev_err(ctrl->device,
2368+
"Subsystem does not support multiple controllers\n");
2369+
return false;
23552370
}
2356-
mutex_unlock(&subsys->lock);
23572371

2358-
return count;
2372+
return true;
23592373
}
23602374

23612375
static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
@@ -2395,22 +2409,13 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
23952409
mutex_lock(&nvme_subsystems_lock);
23962410
found = __nvme_find_get_subsystem(subsys->subnqn);
23972411
if (found) {
2398-
/*
2399-
* Verify that the subsystem actually supports multiple
2400-
* controllers, else bail out.
2401-
*/
2402-
if (!(ctrl->opts && ctrl->opts->discovery_nqn) &&
2403-
nvme_active_ctrls(found) && !(id->cmic & (1 << 1))) {
2404-
dev_err(ctrl->device,
2405-
"ignoring ctrl due to duplicate subnqn (%s).\n",
2406-
found->subnqn);
2407-
nvme_put_subsystem(found);
2408-
ret = -EINVAL;
2409-
goto out_unlock;
2410-
}
2411-
24122412
__nvme_release_subsystem(subsys);
24132413
subsys = found;
2414+
2415+
if (!nvme_validate_cntlid(subsys, ctrl, id)) {
2416+
ret = -EINVAL;
2417+
goto out_put_subsystem;
2418+
}
24142419
} else {
24152420
ret = device_add(&subsys->dev);
24162421
if (ret) {
@@ -2422,23 +2427,20 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
24222427
list_add_tail(&subsys->entry, &nvme_subsystems);
24232428
}
24242429

2425-
ctrl->subsys = subsys;
2426-
mutex_unlock(&nvme_subsystems_lock);
2427-
24282430
if (sysfs_create_link(&subsys->dev.kobj, &ctrl->device->kobj,
24292431
dev_name(ctrl->device))) {
24302432
dev_err(ctrl->device,
24312433
"failed to create sysfs link from subsystem.\n");
2432-
/* the transport driver will eventually put the subsystem */
2433-
return -EINVAL;
2434+
goto out_put_subsystem;
24342435
}
24352436

2436-
mutex_lock(&subsys->lock);
2437+
ctrl->subsys = subsys;
24372438
list_add_tail(&ctrl->subsys_entry, &subsys->ctrls);
2438-
mutex_unlock(&subsys->lock);
2439-
2439+
mutex_unlock(&nvme_subsystems_lock);
24402440
return 0;
24412441

2442+
out_put_subsystem:
2443+
nvme_put_subsystem(subsys);
24422444
out_unlock:
24432445
mutex_unlock(&nvme_subsystems_lock);
24442446
put_device(&subsys->dev);
@@ -3605,19 +3607,18 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
36053607
{
36063608
u32 aer_notice_type = (result & 0xff00) >> 8;
36073609

3610+
trace_nvme_async_event(ctrl, aer_notice_type);
3611+
36083612
switch (aer_notice_type) {
36093613
case NVME_AER_NOTICE_NS_CHANGED:
3610-
trace_nvme_async_event(ctrl, aer_notice_type);
36113614
set_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events);
36123615
nvme_queue_scan(ctrl);
36133616
break;
36143617
case NVME_AER_NOTICE_FW_ACT_STARTING:
3615-
trace_nvme_async_event(ctrl, aer_notice_type);
36163618
queue_work(nvme_wq, &ctrl->fw_act_work);
36173619
break;
36183620
#ifdef CONFIG_NVME_MULTIPATH
36193621
case NVME_AER_NOTICE_ANA:
3620-
trace_nvme_async_event(ctrl, aer_notice_type);
36213622
if (!ctrl->ana_log_buf)
36223623
break;
36233624
queue_work(nvme_wq, &ctrl->ana_work);
@@ -3696,10 +3697,10 @@ static void nvme_free_ctrl(struct device *dev)
36963697
__free_page(ctrl->discard_page);
36973698

36983699
if (subsys) {
3699-
mutex_lock(&subsys->lock);
3700+
mutex_lock(&nvme_subsystems_lock);
37003701
list_del(&ctrl->subsys_entry);
3701-
mutex_unlock(&subsys->lock);
37023702
sysfs_remove_link(&subsys->dev.kobj, dev_name(ctrl->device));
3703+
mutex_unlock(&nvme_subsystems_lock);
37033704
}
37043705

37053706
ctrl->ops->free_ctrl(ctrl);

drivers/nvme/host/fabrics.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ EXPORT_SYMBOL_GPL(nvmf_free_options);
978978
NVMF_OPT_DISABLE_SQFLOW)
979979

980980
static struct nvme_ctrl *
981-
nvmf_create_ctrl(struct device *dev, const char *buf, size_t count)
981+
nvmf_create_ctrl(struct device *dev, const char *buf)
982982
{
983983
struct nvmf_ctrl_options *opts;
984984
struct nvmf_transport_ops *ops;
@@ -1073,7 +1073,7 @@ static ssize_t nvmf_dev_write(struct file *file, const char __user *ubuf,
10731073
goto out_unlock;
10741074
}
10751075

1076-
ctrl = nvmf_create_ctrl(nvmf_device, buf, count);
1076+
ctrl = nvmf_create_ctrl(nvmf_device, buf);
10771077
if (IS_ERR(ctrl)) {
10781078
ret = PTR_ERR(ctrl);
10791079
goto out_unlock;

drivers/nvme/host/fc.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ static LIST_HEAD(nvme_fc_lport_list);
202202
static DEFINE_IDA(nvme_fc_local_port_cnt);
203203
static DEFINE_IDA(nvme_fc_ctrl_cnt);
204204

205-
205+
static struct workqueue_struct *nvme_fc_wq;
206206

207207
/*
208208
* These items are short-term. They will eventually be moved into
@@ -2054,7 +2054,7 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg)
20542054
*/
20552055
if (ctrl->ctrl.state == NVME_CTRL_CONNECTING) {
20562056
active = atomic_xchg(&ctrl->err_work_active, 1);
2057-
if (!active && !schedule_work(&ctrl->err_work)) {
2057+
if (!active && !queue_work(nvme_fc_wq, &ctrl->err_work)) {
20582058
atomic_set(&ctrl->err_work_active, 0);
20592059
WARN_ON(1);
20602060
}
@@ -3399,6 +3399,10 @@ static int __init nvme_fc_init_module(void)
33993399
{
34003400
int ret;
34013401

3402+
nvme_fc_wq = alloc_workqueue("nvme_fc_wq", WQ_MEM_RECLAIM, 0);
3403+
if (!nvme_fc_wq)
3404+
return -ENOMEM;
3405+
34023406
/*
34033407
* NOTE:
34043408
* It is expected that in the future the kernel will combine
@@ -3416,7 +3420,7 @@ static int __init nvme_fc_init_module(void)
34163420
ret = class_register(&fc_class);
34173421
if (ret) {
34183422
pr_err("couldn't register class fc\n");
3419-
return ret;
3423+
goto out_destroy_wq;
34203424
}
34213425

34223426
/*
@@ -3440,6 +3444,9 @@ static int __init nvme_fc_init_module(void)
34403444
device_destroy(&fc_class, MKDEV(0, 0));
34413445
out_destroy_class:
34423446
class_unregister(&fc_class);
3447+
out_destroy_wq:
3448+
destroy_workqueue(nvme_fc_wq);
3449+
34433450
return ret;
34443451
}
34453452

@@ -3456,6 +3463,7 @@ static void __exit nvme_fc_exit_module(void)
34563463

34573464
device_destroy(&fc_class, MKDEV(0, 0));
34583465
class_unregister(&fc_class);
3466+
destroy_workqueue(nvme_fc_wq);
34593467
}
34603468

34613469
module_init(nvme_fc_init_module);

drivers/nvme/host/multipath.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns,
3131
sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance);
3232
} else if (ns->head->disk) {
3333
sprintf(disk_name, "nvme%dc%dn%d", ctrl->subsys->instance,
34-
ctrl->cntlid, ns->head->instance);
34+
ctrl->instance, ns->head->instance);
3535
*flags = GENHD_FL_HIDDEN;
3636
} else {
3737
sprintf(disk_name, "nvme%dn%d", ctrl->subsys->instance,

drivers/nvme/host/pci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
12961296
switch (dev->ctrl.state) {
12971297
case NVME_CTRL_DELETING:
12981298
shutdown = true;
1299+
/* fall through */
12991300
case NVME_CTRL_CONNECTING:
13001301
case NVME_CTRL_RESETTING:
13011302
dev_warn_ratelimited(dev->ctrl.device,
@@ -2280,15 +2281,14 @@ static int nvme_dev_add(struct nvme_dev *dev)
22802281
return ret;
22812282
}
22822283
dev->ctrl.tagset = &dev->tagset;
2283-
2284-
nvme_dbbuf_set(dev);
22852284
} else {
22862285
blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1);
22872286

22882287
/* Free previously allocated queues that are no longer usable */
22892288
nvme_free_queues(dev, dev->online_queues);
22902289
}
22912290

2291+
nvme_dbbuf_set(dev);
22922292
return 0;
22932293
}
22942294

drivers/nvme/host/rdma.c

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -697,15 +697,6 @@ static int nvme_rdma_alloc_io_queues(struct nvme_rdma_ctrl *ctrl)
697697
return ret;
698698
}
699699

700-
static void nvme_rdma_free_tagset(struct nvme_ctrl *nctrl,
701-
struct blk_mq_tag_set *set)
702-
{
703-
struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl);
704-
705-
blk_mq_free_tag_set(set);
706-
nvme_rdma_dev_put(ctrl->device);
707-
}
708-
709700
static struct blk_mq_tag_set *nvme_rdma_alloc_tagset(struct nvme_ctrl *nctrl,
710701
bool admin)
711702
{
@@ -744,32 +735,17 @@ static struct blk_mq_tag_set *nvme_rdma_alloc_tagset(struct nvme_ctrl *nctrl,
744735

745736
ret = blk_mq_alloc_tag_set(set);
746737
if (ret)
747-
goto out;
748-
749-
/*
750-
* We need a reference on the device as long as the tag_set is alive,
751-
* as the MRs in the request structures need a valid ib_device.
752-
*/
753-
ret = nvme_rdma_dev_get(ctrl->device);
754-
if (!ret) {
755-
ret = -EINVAL;
756-
goto out_free_tagset;
757-
}
738+
return ERR_PTR(ret);
758739

759740
return set;
760-
761-
out_free_tagset:
762-
blk_mq_free_tag_set(set);
763-
out:
764-
return ERR_PTR(ret);
765741
}
766742

767743
static void nvme_rdma_destroy_admin_queue(struct nvme_rdma_ctrl *ctrl,
768744
bool remove)
769745
{
770746
if (remove) {
771747
blk_cleanup_queue(ctrl->ctrl.admin_q);
772-
nvme_rdma_free_tagset(&ctrl->ctrl, ctrl->ctrl.admin_tagset);
748+
blk_mq_free_tag_set(ctrl->ctrl.admin_tagset);
773749
}
774750
if (ctrl->async_event_sqe.data) {
775751
nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe,
@@ -847,7 +823,7 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl,
847823
blk_cleanup_queue(ctrl->ctrl.admin_q);
848824
out_free_tagset:
849825
if (new)
850-
nvme_rdma_free_tagset(&ctrl->ctrl, ctrl->ctrl.admin_tagset);
826+
blk_mq_free_tag_set(ctrl->ctrl.admin_tagset);
851827
out_free_async_qe:
852828
nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe,
853829
sizeof(struct nvme_command), DMA_TO_DEVICE);
@@ -862,7 +838,7 @@ static void nvme_rdma_destroy_io_queues(struct nvme_rdma_ctrl *ctrl,
862838
{
863839
if (remove) {
864840
blk_cleanup_queue(ctrl->ctrl.connect_q);
865-
nvme_rdma_free_tagset(&ctrl->ctrl, ctrl->ctrl.tagset);
841+
blk_mq_free_tag_set(ctrl->ctrl.tagset);
866842
}
867843
nvme_rdma_free_io_queues(ctrl);
868844
}
@@ -903,7 +879,7 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new)
903879
blk_cleanup_queue(ctrl->ctrl.connect_q);
904880
out_free_tag_set:
905881
if (new)
906-
nvme_rdma_free_tagset(&ctrl->ctrl, ctrl->ctrl.tagset);
882+
blk_mq_free_tag_set(ctrl->ctrl.tagset);
907883
out_free_io_queues:
908884
nvme_rdma_free_io_queues(ctrl);
909885
return ret;

drivers/nvme/host/trace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ TRACE_EVENT(nvme_async_event,
167167
aer_name(NVME_AER_NOTICE_NS_CHANGED),
168168
aer_name(NVME_AER_NOTICE_ANA),
169169
aer_name(NVME_AER_NOTICE_FW_ACT_STARTING),
170+
aer_name(NVME_AER_NOTICE_DISC_CHANGED),
170171
aer_name(NVME_AER_ERROR),
171172
aer_name(NVME_AER_SMART),
172173
aer_name(NVME_AER_CSS),

include/linux/nvme.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,9 +1246,9 @@ enum {
12461246
NVME_SC_FW_NEEDS_SUBSYS_RESET = 0x110,
12471247
NVME_SC_FW_NEEDS_RESET = 0x111,
12481248
NVME_SC_FW_NEEDS_MAX_TIME = 0x112,
1249-
NVME_SC_FW_ACIVATE_PROHIBITED = 0x113,
1249+
NVME_SC_FW_ACTIVATE_PROHIBITED = 0x113,
12501250
NVME_SC_OVERLAPPING_RANGE = 0x114,
1251-
NVME_SC_NS_INSUFFICENT_CAP = 0x115,
1251+
NVME_SC_NS_INSUFFICIENT_CAP = 0x115,
12521252
NVME_SC_NS_ID_UNAVAILABLE = 0x116,
12531253
NVME_SC_NS_ALREADY_ATTACHED = 0x118,
12541254
NVME_SC_NS_IS_PRIVATE = 0x119,

0 commit comments

Comments
 (0)