Merge branch 'nvme-4.18' of git://git.infradead.org/nvme into for-linus
authorJens Axboe <axboe@kernel.dk>
Fri, 15 Jun 2018 14:11:05 +0000 (08:11 -0600)
committerJens Axboe <axboe@kernel.dk>
Fri, 15 Jun 2018 14:11:05 +0000 (08:11 -0600)
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

1  2 
drivers/nvme/host/core.c

diff --combined drivers/nvme/host/core.c
index effb1309682eb2564d77a5550526510cb891b7bd,020a00f932a0352794a152e379772de814cb5d77..21710a7460c823bbc4f84134d7ecce70d3f993ba
@@@ -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)
        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))
        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;