Skip to content

Commit 803fbb9

Browse files
committed
Merge tag 'nvme-6.10-2024-05-14' of git://git.infradead.org/nvme into block-6.10
Pull NVMe updates and fixes from Keith: "nvme updates for Linux 6.10 - Fabrics connection retries (Daniel, Hannes) - Fabrics logging enhancements (Tokunori) - RDMA delete optimization (Sagi)" * tag 'nvme-6.10-2024-05-14' of git://git.infradead.org/nvme: nvme-rdma, nvme-tcp: include max reconnects for reconnect logging nvmet-rdma: Avoid o(n^2) loop in delete_ctrl nvme: do not retry authentication failures nvme-fabrics: short-circuit reconnect retries nvme: return kernel error codes for admin queue connect nvmet: return DHCHAP status codes from nvmet_setup_auth() nvmet: lock config semaphore when accessing DH-HMAC-CHAP key
2 parents e56d4b6 + 54a76c8 commit 803fbb9

File tree

14 files changed

+141
-111
lines changed

14 files changed

+141
-111
lines changed

drivers/nvme/host/auth.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ static void nvme_queue_auth_work(struct work_struct *work)
730730
NVME_AUTH_DHCHAP_MESSAGE_CHALLENGE);
731731
if (ret) {
732732
chap->status = ret;
733-
chap->error = -ECONNREFUSED;
733+
chap->error = -EKEYREJECTED;
734734
return;
735735
}
736736

@@ -797,7 +797,7 @@ static void nvme_queue_auth_work(struct work_struct *work)
797797
NVME_AUTH_DHCHAP_MESSAGE_SUCCESS1);
798798
if (ret) {
799799
chap->status = ret;
800-
chap->error = -ECONNREFUSED;
800+
chap->error = -EKEYREJECTED;
801801
return;
802802
}
803803

@@ -818,7 +818,7 @@ static void nvme_queue_auth_work(struct work_struct *work)
818818
ret = nvme_auth_process_dhchap_success1(ctrl, chap);
819819
if (ret) {
820820
/* Controller authentication failed */
821-
chap->error = -ECONNREFUSED;
821+
chap->error = -EKEYREJECTED;
822822
goto fail2;
823823
}
824824

drivers/nvme/host/core.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,14 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req)
383383
if (likely(nvme_req(req)->status == 0))
384384
return COMPLETE;
385385

386-
if ((nvme_req(req)->status & 0x7ff) == NVME_SC_AUTH_REQUIRED)
387-
return AUTHENTICATE;
388-
389386
if (blk_noretry_request(req) ||
390387
(nvme_req(req)->status & NVME_SC_DNR) ||
391388
nvme_req(req)->retries >= nvme_max_retries)
392389
return COMPLETE;
393390

