nvme fixes for Linux 5.14:

- tracing fix (Keith Busch)
  - fix multipath head refcounting (Hannes Reinecke)
  - Write Zeroes vs PI fix (me)
  - drop a bogus WARN_ON (Zhihao Cheng)
 -----BEGIN PGP SIGNATURE-----
 
 iQI/BAABCgApFiEEgdbnc3r/njty3Iq9D55TZVIEUYMFAmD5vv0LHGhjaEBsc3Qu
 ZGUACgkQD55TZVIEUYPesQ/8DcdEwxWf7BhPhnPtAn9MIcX4ZdpMd99+88nlXQ1p
 3Ysoqc/u79Wuh3Z42mKSg/csU888tzI3brjijIt6+NGPnPjiNVtFdYlIATke1mJp
 crrSGTXANFsVj3qIJWn5otUp2tXA1TMcPPcjvogPb+qYAOLkGqtUqLUpsZqW5NkZ
 4fEj8+7Cfe1wPwCRQSTIDWDOR5R+FTR3/zmfxdmzudvxslRHD//8rlB/XPwamzEt
 1dADaAeZobExJYhGB3HhQH9JbXmnDqQZHZWycYx8VqkigKcLtkcZ6ymTsqYXA65t
 3g13yERWosly+qBJ1u1z9I60FSKZn3+KlilQLRW2ykWixgmgx/nPUARIY2g72zgA
 apsKzMIlUeQu0qmAhcO+dsUsPmRiqrEFoJh3lRXfOlQf6xAgPpy24089LRvkC8oG
 dx+xsIh5TVXIY8Ipa37zYGoutiQ0ebZVTC/i9ZamU27cvV6HeeI0vDublJe6QCB6
 W7j9PsYiUxyCBR2Fb43ntdDlrqJRRSLpC1r5sNv31NefUIfKCKmC4d2A0Cmapg5K
 Tm4AeKiUhyI7kVTf3BlBVKuBFbEN7hB+O9pk6PF/fpEKmv9MFRXnxdj2BBMx45Pg
 q97NfSS3AUUO9K/HMGw5VKqn6HuSzXyxNkIpu8Xk3/d4Gt20GfSQL70EYt7+K5mg
 j0I=
 =8oM5
 -----END PGP SIGNATURE-----

Merge tag 'nvme-5.14-2021-07-22' of git://git.infradead.org/nvme into block-5.14

Pull NVMe fixes from Christoph:

"nvme fixes for Linux 5.14:

 - tracing fix (Keith Busch)
 - fix multipath head refcounting (Hannes Reinecke)
 - Write Zeroes vs PI fix (me)
 - drop a bogus WARN_ON (Zhihao Cheng)"

* tag 'nvme-5.14-2021-07-22' of git://git.infradead.org/nvme:
  nvme: set the PRACT bit when using Write Zeroes with T10 PI
  nvme: fix nvme_setup_command metadata trace event
  nvme: fix refcounting imbalance when all paths are down
  nvme-pci: don't WARN_ON in nvme_reset_work if ctrl.state is not RESETTING
This commit is contained in:
Jens Axboe 2021-07-22 14:23:55 -06:00
commit 7054133da3
5 changed files with 31 additions and 18 deletions

View File

@ -900,6 +900,9 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns,
cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req))); cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req)));
cmnd->write_zeroes.length = cmnd->write_zeroes.length =
cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1); cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
if (nvme_ns_has_pi(ns))
cmnd->write_zeroes.control = cpu_to_le16(NVME_RW_PRINFO_PRACT);
else
cmnd->write_zeroes.control = 0; cmnd->write_zeroes.control = 0;
return BLK_STS_OK; return BLK_STS_OK;
} }
@ -3807,6 +3810,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
static void nvme_ns_remove(struct nvme_ns *ns) static void nvme_ns_remove(struct nvme_ns *ns)
{ {
bool last_path = false;
if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags)) if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags))
return; return;
@ -3815,8 +3820,6 @@ static void nvme_ns_remove(struct nvme_ns *ns)
mutex_lock(&ns->ctrl->subsys->lock); mutex_lock(&ns->ctrl->subsys->lock);
list_del_rcu(&ns->siblings); list_del_rcu(&ns->siblings);
if (list_empty(&ns->head->list))
list_del_init(&ns->head->entry);
mutex_unlock(&ns->ctrl->subsys->lock); mutex_unlock(&ns->ctrl->subsys->lock);
synchronize_rcu(); /* guarantee not available in head->list */ synchronize_rcu(); /* guarantee not available in head->list */
@ -3836,7 +3839,15 @@ static void nvme_ns_remove(struct nvme_ns *ns)
list_del_init(&ns->list); list_del_init(&ns->list);
up_write(&ns->ctrl->namespaces_rwsem); up_write(&ns->ctrl->namespaces_rwsem);
nvme_mpath_check_last_path(ns); /* Synchronize with nvme_init_ns_head() */
mutex_lock(&ns->head->subsys->lock);
if (list_empty(&ns->head->list)) {
list_del_init(&ns->head->entry);
last_path = true;
}
mutex_unlock(&ns->head->subsys->lock);
if (last_path)
nvme_mpath_shutdown_disk(ns->head);
nvme_put_ns(ns); nvme_put_ns(ns);
} }

