Skip to content

Commit adfde7e

Browse files
hreineckekeithbusch
authored andcommitted
nvme-fabrics: short-circuit reconnect retries
Returning a nvme status from nvme_tcp_setup_ctrl() indicates that the association was established and we have received a status from the controller; consequently we should honour the DNR bit. If not any future reconnect attempts will just return the same error, so we can short-circuit the reconnect attempts and fail the connection directly. Signed-off-by: Hannes Reinecke <[email protected]> [dwagner: - extended nvme_should_reconnect] Signed-off-by: Daniel Wagner <[email protected]> Signed-off-by: Keith Busch <[email protected]>
1 parent 4435033 commit adfde7e

File tree

5 files changed

+41
-20
lines changed

5 files changed

+41
-20
lines changed

drivers/nvme/host/fabrics.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,20 @@ int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid)
559559
}
560560
EXPORT_SYMBOL_GPL(nvmf_connect_io_queue);
561561

562-
bool nvmf_should_reconnect(struct nvme_ctrl *ctrl)
562+
/*
563+
* Evaluate the status information returned by the transport in order to decided
564+
* if a reconnect attempt should be scheduled.
565+
*
566+
* Do not retry when:
567+
*
568+
* - the DNR bit is set and the specification states no further connect
569+
* attempts with the same set of paramenters should be attempted.
570+
*/
571+
bool nvmf_should_reconnect(struct nvme_ctrl *ctrl, int status)
563572
{
573+
if (status > 0 && (status & NVME_SC_DNR))
574+
return false;
575+
564576
if (ctrl->opts->max_reconnects == -1 ||
565577
ctrl->nr_reconnects < ctrl->opts->max_reconnects)
566578
return true;

drivers/nvme/host/fabrics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ int nvmf_register_transport(struct nvmf_transport_ops *ops);
223223
void nvmf_unregister_transport(struct nvmf_transport_ops *ops);
224224
void nvmf_free_options(struct nvmf_ctrl_options *opts);
225225
int nvmf_get_address(struct nvme_ctrl *ctrl, char *buf, int size);
226-
bool nvmf_should_reconnect(struct nvme_ctrl *ctrl);
226+
bool nvmf_should_reconnect(struct nvme_ctrl *ctrl, int status);
227227
bool nvmf_ip_options_match(struct nvme_ctrl *ctrl,
228228
struct nvmf_ctrl_options *opts);
229229
void nvmf_set_io_queues(struct nvmf_ctrl_options *opts, u32 nr_io_queues,

drivers/nvme/host/fc.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3310,12 +3310,10 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status)
33103310
dev_info(ctrl->ctrl.device,
33113311
"NVME-FC{%d}: reset: Reconnect attempt failed (%d)\n",
33123312
ctrl->cnum, status);
3313-
if (status > 0 && (status & NVME_SC_DNR))
3314-
recon = false;
33153313
} else if (time_after_eq(jiffies, rport->dev_loss_end))
33163314
recon = false;
33173315

3318-
if (recon && nvmf_should_reconnect(&ctrl->ctrl)) {
3316+
if (recon && nvmf_should_reconnect(&ctrl->ctrl, status)) {
33193317
if (portptr->port_state == FC_OBJSTATE_ONLINE)
33203318
dev_info(ctrl->ctrl.device,
33213319
"NVME-FC{%d}: Reconnect attempt in %ld "

drivers/nvme/host/rdma.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,8 @@ static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl)
982982
kfree(ctrl);
983983
}
984984

985-
static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl)
985+
static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl,
986+
int status)
986987
{
987988
enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl);
988989

@@ -992,7 +993,7 @@ static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl)
992993
return;
993994
}
994995

995-
if (nvmf_should_reconnect(&ctrl->ctrl)) {
996+
if (nvmf_should_reconnect(&ctrl->ctrl, status)) {
996997
dev_info(ctrl->ctrl.device, "Reconnecting in %d seconds...\n",
997998
ctrl->ctrl.opts->reconnect_delay);
998999
queue_delayed_work(nvme_wq, &ctrl->reconnect_work,
@@ -1104,10 +1105,12 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)
11041105
{
11051106
struct nvme_rdma_ctrl *ctrl = container_of(to_delayed_work(work),
11061107
struct nvme_rdma_ctrl, reconnect_work);
1108+
int ret;
11071109

11081110
++ctrl->ctrl.nr_reconnects;
11091111

1110-
if (nvme_rdma_setup_ctrl(ctrl, false))
1112+
ret = nvme_rdma_setup_ctrl(ctrl, false);
1113+
if (ret)
11111114
goto requeue;
11121115

11131116
dev_info(ctrl->ctrl.device, "Successfully reconnected (%d attempts)\n",
@@ -1120,7 +1123,7 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)
11201123
requeue:
11211124
dev_info(ctrl->ctrl.device, "Failed reconnect attempt %d\n",
11221125
ctrl->ctrl.nr_reconnects);
1123-
nvme_rdma_reconnect_or_remove(ctrl);
1126+
nvme_rdma_reconnect_or_remove(ctrl, ret);
11241127
}
11251128

11261129
static void nvme_rdma_error_recovery_work(struct work_struct *work)
@@ -1145,7 +1148,7 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)
11451148
return;
11461149
}
11471150