391+
if ((nvme_req(req)->status & 0x7ff) == NVME_SC_AUTH_REQUIRED)
392+
return AUTHENTICATE;
393+
394394
if (req->cmd_flags & REQ_NVME_MPATH) {
395395
if (nvme_is_path_error(nvme_req(req)->status) ||
396396
blk_queue_dying(req->q))

drivers/nvme/host/fabrics.c

+32-19
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,6 @@ static void nvmf_connect_cmd_prep(struct nvme_ctrl *ctrl, u16 qid,
428428
* fabrics-protocol connection of the NVMe Admin queue between the
429429
* host system device and the allocated NVMe controller on the
430430
* target system via a NVMe Fabrics "Connect" command.
431-
*
432-
* Return:
433-
* 0: success
434-
* > 0: NVMe error status code
435-
* < 0: Linux errno error code
436-
*
437431
*/
438432
int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl)
439433
{
@@ -467,22 +461,22 @@ int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl)
467461
if (result & NVME_CONNECT_AUTHREQ_ASCR) {
468462
dev_warn(ctrl->device,
469463
"qid 0: secure concatenation is not supported\n");
470-
ret = NVME_SC_AUTH_REQUIRED;
464+
ret = -EOPNOTSUPP;
471465
goto out_free_data;
472466
}
473467
/* Authentication required */
474468
ret = nvme_auth_negotiate(ctrl, 0);
475469
if (ret) {
476470
dev_warn(ctrl->device,
477471
"qid 0: authentication setup failed\n");
478-
ret = NVME_SC_AUTH_REQUIRED;
479472
goto out_free_data;
480473
}
481474
ret = nvme_auth_wait(ctrl, 0);
482-
if (ret)
475+
if (ret) {
483476
dev_warn(ctrl->device,
484-
"qid 0: authentication failed\n");
485-
else
477+
"qid 0: authentication failed, error %d\n",
478+
ret);
479+
} else
486480
dev_info(ctrl->device,
487481
"qid 0: authenticated\n");
488482
}
@@ -542,20 +536,21 @@ int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid)
542536
if (result & NVME_CONNECT_AUTHREQ_ASCR) {
543537
dev_warn(ctrl->device,
544538
"qid 0: secure concatenation is not supported\n");
545-
ret = NVME_SC_AUTH_REQUIRED;
539+
ret = -EOPNOTSUPP;
546540
goto out_free_data;
547541
}
548542
/* Authentication required */
549543
ret = nvme_auth_negotiate(ctrl, qid);
550544
if (ret) {
551545
dev_warn(ctrl->device,
552546
"qid %d: authentication setup failed\n", qid);
553-
ret = NVME_SC_AUTH_REQUIRED;
554-
} else {
555-
ret = nvme_auth_wait(ctrl, qid);
556-
if (ret)
557-
dev_warn(ctrl->device,
558-
"qid %u: authentication failed\n", qid);
547+
goto out_free_data;
548+
}
549+
ret = nvme_auth_wait(ctrl, qid);
550+
if (ret) {
551+
dev_warn(ctrl->device,
552+
"qid %u: authentication failed, error %d\n",
553+
qid, ret);
559554
}
560555
}
561556
out_free_data:
@@ -564,8 +559,26 @@ int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid)
564559
}
565560
EXPORT_SYMBOL_GPL(nvmf_connect_io_queue);
566561

567-
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+
* - when the authentication attempt fails, because the key was invalid.
572+
* This error code is set on the host side.
573+
*/
574+
bool nvmf_should_reconnect(struct nvme_ctrl *ctrl, int status)
568575
{
576+
if (status > 0 && (status & NVME_SC_DNR))
577+
return false;
578+
579+
if (status == -EKEYREJECTED)
580+
return false;
581+
569582
if (ctrl->opts->max_reconnects == -1 ||
570583
ctrl->nr_reconnects < ctrl->opts->max_reconnects)
571584
return true;

drivers/nvme/host/fabrics.h

+1-1
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

+1-3
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/nvme.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,7 @@ static inline int nvme_auth_negotiate(struct nvme_ctrl *ctrl, int qid)
11481148
}
11491149
static inline int nvme_auth_wait(struct nvme_ctrl *ctrl, int qid)
11501150
{
1151-
return NVME_SC_AUTH_REQUIRED;
1151+
return -EPROTONOSUPPORT;
11521152
}
11531153
static inline void nvme_auth_free(struct nvme_ctrl *ctrl) {};
11541154
#endif

drivers/nvme/host/rdma.c

+14-9
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",
@@ -1118,9 +1121,9 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work)
11181121
return;
11191122

11201123
requeue:
1121-
dev_info(ctrl->ctrl.device, "Failed reconnect attempt %d\n",
1122-
ctrl->ctrl.nr_reconnects);
1123-
nvme_rdma_reconnect_or_remove(ctrl);
1124+
dev_info(ctrl->ctrl.device, "Failed reconnect attempt %d/%d\n",
1125+
ctrl->ctrl.nr_reconnects, ctrl->ctrl.opts->max_reconnects);
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

+18-12
Original file line numberDiff line numberDiff line change
@@ -2161,7 +2161,8 @@ static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl,
21612161
nvme_tcp_destroy_io_queues(ctrl, remove);
21622162
}
21632163

2164-
static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl)
2164+
static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl,
2165+
int status)
21652166
{
21662167
enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
21672168

@@ -2171,13 +2172,14 @@ static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl)
21712172
return;
21722173
}
21732174

