Skip to content

Commit 90b4622

Browse files
committed
Merge tag 'nvme-6.5-2023-07-13' of git://git.infradead.org/nvme into block-6.5
Pull NVMe fixes from Keith: "nvme fixes for Linux 6.5 - Don't require quirk to use duplicate namespace identifiers (Christoph, Sagi) - One more BOGUS_NID quirk (Pankaj) - IO timeout and error hanlding fixes for PCI (Keith) - Enhanced metadata format mask fix (Ankit) - Association race condition fix for fibre channel (Michael) - Correct debugfs error checks (Minjie) - Use PAGE_SECTORS_SHIFT where needed (Damien) - Reduce kernel logs for legacy nguid attribute (Keith) - Use correct dma direction when unmapping metadata (Ming)" * tag 'nvme-6.5-2023-07-13' of git://git.infradead.org/nvme: nvme-pci: fix DMA direction of unmapping integrity data nvme: don't reject probe due to duplicate IDs for single-ported PCIe devices nvme: ensure disabling pairs with unquiesce nvme-fc: fix race between error recovery and creating association nvme-fc: return non-zero status code when fails to create association nvme: fix parameter check in nvme_fault_inject_init() nvme: warn only once for legacy uuid attribute nvme: fix the NVME_ID_NS_NVM_STS_MASK definition nvmet: use PAGE_SECTORS_SHIFT nvme: add BOGUS_NID quirk for Samsung SM953
2 parents 5c17f45 + b8f6446 commit 90b4622

File tree

8 files changed

+89
-25
lines changed

8 files changed

+89
-25
lines changed

drivers/nvme/host/core.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3431,10 +3431,40 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
34313431

34323432
ret = nvme_global_check_duplicate_ids(ctrl->subsys, &info->ids);
34333433
if (ret) {
3434-
dev_err(ctrl->device,
3435-
"globally duplicate IDs for nsid %d\n", info->nsid);
3434+
/*
3435+
* We've found two different namespaces on two different
3436+
* subsystems that report the same ID. This is pretty nasty
3437+
* for anything that actually requires unique device
3438+
* identification. In the kernel we need this for multipathing,
3439+
* and in user space the /dev/disk/by-id/ links rely on it.
3440+
*
3441+
* If the device also claims to be multi-path capable back off
3442+
* here now and refuse the probe the second device as this is a
3443+
* recipe for data corruption. If not this is probably a
3444+
* cheap consumer device if on the PCIe bus, so let the user
3445+
* proceed and use the shiny toy, but warn that with changing
3446+
* probing order (which due to our async probing could just be
3447+
* device taking longer to startup) the other device could show
3448+
* up at any time.
3449+
*/
34363450
nvme_print_device_info(ctrl);
3437-
return ret;
3451+
if ((ns->ctrl->ops->flags & NVME_F_FABRICS) || /* !PCIe */
3452+
((ns->ctrl->subsys->cmic & NVME_CTRL_CMIC_MULTI_CTRL) &&
3453+
info->is_shared)) {
3454+
dev_err(ctrl->device,
3455+
"ignoring nsid %d because of duplicate IDs\n",
3456+
info->nsid);
3457+
return ret;
3458+
}
3459+
3460+
dev_err(ctrl->device,
3461+
"clearing duplicate IDs for nsid %d\n", info->nsid);
3462+
dev_err(ctrl->device,
3463+
"use of /dev/disk/by-id/ may cause data corruption\n");
3464+
memset(&info->ids.nguid, 0, sizeof(info->ids.nguid));
3465+
memset(&info->ids.uuid, 0, sizeof(info->ids.uuid));
3466+
memset(&info->ids.eui64, 0, sizeof(info->ids.eui64));
3467+
ctrl->quirks |= NVME_QUIRK_BOGUS_NID;
34383468
}
34393469

34403470
mutex_lock(&ctrl->subsys->lock);

drivers/nvme/host/fault_inject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj,
2727

