nvme: use ctrl state accessor
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>
This commit is contained in:
parent
47c5dd66c1
commit
6d3c7fb17b
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 ||
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user