nvme_fc: Support ctrl_loss_tmo
Sync with Sagi's recent addition of ctrl_loss_tmo in the core fabrics layer. Remove local connect limits and connect_attempts variable. Use fabrics new nr_connects variable and use of nvmf_should_reconnect() Refactor duplicate reconnect failure code. Addresses review comment by Sagi on controller reset support: http://lists.infradead.org/pipermail/linux-nvme/2017-April/009261.html Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
0ce872bf8b
commit
5bbecdbc8e
@ -45,8 +45,6 @@ enum nvme_fc_queue_flags {
|
|||||||
|
|
||||||
#define NVMEFC_QUEUE_DELAY 3 /* ms units */
|
#define NVMEFC_QUEUE_DELAY 3 /* ms units */
|
||||||
|
|
||||||
#define NVME_FC_MAX_CONNECT_ATTEMPTS 1
|
|
||||||
|
|
||||||
struct nvme_fc_queue {
|
struct nvme_fc_queue {
|
||||||
struct nvme_fc_ctrl *ctrl;
|
struct nvme_fc_ctrl *ctrl;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
@ -165,7 +163,6 @@ struct nvme_fc_ctrl {
|
|||||||
struct work_struct delete_work;
|
struct work_struct delete_work;
|
||||||
struct work_struct reset_work;
|
struct work_struct reset_work;
|
||||||
struct delayed_work connect_work;
|
struct delayed_work connect_work;
|
||||||
int connect_attempts;
|
|
||||||
|
|
||||||
struct kref ref;
|
struct kref ref;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
@ -2305,7 +2302,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
|
|||||||
int ret;
|
int ret;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
|
||||||
ctrl->connect_attempts++;
|
++ctrl->ctrl.opts->nr_reconnects;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the admin queue
|
* Create the admin queue
|
||||||
@ -2402,7 +2399,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
|
|||||||
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
|
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
|
||||||
WARN_ON_ONCE(!changed);
|
WARN_ON_ONCE(!changed);
|
||||||
|
|
||||||
ctrl->connect_attempts = 0;
|
ctrl->ctrl.opts->nr_reconnects = 0;
|
||||||
|
|
||||||
kref_get(&ctrl->ctrl.kref);
|
kref_get(&ctrl->ctrl.kref);
|
||||||
|
|
||||||
@ -2545,16 +2542,22 @@ nvme_fc_delete_ctrl_work(struct work_struct *work)
|
|||||||
nvme_put_ctrl(&ctrl->ctrl);
|
nvme_put_ctrl(&ctrl->ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
__nvme_fc_schedule_delete_work(struct nvme_fc_ctrl *ctrl)
|
||||||
|
{
|
||||||
|
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!queue_work(nvme_fc_wq, &ctrl->delete_work))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__nvme_fc_del_ctrl(struct nvme_fc_ctrl *ctrl)
|
__nvme_fc_del_ctrl(struct nvme_fc_ctrl *ctrl)
|
||||||
{
|
{
|
||||||
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING))
|
return __nvme_fc_schedule_delete_work(ctrl) ? -EBUSY : 0;
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
if (!queue_work(nvme_fc_wq, &ctrl->delete_work))
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2579,6 +2582,35 @@ nvme_fc_del_nvme_ctrl(struct nvme_ctrl *nctrl)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status)
|
||||||
|
{
|
||||||
|
/* If we are resetting/deleting then do nothing */
|
||||||
|
if (ctrl->ctrl.state != NVME_CTRL_RECONNECTING) {
|
||||||
|
WARN_ON_ONCE(ctrl->ctrl.state == NVME_CTRL_NEW ||
|
||||||
|
ctrl->ctrl.state == NVME_CTRL_LIVE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_warn(ctrl->ctrl.device,
|
||||||
|
"NVME-FC{%d}: reset: Reconnect attempt failed (%d)\n",
|
||||||
|
ctrl->cnum, status);
|
||||||
|
|
||||||
|
if (nvmf_should_reconnect(&ctrl->ctrl)) {
|
||||||
|
dev_info(ctrl->ctrl.device,
|
||||||
|
"NVME-FC{%d}: Reconnect attempt in %d seconds.\n",
|
||||||
|
ctrl->cnum, ctrl->ctrl.opts->reconnect_delay);
|
||||||
|
queue_delayed_work(nvme_fc_wq, &ctrl->connect_work,
|
||||||
|
ctrl->ctrl.opts->reconnect_delay * HZ);
|
||||||
|
} else {
|
||||||
|
dev_info(ctrl->ctrl.device,
|
||||||
|
"NVME-FC{%d}: Max reconnect attempts (%d) "
|
||||||
|
"reached. Removing controller\n",
|
||||||
|
ctrl->cnum, ctrl->ctrl.opts->nr_reconnects);
|
||||||
|
WARN_ON(__nvme_fc_schedule_delete_work(ctrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nvme_fc_reset_ctrl_work(struct work_struct *work)
|
nvme_fc_reset_ctrl_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
@ -2590,34 +2622,9 @@ nvme_fc_reset_ctrl_work(struct work_struct *work)
|
|||||||
nvme_fc_delete_association(ctrl);
|
nvme_fc_delete_association(ctrl);
|
||||||
|
|
||||||
ret = nvme_fc_create_association(ctrl);
|
ret = nvme_fc_create_association(ctrl);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_warn(ctrl->ctrl.device,
|
nvme_fc_reconnect_or_delete(ctrl, ret);
|
||||||
"NVME-FC{%d}: reset: Reconnect attempt failed (%d)\n",
|
else
|
||||||
ctrl->cnum, ret);
|
|
||||||
if (ctrl->connect_attempts >= NVME_FC_MAX_CONNECT_ATTEMPTS) {
|
|
||||||
dev_warn(ctrl->ctrl.device,
|
|
||||||
"NVME-FC{%d}: Max reconnect attempts (%d) "
|
|
||||||
"reached. Removing controller\n",
|
|
||||||
ctrl->cnum, ctrl->connect_attempts);
|
|
||||||
|
|
||||||
if (!nvme_change_ctrl_state(&ctrl->ctrl,
|
|
||||||
NVME_CTRL_DELETING)) {
|
|
||||||
dev_err(ctrl->ctrl.device,
|
|
||||||
"NVME-FC{%d}: failed to change state "
|
|
||||||
"to DELETING\n", ctrl->cnum);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN_ON(!queue_work(nvme_fc_wq, &ctrl->delete_work));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_warn(ctrl->ctrl.device,
|
|
||||||
"NVME-FC{%d}: Reconnect attempt in %d seconds.\n",
|
|
||||||
ctrl->cnum, ctrl->ctrl.opts->reconnect_delay);
|
|
||||||
queue_delayed_work(nvme_fc_wq, &ctrl->connect_work,
|
|
||||||
ctrl->ctrl.opts->reconnect_delay * HZ);
|
|
||||||
} else
|
|
||||||
dev_info(ctrl->ctrl.device,
|
dev_info(ctrl->ctrl.device,
|
||||||
"NVME-FC{%d}: controller reset complete\n", ctrl->cnum);
|
"NVME-FC{%d}: controller reset complete\n", ctrl->cnum);
|
||||||
}
|
}
|
||||||
@ -2670,34 +2677,9 @@ nvme_fc_connect_ctrl_work(struct work_struct *work)
|
|||||||
struct nvme_fc_ctrl, connect_work);
|
struct nvme_fc_ctrl, connect_work);
|
||||||
|
|
||||||
ret = nvme_fc_create_association(ctrl);
|
ret = nvme_fc_create_association(ctrl);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_warn(ctrl->ctrl.device,
|
nvme_fc_reconnect_or_delete(ctrl, ret);
|
||||||
"NVME-FC{%d}: Reconnect attempt failed (%d)\n",
|
else
|
||||||
ctrl->cnum, ret);
|
|
||||||
if (ctrl->connect_attempts >= NVME_FC_MAX_CONNECT_ATTEMPTS) {
|
|
||||||
dev_warn(ctrl->ctrl.device,
|
|
||||||
"NVME-FC{%d}: Max reconnect attempts (%d) "
|
|
||||||
"reached. Removing controller\n",
|
|
||||||
ctrl->cnum, ctrl->connect_attempts);
|
|
||||||
|
|
||||||
if (!nvme_change_ctrl_state(&ctrl->ctrl,
|
|
||||||
NVME_CTRL_DELETING)) {
|
|
||||||
dev_err(ctrl->ctrl.device,
|
|
||||||
"NVME-FC{%d}: failed to change state "
|
|
||||||
"to DELETING\n", ctrl->cnum);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN_ON(!queue_work(nvme_fc_wq, &ctrl->delete_work));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_warn(ctrl->ctrl.device,
|
|
||||||
"NVME-FC{%d}: Reconnect attempt in %d seconds.\n",
|
|
||||||
ctrl->cnum, ctrl->ctrl.opts->reconnect_delay);
|
|
||||||
queue_delayed_work(nvme_fc_wq, &ctrl->connect_work,
|
|
||||||
ctrl->ctrl.opts->reconnect_delay * HZ);
|
|
||||||
} else
|
|
||||||
dev_info(ctrl->ctrl.device,
|
dev_info(ctrl->ctrl.device,
|
||||||
"NVME-FC{%d}: controller reconnect complete\n",
|
"NVME-FC{%d}: controller reconnect complete\n",
|
||||||
ctrl->cnum);
|
ctrl->cnum);
|
||||||
@ -2969,7 +2951,7 @@ nvme_fc_create_ctrl(struct device *dev, struct nvmf_ctrl_options *opts)
|
|||||||
static struct nvmf_transport_ops nvme_fc_transport = {
|
static struct nvmf_transport_ops nvme_fc_transport = {
|
||||||
.name = "fc",
|
.name = "fc",
|
||||||
.required_opts = NVMF_OPT_TRADDR | NVMF_OPT_HOST_TRADDR,
|
.required_opts = NVMF_OPT_TRADDR | NVMF_OPT_HOST_TRADDR,
|
||||||
.allowed_opts = NVMF_OPT_RECONNECT_DELAY,
|
.allowed_opts = NVMF_OPT_RECONNECT_DELAY | NVMF_OPT_CTRL_LOSS_TMO,
|
||||||
.create_ctrl = nvme_fc_create_ctrl,
|
.create_ctrl = nvme_fc_create_ctrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user