2828
/* create debugfs directory and attribute */
2929
parent = debugfs_create_dir(dev_name, NULL);
30-
if (!parent) {
30+
if (IS_ERR(parent)) {
3131
pr_warn("%s: failed to create debugfs directory\n", dev_name);
3232
return;
3333
}

drivers/nvme/host/fc.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,14 +2548,24 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg)
25482548
* the controller. Abort any ios on the association and let the
25492549
* create_association error path resolve things.
25502550
*/
2551-
if (ctrl->ctrl.state == NVME_CTRL_CONNECTING) {
2552-
__nvme_fc_abort_outstanding_ios(ctrl, true);
2551+
enum nvme_ctrl_state state;
2552+
unsigned long flags;
2553+
2554+
spin_lock_irqsave(&ctrl->lock, flags);
2555+
state = ctrl->ctrl.state;
2556+
if (state == NVME_CTRL_CONNECTING) {
25532557
set_bit(ASSOC_FAILED, &ctrl->flags);
2558+
spin_unlock_irqrestore(&ctrl->lock, flags);
2559+
__nvme_fc_abort_outstanding_ios(ctrl, true);
2560+
dev_warn(ctrl->ctrl.device,
2561+
"NVME-FC{%d}: transport error during (re)connect\n",
2562+
ctrl->cnum);
25542563
return;
25552564
}
2565+
spin_unlock_irqrestore(&ctrl->lock, flags);
25562566

25572567
/* Otherwise, only proceed if in LIVE state - e.g. on first error */
2558-
if (ctrl->ctrl.state != NVME_CTRL_LIVE)
2568+
if (state != NVME_CTRL_LIVE)
25592569
return;
25602570

25612571
dev_warn(ctrl->ctrl.device,
@@ -3110,7 +3120,9 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
31103120
*/
31113121

31123122
ret = nvme_enable_ctrl(&ctrl->ctrl);
3113-
if (ret || test_bit(ASSOC_FAILED, &ctrl->flags))
3123+
if (!ret && test_bit(ASSOC_FAILED, &ctrl->flags))
3124+
ret = -EIO;
3125+
if (ret)
31143126
goto out_disconnect_admin_queue;
31153127

31163128
ctrl->ctrl.max_segments = ctrl->lport->ops->max_sgl_segments;
@@ -3120,7 +3132,9 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
31203132
nvme_unquiesce_admin_queue(&ctrl->ctrl);
31213133

31223134
ret = nvme_init_ctrl_finish(&ctrl->ctrl, false);
3123-
if (ret || test_bit(ASSOC_FAILED, &ctrl->flags))
3135+
if (!ret && test_bit(ASSOC_FAILED, &ctrl->flags))
3136+
ret = -EIO;
3137+
if (ret)
31243138
goto out_disconnect_admin_queue;
31253139

31263140
/* sanity checks */
@@ -3165,10 +3179,16 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
31653179
else
31663180
ret = nvme_fc_recreate_io_queues(ctrl);
31673181
}
3168-
if (ret || test_bit(ASSOC_FAILED, &ctrl->flags))
3169-
goto out_term_aen_ops;
31703182

3183+
spin_lock_irqsave(&ctrl->lock, flags);
3184+
if (!ret && test_bit(ASSOC_FAILED, &ctrl->flags))
3185+
ret = -EIO;
3186+
if (ret) {
3187+
spin_unlock_irqrestore(&ctrl->lock, flags);
3188+
goto out_term_aen_ops;
3189+
}
31713190
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
3191+
spin_unlock_irqrestore(&ctrl->lock, flags);
31723192

31733193
ctrl->ctrl.nr_reconnects = 0;
31743194

@@ -3180,6 +3200,9 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
31803200
out_term_aen_ops:
31813201
nvme_fc_term_aen_ops(ctrl);
31823202
out_disconnect_admin_queue:
3203+
dev_warn(ctrl->ctrl.device,
3204+
"NVME-FC{%d}: create_assoc failed, assoc_id %llx ret %d\n",
3205+
ctrl->cnum, ctrl->association_id, ret);
31833206
/* send a Disconnect(association) LS to fc-nvme target */
31843207
nvme_fc_xmt_disconnect_assoc(ctrl);
31853208
spin_lock_irqsave(&ctrl->lock, flags);

drivers/nvme/host/pci.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ static __always_inline void nvme_pci_unmap_rq(struct request *req)
967967
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
968968

969969
dma_unmap_page(dev->dev, iod->meta_dma,
970-
rq_integrity_vec(req)->bv_len, rq_data_dir(req));
970+
rq_integrity_vec(req)->bv_len, rq_dma_dir(req));
971971
}
972972

973973
if (blk_rq_nr_phys_segments(req))
@@ -1298,9 +1298,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
12981298
*/
12991299
if (nvme_should_reset(dev, csts)) {
13001300
nvme_warn_reset(dev, csts);
1301-
nvme_dev_disable(dev, false);
1302-
nvme_reset_ctrl(&dev->ctrl);
1303-
return BLK_EH_DONE;
1301+
goto disable;
13041302
}
13051303

13061304
/*
@@ -1351,10 +1349,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
13511349
"I/O %d QID %d timeout, reset controller\n",
13521350
req->tag, nvmeq->qid);
13531351
nvme_req(req)->flags |= NVME_REQ_CANCELLED;
1354-
nvme_dev_disable(dev, false);
1355-
nvme_reset_ctrl(&dev->ctrl);
1356-
1357-
return BLK_EH_DONE;
1352+
goto disable;
13581353
}
13591354

13601355
if (atomic_dec_return(&dev->ctrl.abort_limit) < 0) {
@@ -1391,6 +1386,15 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
13911386
* as the device then is in a faulty state.
13921387
*/
13931388
return BLK_EH_RESET_TIMER;
1389+
1390+
disable:
1391+
if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING))
1392+
return BLK_EH_DONE;
1393+
1394+
nvme_dev_disable(dev, false);
1395+
if (nvme_try_sched_reset(&dev->ctrl))
1396+
nvme_unquiesce_io_queues(&dev->ctrl);
1397+
return BLK_EH_DONE;
13941398
}
13951399