2174-
if (nvmf_should_reconnect(ctrl)) {
2175+
if (nvmf_should_reconnect(ctrl, status)) {
21752176
dev_info(ctrl->device, "Reconnecting in %d seconds...\n",
21762177
ctrl->opts->reconnect_delay);
21772178
queue_delayed_work(nvme_wq, &to_tcp_ctrl(ctrl)->connect_work,
21782179
ctrl->opts->reconnect_delay * HZ);
21792180
} else {
2180-
dev_info(ctrl->device, "Removing controller...\n");
2181+
dev_info(ctrl->device, "Removing controller (%d)...\n",
2182+
status);
21812183
nvme_delete_ctrl(ctrl);
21822184
}
21832185
}
@@ -2258,23 +2260,25 @@ static void nvme_tcp_reconnect_ctrl_work(struct work_struct *work)
22582260
struct nvme_tcp_ctrl *tcp_ctrl = container_of(to_delayed_work(work),
22592261
struct nvme_tcp_ctrl, connect_work);
22602262
struct nvme_ctrl *ctrl = &tcp_ctrl->ctrl;
2263+
int ret;
22612264

22622265
++ctrl->nr_reconnects;
22632266

2264-
if (nvme_tcp_setup_ctrl(ctrl, false))
2267+
ret = nvme_tcp_setup_ctrl(ctrl, false);
2268+
if (ret)
22652269
goto requeue;
22662270

2267-
dev_info(ctrl->device, "Successfully reconnected (%d attempt)\n",
2268-
ctrl->nr_reconnects);
2271+
dev_info(ctrl->device, "Successfully reconnected (attempt %d/%d)\n",
2272+
ctrl->nr_reconnects, ctrl->opts->max_reconnects);
22692273

22702274
ctrl->nr_reconnects = 0;
22712275

22722276
return;
22732277

22742278
requeue:
2275-
dev_info(ctrl->device, "Failed reconnect attempt %d\n",
2276-
ctrl->nr_reconnects);
2277-
nvme_tcp_reconnect_or_remove(ctrl);
2279+
dev_info(ctrl->device, "Failed reconnect attempt %d/%d\n",
2280+
ctrl->nr_reconnects, ctrl->opts->max_reconnects);
2281+
nvme_tcp_reconnect_or_remove(ctrl, ret);
22782282
}
22792283

22802284
static void nvme_tcp_error_recovery_work(struct work_struct *work)
@@ -2301,7 +2305,7 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work)
23012305
return;
23022306
}
23032307

2304-
nvme_tcp_reconnect_or_remove(ctrl);
2308+
nvme_tcp_reconnect_or_remove(ctrl, 0);
23052309
}
23062310

23072311
static void nvme_tcp_teardown_ctrl(struct nvme_ctrl *ctrl, bool shutdown)
@@ -2321,6 +2325,7 @@ static void nvme_reset_ctrl_work(struct work_struct *work)
23212325
{
23222326
struct nvme_ctrl *ctrl =
23232327
container_of(work, struct nvme_ctrl, reset_work);
2328+
int ret;
23242329

23252330
nvme_stop_ctrl(ctrl);
23262331
nvme_tcp_teardown_ctrl(ctrl, false);
@@ -2334,14 +2339,15 @@ static void nvme_reset_ctrl_work(struct work_struct *work)
23342339
return;
23352340
}
23362341

2337-
if (nvme_tcp_setup_ctrl(ctrl, false))
2342+
ret = nvme_tcp_setup_ctrl(ctrl, false);
2343+
if (ret)
23382344
goto out_fail;
23392345

23402346
return;
23412347

23422348
out_fail:
23432349
++ctrl->nr_reconnects;
2344-
nvme_tcp_reconnect_or_remove(ctrl);
2350+
nvme_tcp_reconnect_or_remove(ctrl, ret);
23452351
}
23462352

23472353
static void nvme_tcp_stop_ctrl(struct nvme_ctrl *ctrl)

0 commit comments

Comments
 (0)