Merge branch 'for-5.18/drivers' into for-5.18/64bit-pi
[sfrench/cifs-2.6.git] / drivers / nvme / host / core.c
index f8084ded69e508cbf3fd319d036cebb2e2f1a898..ace8c61850b12ddb44f5fd24bd8184dc2dba39c8 100644 (file)
@@ -401,6 +401,7 @@ EXPORT_SYMBOL_GPL(nvme_complete_rq);
 
 void nvme_complete_batch_req(struct request *req)
 {
+       trace_nvme_complete_rq(req);
        nvme_cleanup_cmd(req);
        nvme_end_req_zoned(req);
 }
@@ -1749,7 +1750,7 @@ static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
        return 0;
 }
 
-static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
 {
        struct nvme_ctrl *ctrl = ns->ctrl;
 
@@ -1765,7 +1766,8 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
 
        ns->features &= ~(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS);
        if (!ns->ms || !(ctrl->ops->flags & NVME_F_METADATA_SUPPORTED))
-               return 0;
+               return;
+
        if (ctrl->ops->flags & NVME_F_FABRICS) {
                /*
                 * The NVMe over Fabrics specification only supports metadata as
@@ -1773,7 +1775,7 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
                 * remap the separate metadata buffer from the block layer.
                 */
                if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT)))
-                       return -EINVAL;
+                       return;
 
                ns->features |= NVME_NS_EXT_LBAS;
 
@@ -1800,8 +1802,6 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
                else
                        ns->features |= NVME_NS_METADATA_SUPPORTED;
        }
-
-       return 0;
 }
 
 static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
@@ -1942,9 +1942,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
        ns->lba_shift = id->lbaf[lbaf].ds;
        nvme_set_queue_limits(ns->ctrl, ns->queue);
 
-       ret = nvme_configure_metadata(ns, id);
-       if (ret)
-               goto out_unfreeze;
+       nvme_configure_metadata(ns, id);
        nvme_set_chunk_sectors(ns, id);
        nvme_update_disk_info(ns->disk, ns, id);
 
@@ -1960,7 +1958,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
        if (blk_queue_is_zoned(ns->queue)) {
                ret = nvme_revalidate_zones(ns);
                if (ret && !nvme_first_scan(ns->disk))
-                       goto out;
+                       return ret;
        }
 
        if (nvme_ns_head_multipath(ns->head)) {
@@ -1975,16 +1973,16 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
        return 0;
 
 out_unfreeze:
-       blk_mq_unfreeze_queue(ns->disk->queue);
-out:
        /*
         * If probing fails due an unsupported feature, hide the block device,
         * but still allow other access.
         */
        if (ret == -ENODEV) {
                ns->disk->flags |= GENHD_FL_HIDDEN;
+               set_bit(NVME_NS_READY, &ns->flags);
                ret = 0;
        }
+       blk_mq_unfreeze_queue(ns->disk->queue);
        return ret;
 }
 
@@ -4367,7 +4365,14 @@ static void nvme_async_event_work(struct work_struct *work)
                container_of(work, struct nvme_ctrl, async_event_work);
 
        nvme_aen_uevent(ctrl);
-       ctrl->ops->submit_async_event(ctrl);
+
+       /*
+        * The transport drivers must guarantee AER submission here is safe by
+        * flushing ctrl async_event_work after changing the controller state
+        * from LIVE and before freeing the admin queue.
+       */
+       if (ctrl->state == NVME_CTRL_LIVE)
+               ctrl->ops->submit_async_event(ctrl);
 }
 
 static bool nvme_ctrl_pp_status(struct nvme_ctrl *ctrl)
@@ -4682,7 +4687,7 @@ static void nvme_set_queue_dying(struct nvme_ns *ns)
        if (test_and_set_bit(NVME_NS_DEAD, &ns->flags))
                return;
 
-       blk_set_queue_dying(ns->queue);
+       blk_mark_disk_dead(ns->disk);
        nvme_start_ns_queue(ns);
 
        set_capacity_and_notify(ns->disk, 0);