Skip to content

Commit 7441308

Browse files
committed
Merge tag 'nvme-for-4.18' of git://git.infradead.org/nvme
Pull NVMe fixes from Christoph Hellwig: - fix a regression in 4.18 that causes a memory leak on probe failure (Keith Bush) - fix a deadlock in the passthrough ioctl code (Scott Bauer) - don't enable AENs if not supported (Weiping Zhang) - fix an old regression in metadata handling in the passthrough ioctl code (Roland Dreier) * tag 'nvme-for-4.18' of git://git.infradead.org/nvme: nvme: fix handling of metadata_len for NVME_IOCTL_IO_CMD nvme: don't enable AEN if not supported nvme: ensure forward progress during Admin passthru nvme-pci: fix memory leak on probe failure
2 parents 165ea0d + 9b38276 commit 7441308

File tree

2 files changed

+41
-34
lines changed

2 files changed

+41
-34
lines changed

drivers/nvme/host/core.c

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,22 @@ static struct class *nvme_subsys_class;
100100
static void nvme_ns_remove(struct nvme_ns *ns);
101101
static int nvme_revalidate_disk(struct gendisk *disk);
102102
static void nvme_put_subsystem(struct nvme_subsystem *subsys);
103+
static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
104+
unsigned nsid);
105+
106+
static void nvme_set_queue_dying(struct nvme_ns *ns)
107+
{
108+
/*
109+
* Revalidating a dead namespace sets capacity to 0. This will end
110+
* buffered writers dirtying pages that can't be synced.
111+
*/
112+
if (!ns->disk || test_and_set_bit(NVME_NS_DEAD, &ns->flags))
113+
return;
114+
revalidate_disk(ns->disk);
115+
blk_set_queue_dying(ns->queue);
116+
/* Forcibly unquiesce queues to avoid blocking dispatch */
117+
blk_mq_unquiesce_queue(ns->queue);
118+
}
103119

104120
static void nvme_queue_scan(struct nvme_ctrl *ctrl)
105121
{
@@ -1044,14 +1060,17 @@ EXPORT_SYMBOL_GPL(nvme_set_queue_count);
10441060

10451061
static void nvme_enable_aen(struct nvme_ctrl *ctrl)
10461062
{
1047-
u32 result;
1063+
u32 result, supported_aens = ctrl->oaes & NVME_AEN_SUPPORTED;
10481064
int status;
10491065

1050-
status = nvme_set_features(ctrl, NVME_FEAT_ASYNC_EVENT,
1051-
ctrl->oaes & NVME_AEN_SUPPORTED, NULL, 0, &result);
1066+
if (!supported_aens)
1067+
return;
1068+
1069+
status = nvme_set_features(ctrl, NVME_FEAT_ASYNC_EVENT, supported_aens,
1070+
NULL, 0, &result);
10521071
if (status)
10531072
dev_warn(ctrl->device, "Failed to configure AEN (cfg %x)\n",
1054-
ctrl->oaes & NVME_AEN_SUPPORTED);
1073+
supported_aens);
10551074
}
10561075

10571076
static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
@@ -1151,19 +1170,15 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
11511170

11521171
static void nvme_update_formats(struct nvme_ctrl *ctrl)
11531172
{
1154-
struct nvme_ns *ns, *next;
1155-
LIST_HEAD(rm_list);
1173+
struct nvme_ns *ns;
11561174

1157-
down_write(&ctrl->namespaces_rwsem);
1158-
list_for_each_entry(ns, &ctrl->namespaces, list) {
1159-
if (ns->disk && nvme_revalidate_disk(ns->disk)) {
1160-
list_move_tail(&ns->list, &rm_list);
1161-
}
1162-
}
1163-
up_write(&ctrl->namespaces_rwsem);
1175+
down_read(&ctrl->namespaces_rwsem);
1176+
list_for_each_entry(ns, &ctrl->namespaces, list)
1177+
if (ns->disk && nvme_revalidate_disk(ns->disk))
1178+
nvme_set_queue_dying(ns);
1179+
up_read(&ctrl->namespaces_rwsem);
11641180

1165-
list_for_each_entry_safe(ns, next, &rm_list, list)
1166-
nvme_ns_remove(ns);
1181+
nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL);
11671182
}
11681183

11691184
static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects)
@@ -1218,7 +1233,7 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
12181233
effects = nvme_passthru_start(ctrl, ns, cmd.opcode);
12191234
status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
12201235
(void __user *)(uintptr_t)cmd.addr, cmd.data_len,
1221-
(void __user *)(uintptr_t)cmd.metadata, cmd.metadata,
1236+
(void __user *)(uintptr_t)cmd.metadata, cmd.metadata_len,
12221237
0, &cmd.result, timeout);
12231238
nvme_passthru_end(ctrl, effects);
12241239

@@ -3138,7 +3153,7 @@ static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
31383153

31393154
down_write(&ctrl->namespaces_rwsem);
31403155
list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) {
3141-
if (ns->head->ns_id > nsid)
3156+
if (ns->head->ns_id > nsid || test_bit(NVME_NS_DEAD, &ns->flags))
31423157
list_move_tail(&ns->list, &rm_list);
31433158
}
31443159
up_write(&ctrl->namespaces_rwsem);
@@ -3542,19 +3557,9 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl)
35423557
if (ctrl->admin_q)
35433558
blk_mq_unquiesce_queue(ctrl->admin_q);
35443559

3545-
list_for_each_entry(ns, &ctrl->namespaces, list) {
3546-
/*
3547-
* Revalidating a dead namespace sets capacity to 0. This will
3548-
* end buffered writers dirtying pages that can't be synced.
3549-
*/
3550-
if (!ns->disk || test_and_set_bit(NVME_NS_DEAD, &ns->flags))
3551-
continue;
3552-
revalidate_disk(ns->disk);
3553-
blk_set_queue_dying(ns->queue);
3560+
list_for_each_entry(ns, &ctrl->namespaces, list)
3561+
nvme_set_queue_dying(ns);
35543562

3555-
/* Forcibly unquiesce queues to avoid blocking dispatch */
3556-
blk_mq_unquiesce_queue(ns->queue);
3557-
}
35583563
up_read(&ctrl->namespaces_rwsem);
35593564
}
35603565
EXPORT_SYMBOL_GPL(nvme_kill_queues);

drivers/nvme/host/pci.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2556,11 +2556,6 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
25562556

25572557
quirks |= check_vendor_combination_bug(pdev);
25582558

2559-
result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
2560-
quirks);
2561-
if (result)
2562-
goto release_pools;
2563-
25642559
/*
25652560
* Double check that our mempool alloc size will cover the biggest
25662561
* command we support.
@@ -2578,13 +2573,20 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
25782573
goto release_pools;
25792574
}
25802575

2576+
result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
2577+
quirks);
2578+
if (result)
2579+
goto release_mempool;
2580+
25812581
dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev));
25822582

25832583
nvme_get_ctrl(&dev->ctrl);
25842584
async_schedule(nvme_async_probe, dev);
25852585

25862586
return 0;
25872587

2588+
release_mempool:
2589+
mempool_destroy(dev->iod_mempool);
25882590
release_pools:
25892591
nvme_release_prp_pools(dev);
25902592
unmap:

0 commit comments

Comments
 (0)