Merge branch 'for-jens' of git://git.infradead.org/nvme into for-linus
authorJens Axboe <axboe@kernel.dk>
Wed, 28 Feb 2018 19:18:58 +0000 (12:18 -0700)
committerJens Axboe <axboe@kernel.dk>
Wed, 28 Feb 2018 19:18:58 +0000 (12:18 -0700)
Pull NVMe fixes from Keith for 4.16-rc.

* 'for-jens' of git://git.infradead.org/nvme:
  nvmet: fix PSDT field check in command format
  nvme-multipath: fix sysfs dangerously created links
  nvme-pci: Fix nvme queue cleanup if IRQ setup fails
  nvmet-loop: use blk_rq_payload_bytes for sgl selection
  nvme-rdma: use blk_rq_payload_bytes instead of blk_rq_bytes
  nvme-fabrics: don't check for non-NULL module in nvmf_register_transport

1  2 
drivers/nvme/host/core.c
drivers/nvme/host/pci.c
drivers/nvme/host/rdma.c

diff --combined drivers/nvme/host/core.c
@@@ -120,12 -120,8 +120,12 @@@ int nvme_reset_ctrl_sync(struct nvme_ct
        int ret;
  
        ret = nvme_reset_ctrl(ctrl);
 -      if (!ret)
 +      if (!ret) {
                flush_work(&ctrl->reset_work);
 +              if (ctrl->state != NVME_CTRL_LIVE)
 +                      ret = -ENETRESET;
 +      }
 +
        return ret;
  }
  EXPORT_SYMBOL_GPL(nvme_reset_ctrl_sync);