View File

@ -760,14 +760,21 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id)
#endif #endif
} }
void nvme_mpath_remove_disk(struct nvme_ns_head *head) void nvme_mpath_shutdown_disk(struct nvme_ns_head *head)
{ {
if (!head->disk) if (!head->disk)
return; return;
kblockd_schedule_work(&head->requeue_work);
if (head->disk->flags & GENHD_FL_UP) { if (head->disk->flags & GENHD_FL_UP) {
nvme_cdev_del(&head->cdev, &head->cdev_device); nvme_cdev_del(&head->cdev, &head->cdev_device);
del_gendisk(head->disk); del_gendisk(head->disk);
} }
}
void nvme_mpath_remove_disk(struct nvme_ns_head *head)
{
if (!head->disk)
return;
blk_set_queue_dying(head->disk->queue); blk_set_queue_dying(head->disk->queue);
/* make sure all pending bios are cleaned up */ /* make sure all pending bios are cleaned up */
kblockd_schedule_work(&head->requeue_work); kblockd_schedule_work(&head->requeue_work);

View File

@ -716,14 +716,7 @@ void nvme_mpath_uninit(struct nvme_ctrl *ctrl);
void nvme_mpath_stop(struct nvme_ctrl *ctrl); void nvme_mpath_stop(struct nvme_ctrl *ctrl);
bool nvme_mpath_clear_current_path(struct nvme_ns *ns); bool nvme_mpath_clear_current_path(struct nvme_ns *ns);
void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl); void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl);
void nvme_mpath_shutdown_disk(struct nvme_ns_head *head);
static inline void nvme_mpath_check_last_path(struct nvme_ns *ns)
{
struct nvme_ns_head *head = ns->head;
if (head->disk && list_empty(&head->list))
kblockd_schedule_work(&head->requeue_work);
}
static inline void nvme_trace_bio_complete(struct request *req) static inline void nvme_trace_bio_complete(struct request *req)
{ {
@ -772,7 +765,7 @@ static inline bool nvme_mpath_clear_current_path(struct nvme_ns *ns)
static inline void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) static inline void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)
{ {
} }
static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) static inline void nvme_mpath_shutdown_disk(struct nvme_ns_head *head)
{ {
} }
static inline void nvme_trace_bio_complete(struct request *req) static inline void nvme_trace_bio_complete(struct request *req)

View File

@ -2631,7 +2631,9 @@ static void nvme_reset_work(struct work_struct *work)
bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL);
int result; int result;
if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING)) { if (dev->ctrl.state != NVME_CTRL_RESETTING) {
dev_warn(dev->ctrl.device, "ctrl state %d is not RESETTING\n",
dev->ctrl.state);
result = -ENODEV; result = -ENODEV;
goto out; goto out;
} }

View File

@ -56,7 +56,7 @@ TRACE_EVENT(nvme_setup_cmd,
__field(u8, fctype) __field(u8, fctype)
__field(u16, cid) __field(u16, cid)
__field(u32, nsid) __field(u32, nsid)
__field(u64, metadata) __field(bool, metadata)
__array(u8, cdw10, 24) __array(u8, cdw10, 24)
), ),
TP_fast_assign( TP_fast_assign(
@ -66,13 +66,13 @@ TRACE_EVENT(nvme_setup_cmd,
__entry->flags = cmd->common.flags; __entry->flags = cmd->common.flags;
__entry->cid = cmd->common.command_id; __entry->cid = cmd->common.command_id;
__entry->nsid = le32_to_cpu(cmd->common.nsid); __entry->nsid = le32_to_cpu(cmd->common.nsid);
__entry->metadata = le64_to_cpu(cmd->common.metadata); __entry->metadata = !!blk_integrity_rq(req);
__entry->fctype = cmd->fabrics.fctype; __entry->fctype = cmd->fabrics.fctype;
__assign_disk_name(__entry->disk, req->rq_disk); __assign_disk_name(__entry->disk, req->rq_disk);
memcpy(__entry->cdw10, &cmd->common.cdw10, memcpy(__entry->cdw10, &cmd->common.cdw10,
sizeof(__entry->cdw10)); sizeof(__entry->cdw10));
), ),
TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%llx, cmd=(%s %s)", TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%x, cmd=(%s %s)",
__entry->ctrl_id, __print_disk_name(__entry->disk), __entry->ctrl_id, __print_disk_name(__entry->disk),
__entry->qid, __entry->cid, __entry->nsid, __entry->qid, __entry->cid, __entry->nsid,
__entry->flags, __entry->metadata, __entry->flags, __entry->metadata,