1148-
nvme_rdma_reconnect_or_remove(ctrl);
1151+
nvme_rdma_reconnect_or_remove(ctrl, 0);
11491152
}
11501153

11511154
static void nvme_rdma_error_recovery(struct nvme_rdma_ctrl *ctrl)
@@ -2169,6 +2172,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
21692172
{
21702173
struct nvme_rdma_ctrl *ctrl =
21712174
container_of(work, struct nvme_rdma_ctrl, ctrl.reset_work);
2175+
int ret;
21722176

21732177
nvme_stop_ctrl(&ctrl->ctrl);
21742178
nvme_rdma_shutdown_ctrl(ctrl, false);
@@ -2179,14 +2183,15 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
21792183
return;
21802184
}
21812185

2182-
if (nvme_rdma_setup_ctrl(ctrl, false))
2186+
ret = nvme_rdma_setup_ctrl(ctrl, false);
2187+
if (ret)
21832188
goto out_fail;
21842189

21852190
return;
21862191

21872192
out_fail:
21882193
++ctrl->ctrl.nr_reconnects;
2189-
nvme_rdma_reconnect_or_remove(ctrl);
2194+
nvme_rdma_reconnect_or_remove(ctrl, ret);
21902195
}
21912196

21922197
static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {

drivers/nvme/host/tcp.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,7 +2155,8 @@ static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl,
21552155
nvme_tcp_destroy_io_queues(ctrl, remove);
21562156
}
21572157

2158-
static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl)
2158+
static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl,
2159+
int status)
21592160
{
21602161
enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
21612162

@@ -2165,13 +2166,14 @@ static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl)
21652166
return;
21662167
}
21672168

2168-
if (nvmf_should_reconnect(ctrl)) {
2169+
if (nvmf_should_reconnect(ctrl, status)) {
21692170
dev_info(ctrl->device, "Reconnecting in %d seconds...\n",
21702171
ctrl->opts->reconnect_delay);
21712172
queue_delayed_work(nvme_wq, &to_tcp_ctrl(ctrl)->connect_work,
21722173
ctrl->opts->reconnect_delay * HZ);
21732174
} else {
2174-
dev_info(ctrl->device, "Removing controller...\n");
2175+
dev_info(ctrl->device, "Removing controller (%d)...\n",
2176+
status);
21752177
nvme_delete_ctrl(ctrl);
21762178
}
21772179
}
@@ -2252,10 +2254,12 @@ static void nvme_tcp_reconnect_ctrl_work(struct work_struct *work)
22522254
struct nvme_tcp_ctrl *tcp_ctrl = container_of(to_delayed_work(work),
22532255
struct nvme_tcp_ctrl, connect_work);
22542256
struct nvme_ctrl *ctrl = &tcp_ctrl->ctrl;
2257+
int ret;
22552258

22562259
++ctrl->nr_reconnects;
22572260

2258-
if (nvme_tcp_setup_ctrl(ctrl, false))
2261+
ret = nvme_tcp_setup_ctrl(ctrl, false);
2262+
if (ret)
22592263
goto requeue;
22602264

22612265
dev_info(ctrl->device, "Successfully reconnected (%d attempt)\n",
@@ -2268,7 +2272,7 @@ static void nvme_tcp_reconnect_ctrl_work(struct work_struct *work)
22682272
requeue:
22692273
dev_info(ctrl->device, "Failed reconnect attempt %d\n",
22702274
ctrl->nr_reconnects);
2271-
nvme_tcp_reconnect_or_remove(ctrl);
2275+
nvme_tcp_reconnect_or_remove(ctrl, ret);
22722276
}
22732277

22742278
static void nvme_tcp_error_recovery_work(struct work_struct *work)
@@ -2295,7 +2299,7 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work)
22952299
return;
22962300
}
22972301

2298-
nvme_tcp_reconnect_or_remove(ctrl);
2302+
nvme_tcp_reconnect_or_remove(ctrl, 0);
22992303
}
23002304

23012305
static void nvme_tcp_teardown_ctrl(struct nvme_ctrl *ctrl, bool shutdown)
@@ -2315,6 +2319,7 @@ static void nvme_reset_ctrl_work(struct work_struct *work)
23152319
{
23162320
struct nvme_ctrl *ctrl =
23172321
container_of(work, struct nvme_ctrl, reset_work);
2322+
int ret;
23182323

23192324
nvme_stop_ctrl(ctrl);
23202325
nvme_tcp_teardown_ctrl(ctrl, false);
@@ -2328,14 +2333,15 @@ static void nvme_reset_ctrl_work(struct work_struct *work)
23282333
return;
23292334
}
23302335

2331-
if (nvme_tcp_setup_ctrl(ctrl, false))
2336+
ret = nvme_tcp_setup_ctrl(ctrl, false);
2337+
if (ret)
23322338
goto out_fail;
23332339

23342340
return;
23352341

23362342
out_fail:
23372343
++ctrl->nr_reconnects;
2338-
nvme_tcp_reconnect_or_remove(ctrl);
2344+
nvme_tcp_reconnect_or_remove(ctrl, ret);
23392345
}
23402346

23412347
static void nvme_tcp_stop_ctrl(struct nvme_ctrl *ctrl)

0 commit comments

Comments
 (0)