diff options
author | James Smart <jsmart2021@gmail.com> | 2017-10-09 19:39:22 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2017-10-18 13:30:01 -0400 |
commit | 17c4dc6eb7e1b2fb1ce6a52467e3be635224606e (patch) | |
tree | 9132517ada51bf3bf431b4678d25fde312cb1a2e | |
parent | 8a82dbf19129dde9e6fc9ab25a00dbc7569abe6a (diff) |
nvme-fc: retry initial controller connections 3 times
Currently, if a frame is lost of command fails as part of initial
association create for a new controller, the new controller connection
request will immediately fail.
Add in an immediate 3 retry loop before giving up.
Signed-off-by: James Smart <james.smart@broadcom.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | drivers/nvme/host/fc.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 8182b1999f49..be49d0f79381 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
@@ -2734,7 +2734,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
2734 | { | 2734 | { |
2735 | struct nvme_fc_ctrl *ctrl; | 2735 | struct nvme_fc_ctrl *ctrl; |
2736 | unsigned long flags; | 2736 | unsigned long flags; |
2737 | int ret, idx; | 2737 | int ret, idx, retry; |
2738 | 2738 | ||
2739 | if (!(rport->remoteport.port_role & | 2739 | if (!(rport->remoteport.port_role & |
2740 | (FC_PORT_ROLE_NVME_DISCOVERY | FC_PORT_ROLE_NVME_TARGET))) { | 2740 | (FC_PORT_ROLE_NVME_DISCOVERY | FC_PORT_ROLE_NVME_TARGET))) { |
@@ -2826,9 +2826,37 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
2826 | list_add_tail(&ctrl->ctrl_list, &rport->ctrl_list); | 2826 | list_add_tail(&ctrl->ctrl_list, &rport->ctrl_list); |
2827 | spin_unlock_irqrestore(&rport->lock, flags); | 2827 | spin_unlock_irqrestore(&rport->lock, flags); |
2828 | 2828 | ||
2829 | ret = nvme_fc_create_association(ctrl); | 2829 | /* |
2830 | * It's possible that transactions used to create the association | ||
2831 | * may fail. Examples: CreateAssociation LS or CreateIOConnection | ||
2832 | * LS gets dropped/corrupted/fails; or a frame gets dropped or a | ||
2833 | * command times out for one of the actions to init the controller | ||
2834 | * (Connect, Get/Set_Property, Set_Features, etc). Many of these | ||
2835 | * transport errors (frame drop, LS failure) inherently must kill | ||
2836 | * the association. The transport is coded so that any command used | ||
2837 | * to create the association (prior to a LIVE state transition | ||
2838 | * while NEW or RECONNECTING) will fail if it completes in error or | ||
2839 | * times out. | ||
2840 | * | ||
2841 | * As such: as the connect request was mostly likely due to a | ||
2842 | * udev event that discovered the remote port, meaning there is | ||
2843 | * not an admin or script there to restart if the connect | ||
2844 | * request fails, retry the initial connection creation up to | ||
2845 | * three times before giving up and declaring failure. | ||
2846 | */ | ||
2847 | for (retry = 0; retry < 3; retry++) { | ||
2848 | ret = nvme_fc_create_association(ctrl); | ||
2849 | if (!ret) | ||
2850 | break; | ||
2851 | } | ||
2852 | |||
2830 | if (ret) { | 2853 | if (ret) { |
2854 | /* couldn't schedule retry - fail out */ | ||
2855 | dev_err(ctrl->ctrl.device, | ||
2856 | "NVME-FC{%d}: Connect retry failed\n", ctrl->cnum); | ||
2857 | |||
2831 | ctrl->ctrl.opts = NULL; | 2858 | ctrl->ctrl.opts = NULL; |
2859 | |||
2832 | /* initiate nvme ctrl ref counting teardown */ | 2860 | /* initiate nvme ctrl ref counting teardown */ |
2833 | nvme_uninit_ctrl(&ctrl->ctrl); | 2861 | nvme_uninit_ctrl(&ctrl->ctrl); |
2834 | nvme_put_ctrl(&ctrl->ctrl); | 2862 | nvme_put_ctrl(&ctrl->ctrl); |