forked from Minki/linux
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 NVME_FC_MAX_CONNECT_ATTEMPTS 1
|
||||
|
||||
struct nvme_fc_queue {
|
||||
struct nvme_fc_ctrl *ctrl;
|
||||
struct device *dev;
|
||||
@ -165,7 +163,6 @@ struct nvme_fc_ctrl {
|
||||
struct work_struct delete_work;
|
||||
struct work_struct reset_work;
|
||||
struct delayed_work connect_work;
|
||||
int connect_attempts;
|
||||
|
||||
struct kref ref;
|
||||
u32 flags;
|
||||
@ -2305,7 +2302,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
|
||||
int ret;
|
||||
bool changed;
|
||||
|
||||
ctrl->connect_attempts++;
|
||||
++ctrl->ctrl.opts->nr_reconnects;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
WARN_ON_ONCE(!changed);
|
||||
|
||||
ctrl->connect_attempts = 0;
|
||||
ctrl->ctrl.opts->nr_reconnects = 0;
|
||||
|
||||
kref_get(&ctrl->ctrl.kref);
|
||||
|
||||
@ -2545,16 +2542,22 @@ nvme_fc_delete_ctrl_work(struct work_struct *work)
|
||||
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
|
||||
__nvme_fc_del_ctrl(struct nvme_fc_ctrl *ctrl)
|
||||
{
|
||||
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING))
|
||||
return -EBUSY;
|
||||
|
||||
if (!queue_work(nvme_fc_wq, &ctrl->delete_work))
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
return __nvme_fc_schedule_delete_work(ctrl) ? -EBUSY : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2579,6 +2582,35 @@ nvme_fc_del_nvme_ctrl(struct nvme_ctrl *nctrl)
|
||||
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
|
||||
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);
|
||||
|
||||
ret = nvme_fc_create_association(ctrl);
|
||||
if (ret) {
|
||||
dev_warn(ctrl->ctrl.device,
|
||||
"NVME-FC{%d}: reset: Reconnect attempt failed (%d)\n",
|
||||
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
|
||||
if (ret)
|
||||
nvme_fc_reconnect_or_delete(ctrl, ret);
|
||||
else
|
||||
dev_info(ctrl->ctrl.device,
|
||||
"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);
|
||||
|
||||
ret = nvme_fc_create_association(ctrl);
|
||||
if (ret) {
|
||||
dev_warn(ctrl->ctrl.device,
|
||||
"NVME-FC{%d}: Reconnect attempt failed (%d)\n",
|
||||
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
|
||||
if (ret)
|
||||
nvme_fc_reconnect_or_delete(ctrl, ret);
|
||||
else
|
||||
dev_info(ctrl->ctrl.device,
|
||||
"NVME-FC{%d}: controller reconnect complete\n",
|
||||
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 = {
|
||||
.name = "fc",
|
||||
.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,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user