@@@ -269,7 -265,7 +269,7 @@@ bool nvme_change_ctrl_state(struct nvme
        switch (new_state) {
        case NVME_CTRL_ADMIN_ONLY:
                switch (old_state) {
 -              case NVME_CTRL_RECONNECTING:
 +              case NVME_CTRL_CONNECTING:
                        changed = true;
                        /* FALLTHRU */
                default:
                switch (old_state) {
                case NVME_CTRL_NEW:
                case NVME_CTRL_RESETTING:
 -              case NVME_CTRL_RECONNECTING:
 +              case NVME_CTRL_CONNECTING:
                        changed = true;
                        /* FALLTHRU */
                default:
                        break;
                }
                break;
 -      case NVME_CTRL_RECONNECTING:
 +      case NVME_CTRL_CONNECTING:
                switch (old_state) {
 -              case NVME_CTRL_LIVE:
 +              case NVME_CTRL_NEW:
                case NVME_CTRL_RESETTING:
                        changed = true;
                        /* FALLTHRU */
                case NVME_CTRL_LIVE:
                case NVME_CTRL_ADMIN_ONLY:
                case NVME_CTRL_RESETTING:
 -              case NVME_CTRL_RECONNECTING:
 +              case NVME_CTRL_CONNECTING:
                        changed = true;
                        /* FALLTHRU */
                default:
@@@ -522,11 -518,9 +522,11 @@@ static blk_status_t nvme_setup_discard(
                u64 slba = nvme_block_nr(ns, bio->bi_iter.bi_sector);
                u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;
  
 -              range[n].cattr = cpu_to_le32(0);
 -              range[n].nlb = cpu_to_le32(nlb);
 -              range[n].slba = cpu_to_le64(slba);
 +              if (n < segments) {
 +                      range[n].cattr = cpu_to_le32(0);
 +                      range[n].nlb = cpu_to_le32(nlb);
 +                      range[n].slba = cpu_to_le64(slba);
 +              }
                n++;
        }
  
@@@ -800,9 -794,13 +800,9 @@@ static void nvme_keep_alive_end_io(stru
  
  static int nvme_keep_alive(struct nvme_ctrl *ctrl)
  {
 -      struct nvme_command c;
        struct request *rq;
  
 -      memset(&c, 0, sizeof(c));
 -      c.common.opcode = nvme_admin_keep_alive;
 -
 -      rq = nvme_alloc_request(ctrl->admin_q, &c, BLK_MQ_REQ_RESERVED,
 +      rq = nvme_alloc_request(ctrl->admin_q, &ctrl->ka_cmd, BLK_MQ_REQ_RESERVED,
                        NVME_QID_ANY);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
@@@ -834,8 -832,6 +834,8 @@@ void nvme_start_keep_alive(struct nvme_
                return;
  
        INIT_DELAYED_WORK(&ctrl->ka_work, nvme_keep_alive_work);
 +      memset(&ctrl->ka_cmd, 0, sizeof(ctrl->ka_cmd));
 +      ctrl->ka_cmd.common.opcode = nvme_admin_keep_alive;
        schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ);
  }
  EXPORT_SYMBOL_GPL(nvme_start_keep_alive);
@@@ -1121,19 -1117,14 +1121,19 @@@ static u32 nvme_passthru_start(struct n
  
  static void nvme_update_formats(struct nvme_ctrl *ctrl)
  {
 -      struct nvme_ns *ns;
 +      struct nvme_ns *ns, *next;
 +      LIST_HEAD(rm_list);
  
        mutex_lock(&ctrl->namespaces_mutex);
        list_for_each_entry(ns, &ctrl->namespaces, list) {
 -              if (ns->disk && nvme_revalidate_disk(ns->disk))
 -                      nvme_ns_remove(ns);
 +              if (ns->disk && nvme_revalidate_disk(ns->disk)) {
 +                      list_move_tail(&ns->list, &rm_list);
 +              }
        }
        mutex_unlock(&ctrl->namespaces_mutex);
 +
 +      list_for_each_entry_safe(ns, next, &rm_list, list)
 +              nvme_ns_remove(ns);
  }
  
  static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects)
@@@ -2696,7 -2687,7 +2696,7 @@@ static ssize_t nvme_sysfs_show_state(st
                [NVME_CTRL_LIVE]        = "live",
                [NVME_CTRL_ADMIN_ONLY]  = "only-admin",
                [NVME_CTRL_RESETTING]   = "resetting",
 -              [NVME_CTRL_RECONNECTING]= "reconnecting",
 +              [NVME_CTRL_CONNECTING]  = "connecting",
                [NVME_CTRL_DELETING]    = "deleting",
                [NVME_CTRL_DEAD]        = "dead",
        };
@@@ -2844,7 -2835,7 +2844,7 @@@ out
  }
  
  static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
-               struct nvme_id_ns *id, bool *new)
+               struct nvme_id_ns *id)
  {
        struct nvme_ctrl *ctrl = ns->ctrl;
        bool is_shared = id->nmic & (1 << 0);
                        ret = PTR_ERR(head);
                        goto out_unlock;
                }
-               *new = true;
        } else {
                struct nvme_ns_ids ids;
  
                        ret = -EINVAL;
                        goto out_unlock;
                }
-               *new = false;
        }
  
        list_add_tail(&ns->siblings, &head->list);
@@@ -2945,7 -2932,6 +2941,6 @@@ static void nvme_alloc_ns(struct nvme_c
        struct nvme_id_ns *id;
        char disk_name[DISK_NAME_LEN];
        int node = dev_to_node(ctrl->dev), flags = GENHD_FL_EXT_DEVT;
-       bool new = true;
  
        ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
        if (!ns)
        if (id->ncap == 0)
                goto out_free_id;
  
-       if (nvme_init_ns_head(ns, nsid, id, &new))
+       if (nvme_init_ns_head(ns, nsid, id))
                goto out_free_id;
        nvme_setup_streams_ns(ctrl, ns);
        
                pr_warn("%s: failed to register lightnvm sysfs group for identification\n",
                        ns->disk->disk_name);
  
-       if (new)
-               nvme_mpath_add_disk(ns->head);
+       nvme_mpath_add_disk(ns->head);
        nvme_mpath_add_disk_links(ns);
        return;
   out_unlink_ns:
diff --combined drivers/nvme/host/pci.c
@@@ -1141,7 -1141,7 +1141,7 @@@ static bool nvme_should_reset(struct nv
        /* If there is a reset/reinit ongoing, we shouldn't reset again. */
        switch (dev->ctrl.state) {
        case NVME_CTRL_RESETTING:
 -      case NVME_CTRL_RECONNECTING:
 +      case NVME_CTRL_CONNECTING:
                return false;
        default:
                break;
@@@ -1215,17 -1215,13 +1215,17 @@@ static enum blk_eh_timer_return nvme_ti
         * cancellation error. All outstanding requests are completed on
         * shutdown, so we return BLK_EH_HANDLED.
         */
 -      if (dev->ctrl.state == NVME_CTRL_RESETTING) {
 +      switch (dev->ctrl.state) {
 +      case NVME_CTRL_CONNECTING:
 +      case NVME_CTRL_RESETTING:
                dev_warn(dev->ctrl.device,
                         "I/O %d QID %d timeout, disable controller\n",
                         req->tag, nvmeq->qid);
                nvme_dev_disable(dev, false);
                nvme_req(req)->flags |= NVME_REQ_CANCELLED;
                return BLK_EH_HANDLED;
 +      default:
 +              break;
        }
  
        /*
@@@ -1368,14 -1364,18 +1368,14 @@@ static int nvme_cmb_qdepth(struct nvme_
  static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,
                                int qid, int depth)
  {
 -      if (qid && dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) {
 -              unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth),
 -                                                    dev->ctrl.page_size);
 -              nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset;
 -              nvmeq->sq_cmds_io = dev->cmb + offset;
 -      } else {
 -              nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth),
 -                                      &nvmeq->sq_dma_addr, GFP_KERNEL);
 -              if (!nvmeq->sq_cmds)
 -                      return -ENOMEM;
 -      }
 +      /* CMB SQEs will be mapped before creation */
 +      if (qid && dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS))
 +              return 0;
  
 +      nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth),
 +                                          &nvmeq->sq_dma_addr, GFP_KERNEL);
 +      if (!nvmeq->sq_cmds)
 +              return -ENOMEM;
        return 0;
  }
  
@@@ -1449,17 -1449,10 +1449,17 @@@ static int nvme_create_queue(struct nvm
        struct nvme_dev *dev = nvmeq->dev;
        int result;
  
 +      if (dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) {
 +              unsigned offset = (qid - 1) * roundup(SQ_SIZE(nvmeq->q_depth),
 +                                                    dev->ctrl.page_size);
 +              nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset;
 +              nvmeq->sq_cmds_io = dev->cmb + offset;
 +      }
 +
        nvmeq->cq_vector = qid - 1;
        result = adapter_alloc_cq(dev, qid, nvmeq);
        if (result < 0)
-               return result;
+               goto release_vector;
  
        result = adapter_alloc_sq(dev, qid, nvmeq);
        if (result < 0)
        return result;
  
   release_sq:
+       dev->online_queues--;
        adapter_delete_sq(dev, qid);
   release_cq:
        adapter_delete_cq(dev, qid);
+  release_vector:
+       nvmeq->cq_vector = -1;
        return result;
  }
  
@@@ -2295,12 -2291,12 +2298,12 @@@ static void nvme_reset_work(struct work
                nvme_dev_disable(dev, false);
  
        /*
 -       * Introduce RECONNECTING state from nvme-fc/rdma transports to mark the
 +       * Introduce CONNECTING state from nvme-fc/rdma transports to mark the
         * initializing procedure here.
         */
 -      if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RECONNECTING)) {
 +      if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) {
                dev_warn(dev->ctrl.device,
 -                      "failed to mark controller RECONNECTING\n");
 +                      "failed to mark controller CONNECTING\n");
                goto out;
        }
  
