nvme: use ctrl state accessor
authorKeith Busch <kbusch@kernel.org>
Wed, 24 Jan 2024 17:27:27 +0000 (09:27 -0800)
committerKeith Busch <kbusch@kernel.org>
Mon, 29 Jan 2024 15:02:50 +0000 (07:02 -0800)
The ctrl->state value is updated in another thread using WRITE_ONCE, so
ensure all the readers use the appropriate accessor.

Reviewed-by: Sagi Grimberg <sagi@grmberg.me>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/apple.c
drivers/nvme/host/auth.c
drivers/nvme/host/core.c
drivers/nvme/host/fabrics.h
drivers/nvme/host/multipath.c
drivers/nvme/host/nvme.h
drivers/nvme/host/sysfs.c
drivers/nvme/target/loop.c

index 596bb11eeba5a9d0a4d1637f2c061775956bb84e..c727cd1f264bf6221d2043d1f65bb70a51f00c1d 100644 (file)
@@ -797,6 +797,7 @@ static int apple_nvme_init_request(struct blk_mq_tag_set *set,
 
 static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown)
 {
+       enum nvme_ctrl_state state = nvme_ctrl_state(&anv->ctrl);
        u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS);
        bool dead = false, freeze = false;
        unsigned long flags;
@@ -808,8 +809,8 @@ static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown)
        if (csts & NVME_CSTS_CFS)
                dead = true;
 
-       if (anv->ctrl.state == NVME_CTRL_LIVE ||
-           anv->ctrl.state == NVME_CTRL_RESETTING) {
+       if (state == NVME_CTRL_LIVE ||
+           state == NVME_CTRL_RESETTING) {
                freeze = true;
                nvme_start_freeze(&anv->ctrl);
        }
@@ -881,7 +882,7 @@ static enum blk_eh_timer_return apple_nvme_timeout(struct request *req)
        unsigned long flags;
        u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS);
 
