From: Jens Axboe Date: Fri, 15 Jun 2018 14:11:05 +0000 (-0600) Subject: Merge branch 'nvme-4.18' of git://git.infradead.org/nvme into for-linus X-Git-Tag: v4.18-rc1~1^2~2 X-Git-Url: http://git.samba.org/samba.git/?p=sfrench%2Fcifs-2.6.git;a=commitdiff_plain;h=95c7c09f4cc8ac3cfbcf4382ff3f7ecfd97e8ed6;hp=-c Merge branch 'nvme-4.18' of git://git.infradead.org/nvme into for-linus Pull NVMe fixes from Christoph: "Fix various little regressions introduced in this merge window, plus a rework of the fibre channel connect and reconnect path to share the code instead of having separate sets of bugs. Last but not least a trivial trace point addition from Hannes." * 'nvme-4.18' of git://git.infradead.org/nvme: nvme-fabrics: fix and refine state checks in __nvmf_check_ready nvme-fabrics: handle the admin-only case properly in nvmf_check_ready nvme-fabrics: refactor queue ready check blk-mq: remove blk_mq_tagset_iter nvme: remove nvme_reinit_tagset nvme-fc: fix nulling of queue data on reconnect nvme-fc: remove reinit_request routine nvme-fc: change controllers first connect to use reconnect path nvme: don't rely on the changed namespace list log nvmet: free smart-log buffer after use nvme-rdma: fix error flow during mapping request data nvme: add bio remapping tracepoint nvme: fix NULL pointer dereference in nvme_init_subsystem --- 95c7c09f4cc8ac3cfbcf4382ff3f7ecfd97e8ed6 diff --combined drivers/nvme/host/core.c index effb1309682e,020a00f932a0..21710a7460c8 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@@ -357,7 -357,7 +357,7 @@@ static void nvme_free_ns_head(struct kr nvme_mpath_remove_disk(head); ida_simple_remove(&head->subsys->ns_ida, head->instance); list_del_init(&head->entry); - cleanup_srcu_struct(&head->srcu); + cleanup_srcu_struct_quiesced(&head->srcu); nvme_put_subsystem(head->subsys); kfree(head); } @@@ -2208,7 -2208,7 +2208,7 @@@ static int nvme_init_subsystem(struct n * Verify that the subsystem actually supports multiple * controllers, else bail out. */ - if (!ctrl->opts->discovery_nqn && + if (!(ctrl->opts && ctrl->opts->discovery_nqn) && nvme_active_ctrls(found) && !(id->cmic & (1 << 1))) { dev_err(ctrl->device, "ignoring ctrl due to duplicate subnqn (%s).\n", @@@ -3197,40 -3197,28 +3197,28 @@@ static void nvme_scan_ns_sequential(str nvme_remove_invalid_namespaces(ctrl, nn); } - static bool nvme_scan_changed_ns_log(struct nvme_ctrl *ctrl) + static void nvme_clear_changed_ns_log(struct nvme_ctrl *ctrl) { size_t log_size = NVME_MAX_CHANGED_NAMESPACES * sizeof(__le32); __le32 *log; - int error, i; - bool ret = false; + int error; log = kzalloc(log_size, GFP_KERNEL); if (!log) - return false; + return; + /* + * We need to read the log to clear the AEN, but we don't want to rely + * on it for the changed namespace information as userspace could have + * raced with us in reading the log page, which could cause us to miss + * updates. + */ error = nvme_get_log(ctrl, NVME_LOG_CHANGED_NS, log, log_size); - if (error) { + if (error) dev_warn(ctrl->device, "reading changed ns log failed: %d\n", error); - goto out_free_log; - } - - if (log[0] == cpu_to_le32(0xffffffff)) - goto out_free_log; - - for (i = 0; i < NVME_MAX_CHANGED_NAMESPACES; i++) { - u32 nsid = le32_to_cpu(log[i]); - if (nsid == 0) - break; - dev_info(ctrl->device, "rescanning namespace %d.\n", nsid); - nvme_validate_ns(ctrl, nsid); - } - ret = true; - - out_free_log: kfree(log); - return ret; } static void nvme_scan_work(struct work_struct *work) @@@ -3246,9 -3234,8 +3234,8 @@@ WARN_ON_ONCE(!ctrl->tagset); if (test_and_clear_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) { - if (nvme_scan_changed_ns_log(ctrl)) - goto out_sort_namespaces; dev_info(ctrl->device, "rescanning namespaces.\n"); + nvme_clear_changed_ns_log(ctrl); } if (nvme_identify_ctrl(ctrl, &id)) @@@ -3263,7 -3250,6 +3250,6 @@@ nvme_scan_ns_sequential(ctrl, nn); out_free_id: kfree(id); - out_sort_namespaces: down_write(&ctrl->namespaces_rwsem); list_sort(NULL, &ctrl->namespaces, ns_cmp); up_write(&ctrl->namespaces_rwsem); @@@ -3641,16 -3627,6 +3627,6 @@@ void nvme_start_queues(struct nvme_ctr } EXPORT_SYMBOL_GPL(nvme_start_queues); - int nvme_reinit_tagset(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set) - { - if (!ctrl->ops->reinit_request) - return 0; - - return blk_mq_tagset_iter(set, set->driver_data, - ctrl->ops->reinit_request); - } - EXPORT_SYMBOL_GPL(nvme_reinit_tagset); - int __init nvme_core_init(void) { int result = -ENOMEM;