13961400
static void nvme_free_queue(struct nvme_queue *nvmeq)
@@ -3278,6 +3282,10 @@ static pci_ers_result_t nvme_error_detected(struct pci_dev *pdev,
32783282
case pci_channel_io_frozen:
32793283
dev_warn(dev->ctrl.device,
32803284
"frozen state error detected, reset controller\n");
3285+
if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING)) {
3286+
nvme_dev_disable(dev, true);
3287+
return PCI_ERS_RESULT_DISCONNECT;
3288+
}
32813289
nvme_dev_disable(dev, false);
32823290
return PCI_ERS_RESULT_NEED_RESET;
32833291
case pci_channel_io_perm_failure:
@@ -3294,7 +3302,8 @@ static pci_ers_result_t nvme_slot_reset(struct pci_dev *pdev)
32943302

32953303
dev_info(dev->ctrl.device, "restart after slot reset\n");
32963304
pci_restore_state(pdev);
3297-
nvme_reset_ctrl(&dev->ctrl);
3305+
if (!nvme_try_sched_reset(&dev->ctrl))
3306+
nvme_unquiesce_io_queues(&dev->ctrl);
32983307
return PCI_ERS_RESULT_RECOVERED;
32993308
}
33003309

@@ -3396,6 +3405,8 @@ static const struct pci_device_id nvme_id_table[] = {
33963405
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
33973406
{ PCI_DEVICE(0x144d, 0xa809), /* Samsung MZALQ256HBJD 256G */
33983407
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
3408+
{ PCI_DEVICE(0x144d, 0xa802), /* Samsung SM953 */
3409+
.driver_data = NVME_QUIRK_BOGUS_NID, },
33993410
{ PCI_DEVICE(0x1cc4, 0x6303), /* UMIS RPJTJ512MGE1QDY 512G */
34003411
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
34013412
{ PCI_DEVICE(0x1cc4, 0x6302), /* UMIS RPJTJ256MGE1QDY 256G */

drivers/nvme/host/sysfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
9292
* we have no UUID set
9393
*/
9494
if (uuid_is_null(&ids->uuid)) {
95-
dev_warn_ratelimited(dev,
95+
dev_warn_once(dev,
9696
"No UUID available providing old NGUID\n");
9797
return sysfs_emit(buf, "%pU\n", ids->nguid);
9898
}

drivers/nvme/target/loop.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl)
373373
goto out_cleanup_tagset;
374374

375375
ctrl->ctrl.max_hw_sectors =
376-
(NVME_LOOP_MAX_SEGMENTS - 1) << (PAGE_SHIFT - 9);
376+
(NVME_LOOP_MAX_SEGMENTS - 1) << PAGE_SECTORS_SHIFT;
377377

378378
nvme_unquiesce_admin_queue(&ctrl->ctrl);
379379

drivers/nvme/target/passthru.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,14 @@ static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req)
102102
* which depends on the host's memory fragementation. To solve this,
103103
* ensure mdts is limited to the pages equal to the number of segments.
104104
*/
105-
max_hw_sectors = min_not_zero(pctrl->max_segments << (PAGE_SHIFT - 9),
105+
max_hw_sectors = min_not_zero(pctrl->max_segments << PAGE_SECTORS_SHIFT,
106106
pctrl->max_hw_sectors);
107107

108108
/*
109109
* nvmet_passthru_map_sg is limitted to using a single bio so limit
110110
* the mdts based on BIO_MAX_VECS as well
111111
*/
112-
max_hw_sectors = min_not_zero(BIO_MAX_VECS << (PAGE_SHIFT - 9),
112+
max_hw_sectors = min_not_zero(BIO_MAX_VECS << PAGE_SECTORS_SHIFT,
113113
max_hw_sectors);
114114

115115
page_shift = NVME_CAP_MPSMIN(ctrl->cap) + 12;

include/linux/nvme.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ struct nvme_id_ns_nvm {
473473
};
474474

475475
enum {
476-
NVME_ID_NS_NVM_STS_MASK = 0x3f,
476+
NVME_ID_NS_NVM_STS_MASK = 0x7f,
477477
NVME_ID_NS_NVM_GUARD_SHIFT = 7,
478478
NVME_ID_NS_NVM_GUARD_MASK = 0x3,
479479
};

0 commit comments

Comments
 (0)