-       if (anv->ctrl.state != NVME_CTRL_LIVE) {
+       if (nvme_ctrl_state(&anv->ctrl) != NVME_CTRL_LIVE) {
                /*
                 * From rdma.c:
                 * If we are resetting, connecting or deleting we should
@@ -985,10 +986,10 @@ static void apple_nvme_reset_work(struct work_struct *work)
        u32 boot_status, aqa;
        struct apple_nvme *anv =
                container_of(work, struct apple_nvme, ctrl.reset_work);
+       enum nvme_ctrl_state state = nvme_ctrl_state(&anv->ctrl);
 
-       if (anv->ctrl.state != NVME_CTRL_RESETTING) {
-               dev_warn(anv->dev, "ctrl state %d is not RESETTING\n",
-                        anv->ctrl.state);
+       if (state != NVME_CTRL_RESETTING) {
+               dev_warn(anv->dev, "ctrl state %d is not RESETTING\n", state);
                ret = -ENODEV;
                goto out;
        }
index 72c0525c75f503bb56c7c246c733f9eea57e44ab..2a12ee878783fc569b9d481be1f2799f0c8b24e4 100644 (file)
@@ -897,7 +897,7 @@ static void nvme_ctrl_auth_work(struct work_struct *work)
         * If the ctrl is no connected, bail as reconnect will handle
         * authentication.
         */
-       if (ctrl->state != NVME_CTRL_LIVE)
+       if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE)
                return;
 
        /* Authenticate admin queue first */
index 0810be0d1154c17cc45aa35ba99feaa15b6d900b..a42c347d08e87c82f7ad8388124f4c13400e5226 100644 (file)
@@ -721,7 +721,7 @@ blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl,
 EXPORT_SYMBOL_GPL(nvme_fail_nonready_command);
 
 bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
-               bool queue_live)
+               bool queue_live, enum nvme_ctrl_state state)
 {
        struct nvme_request *req = nvme_req(rq);
 
@@ -742,7 +742,7 @@ bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
                 * command, which is require to set the queue live in the
                 * appropinquate states.
                 */
-               switch (nvme_ctrl_state(ctrl)) {
+               switch (state) {
                case NVME_CTRL_CONNECTING:
                        if (blk_rq_is_passthrough(rq) && nvme_is_fabrics(req->cmd) &&
                            (req->cmd->fabrics.fctype == nvme_fabrics_type_connect ||
index fbaee5a7be196c08483a41b6673f00e5032bec10..06cc54851b1be39615cdfa6eed1a935dec472f82 100644 (file)
@@ -185,9 +185,11 @@ static inline bool
 nvmf_ctlr_matches_baseopts(struct nvme_ctrl *ctrl,
                        struct nvmf_ctrl_options *opts)
 {
-       if (ctrl->state == NVME_CTRL_DELETING ||
-           ctrl->state == NVME_CTRL_DELETING_NOIO ||
-           ctrl->state == NVME_CTRL_DEAD ||
+       enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
+
+       if (state == NVME_CTRL_DELETING ||
+           state == NVME_CTRL_DELETING_NOIO ||
+           state == NVME_CTRL_DEAD ||
            strcmp(opts->subsysnqn, ctrl->opts->subsysnqn) ||
            strcmp(opts->host->nqn, ctrl->opts->host->nqn) ||
            !uuid_equal(&opts->host->id, &ctrl->opts->host->id))
index 2dd4137a08b284df64788972a067d4282fa92ac7..74de1e64aeead77c604ec31e30bac179a0de245b 100644 (file)
@@ -156,7 +156,7 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl)
                if (!ns->head->disk)
                        continue;
                kblockd_schedule_work(&ns->head->requeue_work);
-               if (ctrl->state == NVME_CTRL_LIVE)
+               if (nvme_ctrl_state(ns->ctrl) == NVME_CTRL_LIVE)
                        disk_uevent(ns->head->disk, KOBJ_CHANGE);
        }
        up_read(&ctrl->namespaces_rwsem);
@@ -223,13 +223,14 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
 
 static bool nvme_path_is_disabled(struct nvme_ns *ns)
 {
+       enum nvme_ctrl_state state = nvme_ctrl_state(ns->ctrl);
+
        /*
         * We don't treat NVME_CTRL_DELETING as a disabled path as I/O should
         * still be able to complete assuming that the controller is connected.
         * Otherwise it will fail immediately and return to the requeue list.
         */
-       if (ns->ctrl->state != NVME_CTRL_LIVE &&
-           ns->ctrl->state != NVME_CTRL_DELETING)
+       if (state != NVME_CTRL_LIVE && state != NVME_CTRL_DELETING)
                return true;
        if (test_bit(NVME_NS_ANA_PENDING, &ns->flags) ||
            !test_bit(NVME_NS_READY, &ns->flags))
@@ -331,7 +332,7 @@ out:
 
 static inline bool nvme_path_is_optimized(struct nvme_ns *ns)
 {
-       return ns->ctrl->state == NVME_CTRL_LIVE &&
+       return nvme_ctrl_state(ns->ctrl) == NVME_CTRL_LIVE &&
                ns->ana_state == NVME_ANA_OPTIMIZED;
 }
 
@@ -358,7 +359,7 @@ static bool nvme_available_path(struct nvme_ns_head *head)
        list_for_each_entry_rcu(ns, &head->list, siblings) {
                if (test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ns->ctrl->flags))
                        continue;
-               switch (ns->ctrl->state) {
+               switch (nvme_ctrl_state(ns->ctrl)) {
                case NVME_CTRL_LIVE:
                case NVME_CTRL_RESETTING:
                case NVME_CTRL_CONNECTING:
@@ -667,7 +668,7 @@ static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc,
         * controller is ready.
         */
        if (nvme_state_is_live(ns->ana_state) &&
-           ns->ctrl->state == NVME_CTRL_LIVE)
+           nvme_ctrl_state(ns->ctrl) == NVME_CTRL_LIVE)
                nvme_mpath_set_live(ns);
 }
 
@@ -748,7 +749,7 @@ static void nvme_ana_work(struct work_struct *work)
 {
        struct nvme_ctrl *ctrl = container_of(work, struct nvme_ctrl, ana_work);
 
-       if (ctrl->state != NVME_CTRL_LIVE)
+       if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE)
                return;
 
        nvme_read_ana_log(ctrl);
index 030c8081824065e7fa3d14e1a4918f1c94080565..1700063bc24de38c74b2ad2e7c48b0343659202d 100644 (file)
@@ -805,17 +805,18 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req);
 blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl,
                struct request *req);
 bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
-               bool queue_live);
+               bool queue_live, enum nvme_ctrl_state state);
 
 static inline bool nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
                bool queue_live)
 {
-       if (likely(ctrl->state == NVME_CTRL_LIVE))
+       enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
+
+       if (likely(state == NVME_CTRL_LIVE))
                return true;
-       if (ctrl->ops->flags & NVME_F_FABRICS &&
-           ctrl->state == NVME_CTRL_DELETING)
+       if (ctrl->ops->flags & NVME_F_FABRICS && state == NVME_CTRL_DELETING)
                return queue_live;
-       return __nvme_check_ready(ctrl, rq, queue_live);
+       return __nvme_check_ready(ctrl, rq, queue_live, state);
 }
 
 /*
index 754e911110420f5f30074762c7787a88b183830a..6b2f06f190de397f094b2d12b5390de86f36eca2 100644 (file)
@@ -311,6 +311,7 @@ static ssize_t nvme_sysfs_show_state(struct device *dev,
                                     char *buf)
 {
        struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+       unsigned state = (unsigned)nvme_ctrl_state(ctrl);
        static const char *const state_name[] = {
                [NVME_CTRL_NEW]         = "new",
                [NVME_CTRL_LIVE]        = "live",
@@ -321,9 +322,8 @@ static ssize_t nvme_sysfs_show_state(struct device *dev,
                [NVME_CTRL_DEAD]        = "dead",
        };
 
-       if ((unsigned)ctrl->state < ARRAY_SIZE(state_name) &&
-           state_name[ctrl->state])
-               return sysfs_emit(buf, "%s\n", state_name[ctrl->state]);
+       if (state < ARRAY_SIZE(state_name) && state_name[state])
+               return sysfs_emit(buf, "%s\n", state_name[state]);
 
        return sysfs_emit(buf, "unknown state\n");
 }
index 2b2e0d00af85e92d5d851f2fc6001fbd35a9a489..e589915ddef85cf5f67fcba50deed724b37616d3 100644 (file)
@@ -400,7 +400,7 @@ static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl)
        }
 
        nvme_quiesce_admin_queue(&ctrl->ctrl);
-       if (ctrl->ctrl.state == NVME_CTRL_LIVE)
+       if (nvme_ctrl_state(&ctrl->ctrl) == NVME_CTRL_LIVE)
                nvme_disable_ctrl(&ctrl->ctrl, true);
 
        nvme_cancel_admin_tagset(&ctrl->ctrl);
@@ -434,8 +434,10 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work)
        nvme_loop_shutdown_ctrl(ctrl);
 
        if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
-               if (ctrl->ctrl.state != NVME_CTRL_DELETING &&
-                   ctrl->ctrl.state != NVME_CTRL_DELETING_NOIO)
+               enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl);
+
+               if (state != NVME_CTRL_DELETING &&
+                   state != NVME_CTRL_DELETING_NOIO)
                        /* state change failure for non-deleted ctrl? */
                        WARN_ON_ONCE(1);
                return;