diff --combined drivers/nvme/host/rdma.c
@@@ -887,7 -887,7 +887,7 @@@ free_ctrl
  static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl)
  {
        /* If we are resetting/deleting then do nothing */
 -      if (ctrl->ctrl.state != NVME_CTRL_RECONNECTING) {
 +      if (ctrl->ctrl.state != NVME_CTRL_CONNECTING) {
                WARN_ON_ONCE(ctrl->ctrl.state == NVME_CTRL_NEW ||
                        ctrl->ctrl.state == NVME_CTRL_LIVE);
                return;
@@@ -973,7 -973,7 +973,7 @@@ static void nvme_rdma_error_recovery_wo
        blk_mq_unquiesce_queue(ctrl->ctrl.admin_q);
        nvme_start_queues(&ctrl->ctrl);
  
 -      if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) {
 +      if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
                /* state change failure should never happen */
                WARN_ON_ONCE(1);
                return;
@@@ -1051,7 -1051,7 +1051,7 @@@ static void nvme_rdma_unmap_data(struc
        struct nvme_rdma_device *dev = queue->device;
        struct ib_device *ibdev = dev->dev;
  
-       if (!blk_rq_bytes(rq))
+       if (!blk_rq_payload_bytes(rq))
                return;
  
        if (req->mr) {
@@@ -1166,7 -1166,7 +1166,7 @@@ static int nvme_rdma_map_data(struct nv
  
        c->common.flags |= NVME_CMD_SGL_METABUF;
  
-       if (!blk_rq_bytes(rq))
+       if (!blk_rq_payload_bytes(rq))
                return nvme_rdma_set_sg_null(c);
  
        req->sg_table.sgl = req->first_sgl;
@@@ -1756,7 -1756,7 +1756,7 @@@ static void nvme_rdma_reset_ctrl_work(s
        nvme_stop_ctrl(&ctrl->ctrl);
        nvme_rdma_shutdown_ctrl(ctrl, false);
  
 -      if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) {
 +      if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
                /* state change failure should never happen */
                WARN_ON_ONCE(1);
                return;
        return;
  
  out_fail:
 -      dev_warn(ctrl->ctrl.device, "Removing after reset failure\n");
 -      nvme_remove_namespaces(&ctrl->ctrl);
 -      nvme_rdma_shutdown_ctrl(ctrl, true);
 -      nvme_uninit_ctrl(&ctrl->ctrl);
 -      nvme_put_ctrl(&ctrl->ctrl);
 +      ++ctrl->ctrl.nr_reconnects;
 +      nvme_rdma_reconnect_or_remove(ctrl);
  }
  
  static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {
@@@ -1939,9 -1942,6 +1939,9 @@@ static struct nvme_ctrl *nvme_rdma_crea
        if (!ctrl->queues)
                goto out_uninit_ctrl;
  
 +      changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING);
 +      WARN_ON_ONCE(!changed);
 +
        ret = nvme_rdma_configure_admin_queue(ctrl, true);
        if (ret)
                goto out_kfree_queues;