diff options
| -rw-r--r-- | drivers/nvme/host/fc.c | 104 |
1 files changed, 47 insertions, 57 deletions
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 0bad65803271..9d826b726425 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
| @@ -142,6 +142,7 @@ struct nvme_fc_ctrl { | |||
| 142 | struct nvme_fc_rport *rport; | 142 | struct nvme_fc_rport *rport; |
| 143 | u32 cnum; | 143 | u32 cnum; |
| 144 | 144 | ||
| 145 | bool ioq_live; | ||
| 145 | bool assoc_active; | 146 | bool assoc_active; |
| 146 | u64 association_id; | 147 | u64 association_id; |
| 147 | 148 | ||
| @@ -2463,6 +2464,8 @@ nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl) | |||
| 2463 | if (ret) | 2464 | if (ret) |
| 2464 | goto out_delete_hw_queues; | 2465 | goto out_delete_hw_queues; |
| 2465 | 2466 | ||
| 2467 | ctrl->ioq_live = true; | ||
| 2468 | |||
| 2466 | return 0; | 2469 | return 0; |
| 2467 | 2470 | ||
| 2468 | out_delete_hw_queues: | 2471 | out_delete_hw_queues: |
| @@ -2615,8 +2618,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl) | |||
| 2615 | if (ret) | 2618 | if (ret) |
| 2616 | goto out_delete_hw_queue; | 2619 | goto out_delete_hw_queue; |
| 2617 | 2620 | ||
| 2618 | if (ctrl->ctrl.state != NVME_CTRL_NEW) | 2621 | blk_mq_unquiesce_queue(ctrl->ctrl.admin_q); |
| 2619 | blk_mq_unquiesce_queue(ctrl->ctrl.admin_q); | ||
| 2620 | 2622 | ||
| 2621 | ret = nvmf_connect_admin_queue(&ctrl->ctrl); | 2623 | ret = nvmf_connect_admin_queue(&ctrl->ctrl); |
| 2622 | if (ret) | 2624 | if (ret) |
| @@ -2689,7 +2691,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl) | |||
| 2689 | */ | 2691 | */ |
| 2690 | 2692 | ||
| 2691 | if (ctrl->ctrl.queue_count > 1) { | 2693 | if (ctrl->ctrl.queue_count > 1) { |
| 2692 | if (ctrl->ctrl.state == NVME_CTRL_NEW) | 2694 | if (!ctrl->ioq_live) |
| 2693 | ret = nvme_fc_create_io_queues(ctrl); | 2695 | ret = nvme_fc_create_io_queues(ctrl); |
| 2694 | else | 2696 | else |
| 2695 | ret = nvme_fc_reinit_io_queues(ctrl); | 2697 | ret = nvme_fc_reinit_io_queues(ctrl); |
| @@ -2776,8 +2778,7 @@ nvme_fc_delete_association(struct nvme_fc_ctrl *ctrl) | |||
| 2776 | * use blk_mq_tagset_busy_itr() and the transport routine to | 2778 | * use blk_mq_tagset_busy_itr() and the transport routine to |
| 2777 | * terminate the exchanges. | 2779 | * terminate the exchanges. |
| 2778 | */ | 2780 | */ |
| 2779 | if (ctrl->ctrl.state != NVME_CTRL_NEW) | 2781 | blk_mq_quiesce_queue(ctrl->ctrl.admin_q); |
| 2780 | blk_mq_quiesce_queue(ctrl->ctrl.admin_q); | ||
| 2781 | blk_mq_tagset_busy_iter(&ctrl->admin_tag_set, | 2782 | blk_mq_tagset_busy_iter(&ctrl->admin_tag_set, |
| 2782 | nvme_fc_terminate_exchange, &ctrl->ctrl); | 2783 | nvme_fc_terminate_exchange, &ctrl->ctrl); |
| 2783 | 2784 | ||
| @@ -2934,7 +2935,7 @@ nvme_fc_connect_ctrl_work(struct work_struct *work) | |||
| 2934 | nvme_fc_reconnect_or_delete(ctrl, ret); | 2935 | nvme_fc_reconnect_or_delete(ctrl, ret); |
| 2935 | else | 2936 | else |
| 2936 | dev_info(ctrl->ctrl.device, | 2937 | dev_info(ctrl->ctrl.device, |
| 2937 | "NVME-FC{%d}: controller reconnect complete\n", | 2938 | "NVME-FC{%d}: controller connect complete\n", |
| 2938 | ctrl->cnum); | 2939 | ctrl->cnum); |
| 2939 | } | 2940 | } |
| 2940 | 2941 | ||
| @@ -2982,7 +2983,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
| 2982 | { | 2983 | { |
| 2983 | struct nvme_fc_ctrl *ctrl; | 2984 | struct nvme_fc_ctrl *ctrl; |
| 2984 | unsigned long flags; | 2985 | unsigned long flags; |
| 2985 | int ret, idx, retry; | 2986 | int ret, idx; |
| 2986 | 2987 | ||
| 2987 | if (!(rport->remoteport.port_role & | 2988 | if (!(rport->remoteport.port_role & |
| 2988 | (FC_PORT_ROLE_NVME_DISCOVERY | FC_PORT_ROLE_NVME_TARGET))) { | 2989 | (FC_PORT_ROLE_NVME_DISCOVERY | FC_PORT_ROLE_NVME_TARGET))) { |
| @@ -3009,11 +3010,13 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
| 3009 | } | 3010 | } |
| 3010 | 3011 | ||
| 3011 | ctrl->ctrl.opts = opts; | 3012 | ctrl->ctrl.opts = opts; |
| 3013 | ctrl->ctrl.nr_reconnects = 0; | ||
| 3012 | INIT_LIST_HEAD(&ctrl->ctrl_list); | 3014 | INIT_LIST_HEAD(&ctrl->ctrl_list); |
| 3013 | ctrl->lport = lport; | 3015 | ctrl->lport = lport; |
| 3014 | ctrl->rport = rport; | 3016 | ctrl->rport = rport; |
| 3015 | ctrl->dev = lport->dev; | 3017 | ctrl->dev = lport->dev; |
| 3016 | ctrl->cnum = idx; | 3018 | ctrl->cnum = idx; |
| 3019 | ctrl->ioq_live = false; | ||
| 3017 | ctrl->assoc_active = false; | 3020 | ctrl->assoc_active = false; |
| 3018 | init_waitqueue_head(&ctrl->ioabort_wait); | 3021 | init_waitqueue_head(&ctrl->ioabort_wait); |
| 3019 | 3022 | ||
| @@ -3032,6 +3035,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
| 3032 | 3035 | ||
| 3033 | ctrl->ctrl.sqsize = opts->queue_size - 1; | 3036 | ctrl->ctrl.sqsize = opts->queue_size - 1; |
| 3034 | ctrl->ctrl.kato = opts->kato; | 3037 | ctrl->ctrl.kato = opts->kato; |
| 3038 | ctrl->ctrl.cntlid = 0xffff; | ||
| 3035 | 3039 | ||
| 3036 | ret = -ENOMEM; | 3040 | ret = -ENOMEM; |
| 3037 | ctrl->queues = kcalloc(ctrl->ctrl.queue_count, | 3041 | ctrl->queues = kcalloc(ctrl->ctrl.queue_count, |
| @@ -3081,62 +3085,24 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
| 3081 | list_add_tail(&ctrl->ctrl_list, &rport->ctrl_list); | 3085 | list_add_tail(&ctrl->ctrl_list, &rport->ctrl_list); |
| 3082 | spin_unlock_irqrestore(&rport->lock, flags); | 3086 | spin_unlock_irqrestore(&rport->lock, flags); |
| 3083 | 3087 | ||
| 3084 | /* | 3088 | if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING) || |
| 3085 | * It's possible that transactions used to create the association | 3089 | !nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { |
| 3086 | * may fail. Examples: CreateAssociation LS or CreateIOConnection | ||
| 3087 | * LS gets dropped/corrupted/fails; or a frame gets dropped or a | ||
| 3088 | * command times out for one of the actions to init the controller | ||
| 3089 | * (Connect, Get/Set_Property, Set_Features, etc). Many of these | ||
| 3090 | * transport errors (frame drop, LS failure) inherently must kill | ||
| 3091 | * the association. The transport is coded so that any command used | ||
| 3092 | * to create the association (prior to a LIVE state transition | ||
| 3093 | * while NEW or CONNECTING) will fail if it completes in error or | ||
| 3094 | * times out. | ||
| 3095 | * | ||
| 3096 | * As such: as the connect request was mostly likely due to a | ||
| 3097 | * udev event that discovered the remote port, meaning there is | ||
| 3098 | * not an admin or script there to restart if the connect | ||
| 3099 | * request fails, retry the initial connection creation up to | ||
| 3100 | * three times before giving up and declaring failure. | ||
| 3101 | */ | ||
| 3102 | for (retry = 0; retry < 3; retry++) { | ||
| 3103 | ret = nvme_fc_create_association(ctrl); | ||
| 3104 | if (!ret) | ||
| 3105 | break; | ||
| 3106 | } | ||
| 3107 | |||
| 3108 | if (ret) { | ||
| 3109 | nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING); | ||
| 3110 | cancel_work_sync(&ctrl->ctrl.reset_work); | ||
| 3111 | cancel_delayed_work_sync(&ctrl->connect_work); | ||
| 3112 | |||
| 3113 | /* couldn't schedule retry - fail out */ | ||
| 3114 | dev_err(ctrl->ctrl.device, | 3090 | dev_err(ctrl->ctrl.device, |
| 3115 | "NVME-FC{%d}: Connect retry failed\n", ctrl->cnum); | 3091 | "NVME-FC{%d}: failed to init ctrl state\n", ctrl->cnum); |
| 3116 | 3092 | goto fail_ctrl; | |
| 3117 | ctrl->ctrl.opts = NULL; | 3093 | } |
| 3118 | 3094 | ||
| 3119 | /* initiate nvme ctrl ref counting teardown */ | 3095 | nvme_get_ctrl(&ctrl->ctrl); |
| 3120 | nvme_uninit_ctrl(&ctrl->ctrl); | ||
| 3121 | 3096 | ||
| 3122 | /* Remove core ctrl ref. */ | 3097 | if (!queue_delayed_work(nvme_wq, &ctrl->connect_work, 0)) { |
| 3123 | nvme_put_ctrl(&ctrl->ctrl); | 3098 | nvme_put_ctrl(&ctrl->ctrl); |
| 3124 | 3099 | dev_err(ctrl->ctrl.device, | |
| 3125 | /* as we're past the point where we transition to the ref | 3100 | "NVME-FC{%d}: failed to schedule initial connect\n", |
| 3126 | * counting teardown path, if we return a bad pointer here, | 3101 | ctrl->cnum); |
| 3127 | * the calling routine, thinking it's prior to the | 3102 | goto fail_ctrl; |
| 3128 | * transition, will do an rport put. Since the teardown | ||
| 3129 | * path also does a rport put, we do an extra get here to | ||
| 3130 | * so proper order/teardown happens. | ||
| 3131 | */ | ||
| 3132 | nvme_fc_rport_get(rport); | ||
| 3133 | |||
| 3134 | if (ret > 0) | ||
| 3135 | ret = -EIO; | ||
| 3136 | return ERR_PTR(ret); | ||
| 3137 | } | 3103 | } |
| 3138 | 3104 | ||
| 3139 | nvme_get_ctrl(&ctrl->ctrl); | 3105 | flush_delayed_work(&ctrl->connect_work); |
| 3140 | 3106 | ||
| 3141 | dev_info(ctrl->ctrl.device, | 3107 | dev_info(ctrl->ctrl.device, |
| 3142 | "NVME-FC{%d}: new ctrl: NQN \"%s\"\n", | 3108 | "NVME-FC{%d}: new ctrl: NQN \"%s\"\n", |
| @@ -3144,6 +3110,30 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
| 3144 | 3110 | ||
| 3145 | return &ctrl->ctrl; | 3111 | return &ctrl->ctrl; |
| 3146 | 3112 | ||
| 3113 | fail_ctrl: | ||
| 3114 | nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_DELETING); | ||
| 3115 | cancel_work_sync(&ctrl->ctrl.reset_work); | ||
| 3116 | cancel_delayed_work_sync(&ctrl->connect_work); | ||
| 3117 | |||
| 3118 | ctrl->ctrl.opts = NULL; | ||
| 3119 | |||
| 3120 | /* initiate nvme ctrl ref counting teardown */ | ||
| 3121 | nvme_uninit_ctrl(&ctrl->ctrl); | ||
| 3122 | |||
| 3123 | /* Remove core ctrl ref. */ | ||
| 3124 | nvme_put_ctrl(&ctrl->ctrl); | ||
| 3125 | |||
| 3126 | /* as we're past the point where we transition to the ref | ||
| 3127 | * counting teardown path, if we return a bad pointer here, | ||
| 3128 | * the calling routine, thinking it's prior to the | ||
| 3129 | * transition, will do an rport put. Since the teardown | ||
| 3130 | * path also does a rport put, we do an extra get here to | ||
| 3131 | * so proper order/teardown happens. | ||
| 3132 | */ | ||
| 3133 | nvme_fc_rport_get(rport); | ||
| 3134 | |||
| 3135 | return ERR_PTR(-EIO); | ||
| 3136 | |||
| 3147 | out_cleanup_admin_q: | 3137 | out_cleanup_admin_q: |
| 3148 | blk_cleanup_queue(ctrl->ctrl.admin_q); | 3138 | blk_cleanup_queue(ctrl->ctrl.admin_q); |
| 3149 | out_free_admin_tag_set: | 3139 | out_free_admin_tag_set: |
