1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. All rights reserved. 5 * Copyright (c) 2020 Mellanox Technologies LTD. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/nvmf_spec.h" 35 #include "spdk/string.h" 36 #include "spdk/env.h" 37 #include "nvme_internal.h" 38 #include "nvme_io_msg.h" 39 40 #define SPDK_NVME_DRIVER_NAME "spdk_nvme_driver" 41 42 struct nvme_driver *g_spdk_nvme_driver; 43 pid_t g_spdk_nvme_pid; 44 45 /* gross timeout of 180 seconds in milliseconds */ 46 static int g_nvme_driver_timeout_ms = 3 * 60 * 1000; 47 48 /* Per-process attached controller list */ 49 static TAILQ_HEAD(, spdk_nvme_ctrlr) g_nvme_attached_ctrlrs = 50 TAILQ_HEAD_INITIALIZER(g_nvme_attached_ctrlrs); 51 52 /* Returns true if ctrlr should be stored on the multi-process shared_attached_ctrlrs list */ 53 static bool 54 nvme_ctrlr_shared(const struct spdk_nvme_ctrlr *ctrlr) 55 { 56 return ctrlr->trid.trtype == SPDK_NVME_TRANSPORT_PCIE; 57 } 58 59 void 60 nvme_ctrlr_connected(struct spdk_nvme_probe_ctx *probe_ctx, 61 struct spdk_nvme_ctrlr *ctrlr) 62 { 63 TAILQ_INSERT_TAIL(&probe_ctx->init_ctrlrs, ctrlr, tailq); 64 } 65 66 static void 67 nvme_ctrlr_detach_async_finish(struct spdk_nvme_ctrlr *ctrlr) 68 { 69 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 70 if (nvme_ctrlr_shared(ctrlr)) { 71 TAILQ_REMOVE(&g_spdk_nvme_driver->shared_attached_ctrlrs, ctrlr, tailq); 72 } else { 73 TAILQ_REMOVE(&g_nvme_attached_ctrlrs, ctrlr, tailq); 74 } 75 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 76 } 77 78 static int 79 nvme_ctrlr_detach_async(struct spdk_nvme_ctrlr *ctrlr, 80 struct nvme_ctrlr_detach_ctx **_ctx) 81 { 82 struct nvme_ctrlr_detach_ctx *ctx; 83 int ref_count; 84 85 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 86 87 ref_count = nvme_ctrlr_get_ref_count(ctrlr); 88 assert(ref_count > 0); 89 90 if (ref_count == 1) { 91 /* This is the last reference to the controller, so we need to 92 * allocate a context to destruct it. 93 */ 94 ctx = calloc(1, sizeof(*ctx)); 95 if (ctx == NULL) { 96 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 97 98 return -ENOMEM; 99 } 100 ctx->ctrlr = ctrlr; 101 ctx->cb_fn = nvme_ctrlr_detach_async_finish; 102 103 nvme_ctrlr_proc_put_ref(ctrlr); 104 105 nvme_io_msg_ctrlr_detach(ctrlr); 106 107 nvme_ctrlr_destruct_async(ctrlr, ctx); 108 109 *_ctx = ctx; 110 } else { 111 nvme_ctrlr_proc_put_ref(ctrlr); 112 } 113 114 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 115 116 return 0; 117 } 118 119 static int 120 nvme_ctrlr_detach_poll_async(struct nvme_ctrlr_detach_ctx *ctx) 121 { 122 int rc; 123 124 rc = nvme_ctrlr_destruct_poll_async(ctx->ctrlr, ctx); 125 if (rc == -EAGAIN) { 126 return -EAGAIN; 127 } 128 129 free(ctx); 130 131 return rc; 132 } 133 134 int 135 spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr) 136 { 137 struct nvme_ctrlr_detach_ctx *ctx = NULL; 138 int rc; 139 140 rc = nvme_ctrlr_detach_async(ctrlr, &ctx); 141 if (rc != 0) { 142 return rc; 143 } else if (ctx == NULL) { 144 /* ctrlr was detached from the caller process but any other process 145 * still attaches it. 146 */ 147 return 0; 148 } 149 150 while (1) { 151 rc = nvme_ctrlr_detach_poll_async(ctx); 152 if (rc != -EAGAIN) { 153 break; 154 } 155 nvme_delay(1000); 156 } 157 158 return 0; 159 } 160 161 int 162 spdk_nvme_detach_async(struct spdk_nvme_ctrlr *ctrlr, 163 struct spdk_nvme_detach_ctx **_detach_ctx) 164 { 165 struct spdk_nvme_detach_ctx *detach_ctx; 166 struct nvme_ctrlr_detach_ctx *ctx = NULL; 167 int rc; 168 169 if (ctrlr == NULL || _detach_ctx == NULL) { 170 return -EINVAL; 171 } 172 173 /* Use a context header to poll detachement for multiple controllers. 174 * Allocate an new one if not allocated yet, or use the passed one otherwise. 175 */ 176 detach_ctx = *_detach_ctx; 177 if (detach_ctx == NULL) { 178 detach_ctx = calloc(1, sizeof(*detach_ctx)); 179 if (detach_ctx == NULL) { 180 return -ENOMEM; 181 } 182 TAILQ_INIT(&detach_ctx->head); 183 } else if (detach_ctx->polling_started) { 184 SPDK_ERRLOG("Busy at polling detachment now.\n"); 185 return -EBUSY; 186 } 187 188 rc = nvme_ctrlr_detach_async(ctrlr, &ctx); 189 if (rc != 0 || ctx == NULL) { 190 /* If this detach failed and the context header is empty, it means we just 191 * allocated the header and need to free it before returning. 192 */ 193 if (TAILQ_EMPTY(&detach_ctx->head)) { 194 free(detach_ctx); 195 } 196 return rc; 197 } 198 199 /* Append a context for this detachment to the context header. */ 200 TAILQ_INSERT_TAIL(&detach_ctx->head, ctx, link); 201 202 *_detach_ctx = detach_ctx; 203 204 return 0; 205 } 206 207 int 208 spdk_nvme_detach_poll_async(struct spdk_nvme_detach_ctx *detach_ctx) 209 { 210 struct nvme_ctrlr_detach_ctx *ctx, *tmp_ctx; 211 int rc; 212 213 if (detach_ctx == NULL) { 214 return -EINVAL; 215 } 216 217 detach_ctx->polling_started = true; 218 219 TAILQ_FOREACH_SAFE(ctx, &detach_ctx->head, link, tmp_ctx) { 220 TAILQ_REMOVE(&detach_ctx->head, ctx, link); 221 222 rc = nvme_ctrlr_detach_poll_async(ctx); 223 if (rc == -EAGAIN) { 224 /* If not -EAGAIN, ctx was freed by nvme_ctrlr_detach_poll_async(). */ 225 TAILQ_INSERT_HEAD(&detach_ctx->head, ctx, link); 226 } 227 } 228 229 if (!TAILQ_EMPTY(&detach_ctx->head)) { 230 return -EAGAIN; 231 } 232 233 free(detach_ctx); 234 return 0; 235 } 236 237 void 238 nvme_completion_poll_cb(void *arg, const struct spdk_nvme_cpl *cpl) 239 { 240 struct nvme_completion_poll_status *status = arg; 241 242 if (status->timed_out) { 243 /* There is no routine waiting for the completion of this request, free allocated memory */ 244 free(status); 245 return; 246 } 247 248 /* 249 * Copy status into the argument passed by the caller, so that 250 * the caller can check the status to determine if the 251 * the request passed or failed. 252 */ 253 memcpy(&status->cpl, cpl, sizeof(*cpl)); 254 status->done = true; 255 } 256 257 static void 258 dummy_disconnected_qpair_cb(struct spdk_nvme_qpair *qpair, void *poll_group_ctx) 259 { 260 } 261 262 /** 263 * Poll qpair for completions until a command completes. 264 * 265 * \param qpair queue to poll 266 * \param status completion status. The user must fill this structure with zeroes before calling 267 * this function 268 * \param robust_mutex optional robust mutex to lock while polling qpair 269 * \param timeout_in_usecs optional timeout 270 * 271 * \return 0 if command completed without error, 272 * -EIO if command completed with error, 273 * -ECANCELED if command is not completed due to transport/device error or time expired 274 * 275 * The command to wait upon must be submitted with nvme_completion_poll_cb as the callback 276 * and status as the callback argument. 277 */ 278 int 279 nvme_wait_for_completion_robust_lock_timeout( 280 struct spdk_nvme_qpair *qpair, 281 struct nvme_completion_poll_status *status, 282 pthread_mutex_t *robust_mutex, 283 uint64_t timeout_in_usecs) 284 { 285 uint64_t timeout_tsc = 0; 286 int rc = 0; 287 288 if (timeout_in_usecs) { 289 timeout_tsc = spdk_get_ticks() + timeout_in_usecs * spdk_get_ticks_hz() / SPDK_SEC_TO_USEC; 290 } 291 292 while (status->done == false) { 293 if (robust_mutex) { 294 nvme_robust_mutex_lock(robust_mutex); 295 } 296 297 if (qpair->poll_group) { 298 rc = (int)spdk_nvme_poll_group_process_completions(qpair->poll_group->group, 0, 299 dummy_disconnected_qpair_cb); 300 } else { 301 rc = spdk_nvme_qpair_process_completions(qpair, 0); 302 } 303 304 if (robust_mutex) { 305 nvme_robust_mutex_unlock(robust_mutex); 306 } 307 308 if (rc < 0) { 309 status->cpl.status.sct = SPDK_NVME_SCT_GENERIC; 310 status->cpl.status.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION; 311 break; 312 } 313 if (timeout_tsc && spdk_get_ticks() > timeout_tsc) { 314 rc = -1; 315 break; 316 } 317 if (qpair->ctrlr->trid.trtype == SPDK_NVME_TRANSPORT_PCIE) { 318 union spdk_nvme_csts_register csts = spdk_nvme_ctrlr_get_regs_csts(qpair->ctrlr); 319 if (csts.raw == SPDK_NVME_INVALID_REGISTER_VALUE) { 320 status->cpl.status.sct = SPDK_NVME_SCT_GENERIC; 321 status->cpl.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 322 break; 323 } 324 } 325 } 326 327 if (status->done == false) { 328 status->timed_out = true; 329 } 330 331 if (rc < 0) { 332 return -ECANCELED; 333 } 334 335 return spdk_nvme_cpl_is_error(&status->cpl) ? -EIO : 0; 336 } 337 338 /** 339 * Poll qpair for completions until a command completes. 340 * 341 * \param qpair queue to poll 342 * \param status completion status. The user must fill this structure with zeroes before calling 343 * this function 344 * \param robust_mutex optional robust mutex to lock while polling qpair 345 * 346 * \return 0 if command completed without error, 347 * -EIO if command completed with error, 348 * -ECANCELED if command is not completed due to transport/device error 349 * 350 * The command to wait upon must be submitted with nvme_completion_poll_cb as the callback 351 * and status as the callback argument. 352 */ 353 int 354 nvme_wait_for_completion_robust_lock( 355 struct spdk_nvme_qpair *qpair, 356 struct nvme_completion_poll_status *status, 357 pthread_mutex_t *robust_mutex) 358 { 359 return nvme_wait_for_completion_robust_lock_timeout(qpair, status, robust_mutex, 0); 360 } 361 362 int 363 nvme_wait_for_completion(struct spdk_nvme_qpair *qpair, 364 struct nvme_completion_poll_status *status) 365 { 366 return nvme_wait_for_completion_robust_lock_timeout(qpair, status, NULL, 0); 367 } 368 369 /** 370 * Poll qpair for completions until a command completes. 371 * 372 * \param qpair queue to poll 373 * \param status completion status. The user must fill this structure with zeroes before calling 374 * this function 375 * \param timeout_in_usecs optional timeout 376 * 377 * \return 0 if command completed without error, 378 * -EIO if command completed with error, 379 * -ECANCELED if command is not completed due to transport/device error or time expired 380 * 381 * The command to wait upon must be submitted with nvme_completion_poll_cb as the callback 382 * and status as the callback argument. 383 */ 384 int 385 nvme_wait_for_completion_timeout(struct spdk_nvme_qpair *qpair, 386 struct nvme_completion_poll_status *status, 387 uint64_t timeout_in_usecs) 388 { 389 return nvme_wait_for_completion_robust_lock_timeout(qpair, status, NULL, timeout_in_usecs); 390 } 391 392 static void 393 nvme_user_copy_cmd_complete(void *arg, const struct spdk_nvme_cpl *cpl) 394 { 395 struct nvme_request *req = arg; 396 enum spdk_nvme_data_transfer xfer; 397 398 if (req->user_buffer && req->payload_size) { 399 /* Copy back to the user buffer and free the contig buffer */ 400 assert(nvme_payload_type(&req->payload) == NVME_PAYLOAD_TYPE_CONTIG); 401 xfer = spdk_nvme_opc_get_data_transfer(req->cmd.opc); 402 if (xfer == SPDK_NVME_DATA_CONTROLLER_TO_HOST || 403 xfer == SPDK_NVME_DATA_BIDIRECTIONAL) { 404 assert(req->pid == getpid()); 405 memcpy(req->user_buffer, req->payload.contig_or_cb_arg, req->payload_size); 406 } 407 408 spdk_free(req->payload.contig_or_cb_arg); 409 } 410 411 /* Call the user's original callback now that the buffer has been copied */ 412 req->user_cb_fn(req->user_cb_arg, cpl); 413 } 414 415 /** 416 * Allocate a request as well as a DMA-capable buffer to copy to/from the user's buffer. 417 * 418 * This is intended for use in non-fast-path functions (admin commands, reservations, etc.) 419 * where the overhead of a copy is not a problem. 420 */ 421 struct nvme_request * 422 nvme_allocate_request_user_copy(struct spdk_nvme_qpair *qpair, 423 void *buffer, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, 424 void *cb_arg, bool host_to_controller) 425 { 426 struct nvme_request *req; 427 void *dma_buffer = NULL; 428 429 if (buffer && payload_size) { 430 dma_buffer = spdk_zmalloc(payload_size, 4096, NULL, 431 SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); 432 if (!dma_buffer) { 433 return NULL; 434 } 435 436 if (host_to_controller) { 437 memcpy(dma_buffer, buffer, payload_size); 438 } 439 } 440 441 req = nvme_allocate_request_contig(qpair, dma_buffer, payload_size, nvme_user_copy_cmd_complete, 442 NULL); 443 if (!req) { 444 spdk_free(dma_buffer); 445 return NULL; 446 } 447 448 req->user_cb_fn = cb_fn; 449 req->user_cb_arg = cb_arg; 450 req->user_buffer = buffer; 451 req->cb_arg = req; 452 453 return req; 454 } 455 456 /** 457 * Check if a request has exceeded the controller timeout. 458 * 459 * \param req request to check for timeout. 460 * \param cid command ID for command submitted by req (will be passed to timeout_cb_fn) 461 * \param active_proc per-process data for the controller associated with req 462 * \param now_tick current time from spdk_get_ticks() 463 * \return 0 if requests submitted more recently than req should still be checked for timeouts, or 464 * 1 if requests newer than req need not be checked. 465 * 466 * The request's timeout callback will be called if needed; the caller is only responsible for 467 * calling this function on each outstanding request. 468 */ 469 int 470 nvme_request_check_timeout(struct nvme_request *req, uint16_t cid, 471 struct spdk_nvme_ctrlr_process *active_proc, 472 uint64_t now_tick) 473 { 474 struct spdk_nvme_qpair *qpair = req->qpair; 475 struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr; 476 477 assert(active_proc->timeout_cb_fn != NULL); 478 479 if (req->timed_out || req->submit_tick == 0) { 480 return 0; 481 } 482 483 if (req->pid != g_spdk_nvme_pid) { 484 return 0; 485 } 486 487 if (nvme_qpair_is_admin_queue(qpair) && 488 req->cmd.opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST) { 489 return 0; 490 } 491 492 if (req->submit_tick + active_proc->timeout_ticks > now_tick) { 493 return 1; 494 } 495 496 req->timed_out = true; 497 498 /* 499 * We don't want to expose the admin queue to the user, 500 * so when we're timing out admin commands set the 501 * qpair to NULL. 502 */ 503 active_proc->timeout_cb_fn(active_proc->timeout_cb_arg, ctrlr, 504 nvme_qpair_is_admin_queue(qpair) ? NULL : qpair, 505 cid); 506 return 0; 507 } 508 509 int 510 nvme_robust_mutex_init_shared(pthread_mutex_t *mtx) 511 { 512 int rc = 0; 513 514 #ifdef __FreeBSD__ 515 pthread_mutex_init(mtx, NULL); 516 #else 517 pthread_mutexattr_t attr; 518 519 if (pthread_mutexattr_init(&attr)) { 520 return -1; 521 } 522 if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) || 523 pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST) || 524 pthread_mutex_init(mtx, &attr)) { 525 rc = -1; 526 } 527 pthread_mutexattr_destroy(&attr); 528 #endif 529 530 return rc; 531 } 532 533 int 534 nvme_driver_init(void) 535 { 536 static pthread_mutex_t g_init_mutex = PTHREAD_MUTEX_INITIALIZER; 537 int ret = 0; 538 /* Any socket ID */ 539 int socket_id = -1; 540 541 /* Use a special process-private mutex to ensure the global 542 * nvme driver object (g_spdk_nvme_driver) gets initialized by 543 * only one thread. Once that object is established and its 544 * mutex is initialized, we can unlock this mutex and use that 545 * one instead. 546 */ 547 pthread_mutex_lock(&g_init_mutex); 548 549 /* Each process needs its own pid. */ 550 g_spdk_nvme_pid = getpid(); 551 552 /* 553 * Only one thread from one process will do this driver init work. 554 * The primary process will reserve the shared memory and do the 555 * initialization. 556 * The secondary process will lookup the existing reserved memory. 557 */ 558 if (spdk_process_is_primary()) { 559 /* The unique named memzone already reserved. */ 560 if (g_spdk_nvme_driver != NULL) { 561 pthread_mutex_unlock(&g_init_mutex); 562 return 0; 563 } else { 564 g_spdk_nvme_driver = spdk_memzone_reserve(SPDK_NVME_DRIVER_NAME, 565 sizeof(struct nvme_driver), socket_id, 566 SPDK_MEMZONE_NO_IOVA_CONTIG); 567 } 568 569 if (g_spdk_nvme_driver == NULL) { 570 SPDK_ERRLOG("primary process failed to reserve memory\n"); 571 pthread_mutex_unlock(&g_init_mutex); 572 return -1; 573 } 574 } else { 575 g_spdk_nvme_driver = spdk_memzone_lookup(SPDK_NVME_DRIVER_NAME); 576 577 /* The unique named memzone already reserved by the primary process. */ 578 if (g_spdk_nvme_driver != NULL) { 579 int ms_waited = 0; 580 581 /* Wait the nvme driver to get initialized. */ 582 while ((g_spdk_nvme_driver->initialized == false) && 583 (ms_waited < g_nvme_driver_timeout_ms)) { 584 ms_waited++; 585 nvme_delay(1000); /* delay 1ms */ 586 } 587 if (g_spdk_nvme_driver->initialized == false) { 588 SPDK_ERRLOG("timeout waiting for primary process to init\n"); 589 pthread_mutex_unlock(&g_init_mutex); 590 return -1; 591 } 592 } else { 593 SPDK_ERRLOG("primary process is not started yet\n"); 594 pthread_mutex_unlock(&g_init_mutex); 595 return -1; 596 } 597 598 pthread_mutex_unlock(&g_init_mutex); 599 return 0; 600 } 601 602 /* 603 * At this moment, only one thread from the primary process will do 604 * the g_spdk_nvme_driver initialization 605 */ 606 assert(spdk_process_is_primary()); 607 608 ret = nvme_robust_mutex_init_shared(&g_spdk_nvme_driver->lock); 609 if (ret != 0) { 610 SPDK_ERRLOG("failed to initialize mutex\n"); 611 spdk_memzone_free(SPDK_NVME_DRIVER_NAME); 612 pthread_mutex_unlock(&g_init_mutex); 613 return ret; 614 } 615 616 /* The lock in the shared g_spdk_nvme_driver object is now ready to 617 * be used - so we can unlock the g_init_mutex here. 618 */ 619 pthread_mutex_unlock(&g_init_mutex); 620 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 621 622 g_spdk_nvme_driver->initialized = false; 623 g_spdk_nvme_driver->hotplug_fd = spdk_pci_event_listen(); 624 if (g_spdk_nvme_driver->hotplug_fd < 0) { 625 SPDK_DEBUGLOG(nvme, "Failed to open uevent netlink socket\n"); 626 } 627 628 TAILQ_INIT(&g_spdk_nvme_driver->shared_attached_ctrlrs); 629 630 spdk_uuid_generate(&g_spdk_nvme_driver->default_extended_host_id); 631 632 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 633 634 return ret; 635 } 636 637 /* This function must only be called while holding g_spdk_nvme_driver->lock */ 638 int 639 nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid, 640 struct spdk_nvme_probe_ctx *probe_ctx, void *devhandle) 641 { 642 struct spdk_nvme_ctrlr *ctrlr; 643 struct spdk_nvme_ctrlr_opts opts; 644 645 assert(trid != NULL); 646 647 spdk_nvme_ctrlr_get_default_ctrlr_opts(&opts, sizeof(opts)); 648 649 if (!probe_ctx->probe_cb || probe_ctx->probe_cb(probe_ctx->cb_ctx, trid, &opts)) { 650 ctrlr = nvme_get_ctrlr_by_trid_unsafe(trid); 651 if (ctrlr) { 652 /* This ctrlr already exists. */ 653 654 if (ctrlr->is_destructed) { 655 /* This ctrlr is being destructed asynchronously. */ 656 SPDK_ERRLOG("NVMe controller for SSD: %s is being destructed\n", 657 trid->traddr); 658 return -EBUSY; 659 } 660 661 /* Increase the ref count before calling attach_cb() as the user may 662 * call nvme_detach() immediately. */ 663 nvme_ctrlr_proc_get_ref(ctrlr); 664 665 if (probe_ctx->attach_cb) { 666 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 667 probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts); 668 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 669 } 670 return 0; 671 } 672 673 ctrlr = nvme_transport_ctrlr_construct(trid, &opts, devhandle); 674 if (ctrlr == NULL) { 675 SPDK_ERRLOG("Failed to construct NVMe controller for SSD: %s\n", trid->traddr); 676 return -1; 677 } 678 ctrlr->remove_cb = probe_ctx->remove_cb; 679 ctrlr->cb_ctx = probe_ctx->cb_ctx; 680 681 if (ctrlr->quirks & NVME_QUIRK_MINIMUM_IO_QUEUE_SIZE && 682 ctrlr->opts.io_queue_size == DEFAULT_IO_QUEUE_SIZE) { 683 /* If the user specifically set an IO queue size different than the 684 * default, use that value. Otherwise overwrite with the quirked value. 685 * This allows this quirk to be overridden when necessary. 686 * However, cap.mqes still needs to be respected. 687 */ 688 ctrlr->opts.io_queue_size = spdk_min(DEFAULT_IO_QUEUE_SIZE_FOR_QUIRK, ctrlr->cap.bits.mqes + 1u); 689 } 690 691 nvme_qpair_set_state(ctrlr->adminq, NVME_QPAIR_ENABLED); 692 TAILQ_INSERT_TAIL(&probe_ctx->init_ctrlrs, ctrlr, tailq); 693 return 0; 694 } 695 696 return 1; 697 } 698 699 static void 700 nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr, 701 struct spdk_nvme_probe_ctx *probe_ctx) 702 { 703 int rc = 0; 704 705 rc = nvme_ctrlr_process_init(ctrlr); 706 707 if (rc) { 708 /* Controller failed to initialize. */ 709 TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, tailq); 710 SPDK_ERRLOG("Failed to initialize SSD: %s\n", ctrlr->trid.traddr); 711 nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); 712 nvme_ctrlr_fail(ctrlr, false); 713 nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock); 714 nvme_ctrlr_destruct(ctrlr); 715 return; 716 } 717 718 if (ctrlr->state != NVME_CTRLR_STATE_READY) { 719 return; 720 } 721 722 STAILQ_INIT(&ctrlr->io_producers); 723 724 /* 725 * Controller has been initialized. 726 * Move it to the attached_ctrlrs list. 727 */ 728 TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, tailq); 729 730 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 731 if (nvme_ctrlr_shared(ctrlr)) { 732 TAILQ_INSERT_TAIL(&g_spdk_nvme_driver->shared_attached_ctrlrs, ctrlr, tailq); 733 } else { 734 TAILQ_INSERT_TAIL(&g_nvme_attached_ctrlrs, ctrlr, tailq); 735 } 736 737 /* 738 * Increase the ref count before calling attach_cb() as the user may 739 * call nvme_detach() immediately. 740 */ 741 nvme_ctrlr_proc_get_ref(ctrlr); 742 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 743 744 if (probe_ctx->attach_cb) { 745 probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts); 746 } 747 } 748 749 static int 750 nvme_init_controllers(struct spdk_nvme_probe_ctx *probe_ctx) 751 { 752 int rc = 0; 753 754 while (true) { 755 rc = spdk_nvme_probe_poll_async(probe_ctx); 756 if (rc != -EAGAIN) { 757 return rc; 758 } 759 } 760 761 return rc; 762 } 763 764 /* This function must not be called while holding g_spdk_nvme_driver->lock */ 765 static struct spdk_nvme_ctrlr * 766 nvme_get_ctrlr_by_trid(const struct spdk_nvme_transport_id *trid) 767 { 768 struct spdk_nvme_ctrlr *ctrlr; 769 770 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 771 ctrlr = nvme_get_ctrlr_by_trid_unsafe(trid); 772 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 773 774 return ctrlr; 775 } 776 777 /* This function must be called while holding g_spdk_nvme_driver->lock */ 778 struct spdk_nvme_ctrlr * 779 nvme_get_ctrlr_by_trid_unsafe(const struct spdk_nvme_transport_id *trid) 780 { 781 struct spdk_nvme_ctrlr *ctrlr; 782 783 /* Search per-process list */ 784 TAILQ_FOREACH(ctrlr, &g_nvme_attached_ctrlrs, tailq) { 785 if (spdk_nvme_transport_id_compare(&ctrlr->trid, trid) == 0) { 786 return ctrlr; 787 } 788 } 789 790 /* Search multi-process shared list */ 791 TAILQ_FOREACH(ctrlr, &g_spdk_nvme_driver->shared_attached_ctrlrs, tailq) { 792 if (spdk_nvme_transport_id_compare(&ctrlr->trid, trid) == 0) { 793 return ctrlr; 794 } 795 } 796 797 return NULL; 798 } 799 800 /* This function must only be called while holding g_spdk_nvme_driver->lock */ 801 static int 802 nvme_probe_internal(struct spdk_nvme_probe_ctx *probe_ctx, 803 bool direct_connect) 804 { 805 int rc; 806 struct spdk_nvme_ctrlr *ctrlr, *ctrlr_tmp; 807 808 spdk_nvme_trid_populate_transport(&probe_ctx->trid, probe_ctx->trid.trtype); 809 if (!spdk_nvme_transport_available_by_name(probe_ctx->trid.trstring)) { 810 SPDK_ERRLOG("NVMe trtype %u not available\n", probe_ctx->trid.trtype); 811 return -1; 812 } 813 814 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 815 816 rc = nvme_transport_ctrlr_scan(probe_ctx, direct_connect); 817 if (rc != 0) { 818 SPDK_ERRLOG("NVMe ctrlr scan failed\n"); 819 TAILQ_FOREACH_SAFE(ctrlr, &probe_ctx->init_ctrlrs, tailq, ctrlr_tmp) { 820 TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, tailq); 821 nvme_transport_ctrlr_destruct(ctrlr); 822 } 823 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 824 return -1; 825 } 826 827 /* 828 * Probe controllers on the shared_attached_ctrlrs list 829 */ 830 if (!spdk_process_is_primary() && (probe_ctx->trid.trtype == SPDK_NVME_TRANSPORT_PCIE)) { 831 TAILQ_FOREACH(ctrlr, &g_spdk_nvme_driver->shared_attached_ctrlrs, tailq) { 832 /* Do not attach other ctrlrs if user specify a valid trid */ 833 if ((strlen(probe_ctx->trid.traddr) != 0) && 834 (spdk_nvme_transport_id_compare(&probe_ctx->trid, &ctrlr->trid))) { 835 continue; 836 } 837 838 /* Do not attach if we failed to initialize it in this process */ 839 if (nvme_ctrlr_get_current_process(ctrlr) == NULL) { 840 continue; 841 } 842 843 nvme_ctrlr_proc_get_ref(ctrlr); 844 845 /* 846 * Unlock while calling attach_cb() so the user can call other functions 847 * that may take the driver lock, like nvme_detach(). 848 */ 849 if (probe_ctx->attach_cb) { 850 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 851 probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts); 852 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 853 } 854 } 855 } 856 857 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 858 859 return 0; 860 } 861 862 static void 863 nvme_probe_ctx_init(struct spdk_nvme_probe_ctx *probe_ctx, 864 const struct spdk_nvme_transport_id *trid, 865 void *cb_ctx, 866 spdk_nvme_probe_cb probe_cb, 867 spdk_nvme_attach_cb attach_cb, 868 spdk_nvme_remove_cb remove_cb) 869 { 870 probe_ctx->trid = *trid; 871 probe_ctx->cb_ctx = cb_ctx; 872 probe_ctx->probe_cb = probe_cb; 873 probe_ctx->attach_cb = attach_cb; 874 probe_ctx->remove_cb = remove_cb; 875 TAILQ_INIT(&probe_ctx->init_ctrlrs); 876 } 877 878 int 879 spdk_nvme_probe(const struct spdk_nvme_transport_id *trid, void *cb_ctx, 880 spdk_nvme_probe_cb probe_cb, spdk_nvme_attach_cb attach_cb, 881 spdk_nvme_remove_cb remove_cb) 882 { 883 struct spdk_nvme_transport_id trid_pcie; 884 struct spdk_nvme_probe_ctx *probe_ctx; 885 886 if (trid == NULL) { 887 memset(&trid_pcie, 0, sizeof(trid_pcie)); 888 spdk_nvme_trid_populate_transport(&trid_pcie, SPDK_NVME_TRANSPORT_PCIE); 889 trid = &trid_pcie; 890 } 891 892 probe_ctx = spdk_nvme_probe_async(trid, cb_ctx, probe_cb, 893 attach_cb, remove_cb); 894 if (!probe_ctx) { 895 SPDK_ERRLOG("Create probe context failed\n"); 896 return -1; 897 } 898 899 /* 900 * Keep going even if one or more nvme_attach() calls failed, 901 * but maintain the value of rc to signal errors when we return. 902 */ 903 return nvme_init_controllers(probe_ctx); 904 } 905 906 static bool 907 nvme_connect_probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 908 struct spdk_nvme_ctrlr_opts *opts) 909 { 910 struct spdk_nvme_ctrlr_opts *requested_opts = cb_ctx; 911 912 assert(requested_opts); 913 memcpy(opts, requested_opts, sizeof(*opts)); 914 915 return true; 916 } 917 918 static void 919 nvme_ctrlr_opts_init(struct spdk_nvme_ctrlr_opts *opts, 920 const struct spdk_nvme_ctrlr_opts *opts_user, 921 size_t opts_size_user) 922 { 923 assert(opts); 924 assert(opts_user); 925 926 spdk_nvme_ctrlr_get_default_ctrlr_opts(opts, opts_size_user); 927 928 #define FIELD_OK(field) \ 929 offsetof(struct spdk_nvme_ctrlr_opts, field) + sizeof(opts->field) <= (opts->opts_size) 930 931 #define SET_FIELD(field) \ 932 if (FIELD_OK(field)) { \ 933 opts->field = opts_user->field; \ 934 } 935 936 #define SET_FIELD_ARRAY(field) \ 937 if (FIELD_OK(field)) { \ 938 memcpy(opts->field, opts_user->field, sizeof(opts_user->field)); \ 939 } 940 941 SET_FIELD(num_io_queues); 942 SET_FIELD(use_cmb_sqs); 943 SET_FIELD(no_shn_notification); 944 SET_FIELD(arb_mechanism); 945 SET_FIELD(arbitration_burst); 946 SET_FIELD(low_priority_weight); 947 SET_FIELD(medium_priority_weight); 948 SET_FIELD(high_priority_weight); 949 SET_FIELD(keep_alive_timeout_ms); 950 SET_FIELD(transport_retry_count); 951 SET_FIELD(io_queue_size); 952 SET_FIELD_ARRAY(hostnqn); 953 SET_FIELD(io_queue_requests); 954 SET_FIELD_ARRAY(src_addr); 955 SET_FIELD_ARRAY(src_svcid); 956 SET_FIELD_ARRAY(host_id); 957 SET_FIELD_ARRAY(extended_host_id); 958 SET_FIELD(command_set); 959 SET_FIELD(admin_timeout_ms); 960 SET_FIELD(header_digest); 961 SET_FIELD(data_digest); 962 SET_FIELD(disable_error_logging); 963 SET_FIELD(transport_ack_timeout); 964 SET_FIELD(admin_queue_size); 965 SET_FIELD(fabrics_connect_timeout_us); 966 967 /* Do not remove this statement. When you add a new field, please do update this 968 * assert with the correct size. And do not forget to add a new SET_FIELD statement 969 * related with your new added field. */ 970 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_opts) == 608, "Incorrect size"); 971 972 #undef FIELD_OK 973 #undef SET_FIELD 974 #undef SET_FIELD_ARRAY 975 } 976 977 struct spdk_nvme_ctrlr * 978 spdk_nvme_connect(const struct spdk_nvme_transport_id *trid, 979 const struct spdk_nvme_ctrlr_opts *opts, size_t opts_size) 980 { 981 int rc; 982 struct spdk_nvme_ctrlr *ctrlr = NULL; 983 struct spdk_nvme_probe_ctx *probe_ctx; 984 struct spdk_nvme_ctrlr_opts *opts_local_p = NULL; 985 struct spdk_nvme_ctrlr_opts opts_local; 986 987 if (trid == NULL) { 988 SPDK_ERRLOG("No transport ID specified\n"); 989 return NULL; 990 } 991 992 if (opts) { 993 opts_local_p = &opts_local; 994 nvme_ctrlr_opts_init(opts_local_p, opts, opts_size); 995 } 996 997 probe_ctx = spdk_nvme_connect_async(trid, opts_local_p, NULL); 998 if (!probe_ctx) { 999 SPDK_ERRLOG("Create probe context failed\n"); 1000 return NULL; 1001 } 1002 1003 rc = nvme_init_controllers(probe_ctx); 1004 if (rc != 0) { 1005 return NULL; 1006 } 1007 1008 ctrlr = nvme_get_ctrlr_by_trid(trid); 1009 1010 return ctrlr; 1011 } 1012 1013 void 1014 spdk_nvme_trid_populate_transport(struct spdk_nvme_transport_id *trid, 1015 enum spdk_nvme_transport_type trtype) 1016 { 1017 const char *trstring = ""; 1018 1019 trid->trtype = trtype; 1020 switch (trtype) { 1021 case SPDK_NVME_TRANSPORT_FC: 1022 trstring = SPDK_NVME_TRANSPORT_NAME_FC; 1023 break; 1024 case SPDK_NVME_TRANSPORT_PCIE: 1025 trstring = SPDK_NVME_TRANSPORT_NAME_PCIE; 1026 break; 1027 case SPDK_NVME_TRANSPORT_RDMA: 1028 trstring = SPDK_NVME_TRANSPORT_NAME_RDMA; 1029 break; 1030 case SPDK_NVME_TRANSPORT_TCP: 1031 trstring = SPDK_NVME_TRANSPORT_NAME_TCP; 1032 break; 1033 case SPDK_NVME_TRANSPORT_VFIOUSER: 1034 trstring = SPDK_NVME_TRANSPORT_NAME_VFIOUSER; 1035 break; 1036 case SPDK_NVME_TRANSPORT_CUSTOM: 1037 trstring = SPDK_NVME_TRANSPORT_NAME_CUSTOM; 1038 break; 1039 default: 1040 SPDK_ERRLOG("no available transports\n"); 1041 assert(0); 1042 return; 1043 } 1044 snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", trstring); 1045 } 1046 1047 int 1048 spdk_nvme_transport_id_populate_trstring(struct spdk_nvme_transport_id *trid, const char *trstring) 1049 { 1050 int len, i, rc; 1051 1052 if (trstring == NULL) { 1053 return -EINVAL; 1054 } 1055 1056 len = strnlen(trstring, SPDK_NVMF_TRSTRING_MAX_LEN); 1057 if (len == SPDK_NVMF_TRSTRING_MAX_LEN) { 1058 return -EINVAL; 1059 } 1060 1061 rc = snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", trstring); 1062 if (rc < 0) { 1063 return rc; 1064 } 1065 1066 /* cast official trstring to uppercase version of input. */ 1067 for (i = 0; i < len; i++) { 1068 trid->trstring[i] = toupper(trid->trstring[i]); 1069 } 1070 return 0; 1071 } 1072 1073 int 1074 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str) 1075 { 1076 if (trtype == NULL || str == NULL) { 1077 return -EINVAL; 1078 } 1079 1080 if (strcasecmp(str, "PCIe") == 0) { 1081 *trtype = SPDK_NVME_TRANSPORT_PCIE; 1082 } else if (strcasecmp(str, "RDMA") == 0) { 1083 *trtype = SPDK_NVME_TRANSPORT_RDMA; 1084 } else if (strcasecmp(str, "FC") == 0) { 1085 *trtype = SPDK_NVME_TRANSPORT_FC; 1086 } else if (strcasecmp(str, "TCP") == 0) { 1087 *trtype = SPDK_NVME_TRANSPORT_TCP; 1088 } else if (strcasecmp(str, "VFIOUSER") == 0) { 1089 *trtype = SPDK_NVME_TRANSPORT_VFIOUSER; 1090 } else { 1091 *trtype = SPDK_NVME_TRANSPORT_CUSTOM; 1092 } 1093 return 0; 1094 } 1095 1096 const char * 1097 spdk_nvme_transport_id_trtype_str(enum spdk_nvme_transport_type trtype) 1098 { 1099 switch (trtype) { 1100 case SPDK_NVME_TRANSPORT_PCIE: 1101 return "PCIe"; 1102 case SPDK_NVME_TRANSPORT_RDMA: 1103 return "RDMA"; 1104 case SPDK_NVME_TRANSPORT_FC: 1105 return "FC"; 1106 case SPDK_NVME_TRANSPORT_TCP: 1107 return "TCP"; 1108 case SPDK_NVME_TRANSPORT_VFIOUSER: 1109 return "VFIOUSER"; 1110 case SPDK_NVME_TRANSPORT_CUSTOM: 1111 return "CUSTOM"; 1112 default: 1113 return NULL; 1114 } 1115 } 1116 1117 int 1118 spdk_nvme_transport_id_parse_adrfam(enum spdk_nvmf_adrfam *adrfam, const char *str) 1119 { 1120 if (adrfam == NULL || str == NULL) { 1121 return -EINVAL; 1122 } 1123 1124 if (strcasecmp(str, "IPv4") == 0) { 1125 *adrfam = SPDK_NVMF_ADRFAM_IPV4; 1126 } else if (strcasecmp(str, "IPv6") == 0) { 1127 *adrfam = SPDK_NVMF_ADRFAM_IPV6; 1128 } else if (strcasecmp(str, "IB") == 0) { 1129 *adrfam = SPDK_NVMF_ADRFAM_IB; 1130 } else if (strcasecmp(str, "FC") == 0) { 1131 *adrfam = SPDK_NVMF_ADRFAM_FC; 1132 } else { 1133 return -ENOENT; 1134 } 1135 return 0; 1136 } 1137 1138 const char * 1139 spdk_nvme_transport_id_adrfam_str(enum spdk_nvmf_adrfam adrfam) 1140 { 1141 switch (adrfam) { 1142 case SPDK_NVMF_ADRFAM_IPV4: 1143 return "IPv4"; 1144 case SPDK_NVMF_ADRFAM_IPV6: 1145 return "IPv6"; 1146 case SPDK_NVMF_ADRFAM_IB: 1147 return "IB"; 1148 case SPDK_NVMF_ADRFAM_FC: 1149 return "FC"; 1150 default: 1151 return NULL; 1152 } 1153 } 1154 1155 static size_t 1156 parse_next_key(const char **str, char *key, char *val, size_t key_buf_size, size_t val_buf_size) 1157 { 1158 1159 const char *sep, *sep1; 1160 const char *whitespace = " \t\n"; 1161 size_t key_len, val_len; 1162 1163 *str += strspn(*str, whitespace); 1164 1165 sep = strchr(*str, ':'); 1166 if (!sep) { 1167 sep = strchr(*str, '='); 1168 if (!sep) { 1169 SPDK_ERRLOG("Key without ':' or '=' separator\n"); 1170 return 0; 1171 } 1172 } else { 1173 sep1 = strchr(*str, '='); 1174 if ((sep1 != NULL) && (sep1 < sep)) { 1175 sep = sep1; 1176 } 1177 } 1178 1179 key_len = sep - *str; 1180 if (key_len >= key_buf_size) { 1181 SPDK_ERRLOG("Key length %zu greater than maximum allowed %zu\n", 1182 key_len, key_buf_size - 1); 1183 return 0; 1184 } 1185 1186 memcpy(key, *str, key_len); 1187 key[key_len] = '\0'; 1188 1189 *str += key_len + 1; /* Skip key: */ 1190 val_len = strcspn(*str, whitespace); 1191 if (val_len == 0) { 1192 SPDK_ERRLOG("Key without value\n"); 1193 return 0; 1194 } 1195 1196 if (val_len >= val_buf_size) { 1197 SPDK_ERRLOG("Value length %zu greater than maximum allowed %zu\n", 1198 val_len, val_buf_size - 1); 1199 return 0; 1200 } 1201 1202 memcpy(val, *str, val_len); 1203 val[val_len] = '\0'; 1204 1205 *str += val_len; 1206 1207 return val_len; 1208 } 1209 1210 int 1211 spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char *str) 1212 { 1213 size_t val_len; 1214 char key[32]; 1215 char val[1024]; 1216 1217 if (trid == NULL || str == NULL) { 1218 return -EINVAL; 1219 } 1220 1221 while (*str != '\0') { 1222 1223 val_len = parse_next_key(&str, key, val, sizeof(key), sizeof(val)); 1224 1225 if (val_len == 0) { 1226 SPDK_ERRLOG("Failed to parse transport ID\n"); 1227 return -EINVAL; 1228 } 1229 1230 if (strcasecmp(key, "trtype") == 0) { 1231 if (spdk_nvme_transport_id_populate_trstring(trid, val) != 0) { 1232 SPDK_ERRLOG("invalid transport '%s'\n", val); 1233 return -EINVAL; 1234 } 1235 if (spdk_nvme_transport_id_parse_trtype(&trid->trtype, val) != 0) { 1236 SPDK_ERRLOG("Unknown trtype '%s'\n", val); 1237 return -EINVAL; 1238 } 1239 } else if (strcasecmp(key, "adrfam") == 0) { 1240 if (spdk_nvme_transport_id_parse_adrfam(&trid->adrfam, val) != 0) { 1241 SPDK_ERRLOG("Unknown adrfam '%s'\n", val); 1242 return -EINVAL; 1243 } 1244 } else if (strcasecmp(key, "traddr") == 0) { 1245 if (val_len > SPDK_NVMF_TRADDR_MAX_LEN) { 1246 SPDK_ERRLOG("traddr length %zu greater than maximum allowed %u\n", 1247 val_len, SPDK_NVMF_TRADDR_MAX_LEN); 1248 return -EINVAL; 1249 } 1250 memcpy(trid->traddr, val, val_len + 1); 1251 } else if (strcasecmp(key, "trsvcid") == 0) { 1252 if (val_len > SPDK_NVMF_TRSVCID_MAX_LEN) { 1253 SPDK_ERRLOG("trsvcid length %zu greater than maximum allowed %u\n", 1254 val_len, SPDK_NVMF_TRSVCID_MAX_LEN); 1255 return -EINVAL; 1256 } 1257 memcpy(trid->trsvcid, val, val_len + 1); 1258 } else if (strcasecmp(key, "priority") == 0) { 1259 if (val_len > SPDK_NVMF_PRIORITY_MAX_LEN) { 1260 SPDK_ERRLOG("priority length %zu greater than maximum allowed %u\n", 1261 val_len, SPDK_NVMF_PRIORITY_MAX_LEN); 1262 return -EINVAL; 1263 } 1264 trid->priority = spdk_strtol(val, 10); 1265 } else if (strcasecmp(key, "subnqn") == 0) { 1266 if (val_len > SPDK_NVMF_NQN_MAX_LEN) { 1267 SPDK_ERRLOG("subnqn length %zu greater than maximum allowed %u\n", 1268 val_len, SPDK_NVMF_NQN_MAX_LEN); 1269 return -EINVAL; 1270 } 1271 memcpy(trid->subnqn, val, val_len + 1); 1272 } else if (strcasecmp(key, "hostaddr") == 0) { 1273 continue; 1274 } else if (strcasecmp(key, "hostsvcid") == 0) { 1275 continue; 1276 } else if (strcasecmp(key, "hostnqn") == 0) { 1277 continue; 1278 } else if (strcasecmp(key, "ns") == 0) { 1279 /* 1280 * Special case. The namespace id parameter may 1281 * optionally be passed in the transport id string 1282 * for an SPDK application (e.g. nvme/perf) 1283 * and additionally parsed therein to limit 1284 * targeting a specific namespace. For this 1285 * scenario, just silently ignore this key 1286 * rather than letting it default to logging 1287 * it as an invalid key. 1288 */ 1289 continue; 1290 } else if (strcasecmp(key, "alt_traddr") == 0) { 1291 /* 1292 * Used by applications for enabling transport ID failover. 1293 * Please see the case above for more information on custom parameters. 1294 */ 1295 continue; 1296 } else { 1297 SPDK_ERRLOG("Unknown transport ID key '%s'\n", key); 1298 } 1299 } 1300 1301 return 0; 1302 } 1303 1304 int 1305 spdk_nvme_host_id_parse(struct spdk_nvme_host_id *hostid, const char *str) 1306 { 1307 1308 size_t key_size = 32; 1309 size_t val_size = 1024; 1310 size_t val_len; 1311 char key[key_size]; 1312 char val[val_size]; 1313 1314 if (hostid == NULL || str == NULL) { 1315 return -EINVAL; 1316 } 1317 1318 while (*str != '\0') { 1319 1320 val_len = parse_next_key(&str, key, val, key_size, val_size); 1321 1322 if (val_len == 0) { 1323 SPDK_ERRLOG("Failed to parse host ID\n"); 1324 return val_len; 1325 } 1326 1327 /* Ignore the rest of the options from the transport ID. */ 1328 if (strcasecmp(key, "trtype") == 0) { 1329 continue; 1330 } else if (strcasecmp(key, "adrfam") == 0) { 1331 continue; 1332 } else if (strcasecmp(key, "traddr") == 0) { 1333 continue; 1334 } else if (strcasecmp(key, "trsvcid") == 0) { 1335 continue; 1336 } else if (strcasecmp(key, "subnqn") == 0) { 1337 continue; 1338 } else if (strcasecmp(key, "priority") == 0) { 1339 continue; 1340 } else if (strcasecmp(key, "ns") == 0) { 1341 continue; 1342 } else if (strcasecmp(key, "hostaddr") == 0) { 1343 if (val_len > SPDK_NVMF_TRADDR_MAX_LEN) { 1344 SPDK_ERRLOG("hostaddr length %zu greater than maximum allowed %u\n", 1345 val_len, SPDK_NVMF_TRADDR_MAX_LEN); 1346 return -EINVAL; 1347 } 1348 memcpy(hostid->hostaddr, val, val_len + 1); 1349 1350 } else if (strcasecmp(key, "hostsvcid") == 0) { 1351 if (val_len > SPDK_NVMF_TRSVCID_MAX_LEN) { 1352 SPDK_ERRLOG("trsvcid length %zu greater than maximum allowed %u\n", 1353 val_len, SPDK_NVMF_TRSVCID_MAX_LEN); 1354 return -EINVAL; 1355 } 1356 memcpy(hostid->hostsvcid, val, val_len + 1); 1357 } else { 1358 SPDK_ERRLOG("Unknown transport ID key '%s'\n", key); 1359 } 1360 } 1361 1362 return 0; 1363 } 1364 1365 static int 1366 cmp_int(int a, int b) 1367 { 1368 return a - b; 1369 } 1370 1371 int 1372 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 1373 const struct spdk_nvme_transport_id *trid2) 1374 { 1375 int cmp; 1376 1377 if (trid1->trtype == SPDK_NVME_TRANSPORT_CUSTOM) { 1378 cmp = strcasecmp(trid1->trstring, trid2->trstring); 1379 } else { 1380 cmp = cmp_int(trid1->trtype, trid2->trtype); 1381 } 1382 1383 if (cmp) { 1384 return cmp; 1385 } 1386 1387 if (trid1->trtype == SPDK_NVME_TRANSPORT_PCIE) { 1388 struct spdk_pci_addr pci_addr1 = {}; 1389 struct spdk_pci_addr pci_addr2 = {}; 1390 1391 /* Normalize PCI addresses before comparing */ 1392 if (spdk_pci_addr_parse(&pci_addr1, trid1->traddr) < 0 || 1393 spdk_pci_addr_parse(&pci_addr2, trid2->traddr) < 0) { 1394 return -1; 1395 } 1396 1397 /* PCIe transport ID only uses trtype and traddr */ 1398 return spdk_pci_addr_compare(&pci_addr1, &pci_addr2); 1399 } 1400 1401 cmp = strcasecmp(trid1->traddr, trid2->traddr); 1402 if (cmp) { 1403 return cmp; 1404 } 1405 1406 cmp = cmp_int(trid1->adrfam, trid2->adrfam); 1407 if (cmp) { 1408 return cmp; 1409 } 1410 1411 cmp = strcasecmp(trid1->trsvcid, trid2->trsvcid); 1412 if (cmp) { 1413 return cmp; 1414 } 1415 1416 cmp = strcmp(trid1->subnqn, trid2->subnqn); 1417 if (cmp) { 1418 return cmp; 1419 } 1420 1421 return 0; 1422 } 1423 1424 int 1425 spdk_nvme_prchk_flags_parse(uint32_t *prchk_flags, const char *str) 1426 { 1427 size_t val_len; 1428 char key[32]; 1429 char val[1024]; 1430 1431 if (prchk_flags == NULL || str == NULL) { 1432 return -EINVAL; 1433 } 1434 1435 while (*str != '\0') { 1436 val_len = parse_next_key(&str, key, val, sizeof(key), sizeof(val)); 1437 1438 if (val_len == 0) { 1439 SPDK_ERRLOG("Failed to parse prchk\n"); 1440 return -EINVAL; 1441 } 1442 1443 if (strcasecmp(key, "prchk") == 0) { 1444 if (strcasestr(val, "reftag") != NULL) { 1445 *prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_REFTAG; 1446 } 1447 if (strcasestr(val, "guard") != NULL) { 1448 *prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_GUARD; 1449 } 1450 } else { 1451 SPDK_ERRLOG("Unknown key '%s'\n", key); 1452 return -EINVAL; 1453 } 1454 } 1455 1456 return 0; 1457 } 1458 1459 const char * 1460 spdk_nvme_prchk_flags_str(uint32_t prchk_flags) 1461 { 1462 if (prchk_flags & SPDK_NVME_IO_FLAGS_PRCHK_REFTAG) { 1463 if (prchk_flags & SPDK_NVME_IO_FLAGS_PRCHK_GUARD) { 1464 return "prchk:reftag|guard"; 1465 } else { 1466 return "prchk:reftag"; 1467 } 1468 } else { 1469 if (prchk_flags & SPDK_NVME_IO_FLAGS_PRCHK_GUARD) { 1470 return "prchk:guard"; 1471 } else { 1472 return NULL; 1473 } 1474 } 1475 } 1476 1477 struct spdk_nvme_probe_ctx * 1478 spdk_nvme_probe_async(const struct spdk_nvme_transport_id *trid, 1479 void *cb_ctx, 1480 spdk_nvme_probe_cb probe_cb, 1481 spdk_nvme_attach_cb attach_cb, 1482 spdk_nvme_remove_cb remove_cb) 1483 { 1484 int rc; 1485 struct spdk_nvme_probe_ctx *probe_ctx; 1486 1487 rc = nvme_driver_init(); 1488 if (rc != 0) { 1489 return NULL; 1490 } 1491 1492 probe_ctx = calloc(1, sizeof(*probe_ctx)); 1493 if (!probe_ctx) { 1494 return NULL; 1495 } 1496 1497 nvme_probe_ctx_init(probe_ctx, trid, cb_ctx, probe_cb, attach_cb, remove_cb); 1498 rc = nvme_probe_internal(probe_ctx, false); 1499 if (rc != 0) { 1500 free(probe_ctx); 1501 return NULL; 1502 } 1503 1504 return probe_ctx; 1505 } 1506 1507 int 1508 spdk_nvme_probe_poll_async(struct spdk_nvme_probe_ctx *probe_ctx) 1509 { 1510 struct spdk_nvme_ctrlr *ctrlr, *ctrlr_tmp; 1511 1512 if (!spdk_process_is_primary() && probe_ctx->trid.trtype == SPDK_NVME_TRANSPORT_PCIE) { 1513 free(probe_ctx); 1514 return 0; 1515 } 1516 1517 TAILQ_FOREACH_SAFE(ctrlr, &probe_ctx->init_ctrlrs, tailq, ctrlr_tmp) { 1518 nvme_ctrlr_poll_internal(ctrlr, probe_ctx); 1519 } 1520 1521 if (TAILQ_EMPTY(&probe_ctx->init_ctrlrs)) { 1522 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 1523 g_spdk_nvme_driver->initialized = true; 1524 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 1525 free(probe_ctx); 1526 return 0; 1527 } 1528 1529 return -EAGAIN; 1530 } 1531 1532 struct spdk_nvme_probe_ctx * 1533 spdk_nvme_connect_async(const struct spdk_nvme_transport_id *trid, 1534 const struct spdk_nvme_ctrlr_opts *opts, 1535 spdk_nvme_attach_cb attach_cb) 1536 { 1537 int rc; 1538 spdk_nvme_probe_cb probe_cb = NULL; 1539 struct spdk_nvme_probe_ctx *probe_ctx; 1540 1541 rc = nvme_driver_init(); 1542 if (rc != 0) { 1543 return NULL; 1544 } 1545 1546 probe_ctx = calloc(1, sizeof(*probe_ctx)); 1547 if (!probe_ctx) { 1548 return NULL; 1549 } 1550 1551 if (opts) { 1552 probe_cb = nvme_connect_probe_cb; 1553 } 1554 1555 nvme_probe_ctx_init(probe_ctx, trid, (void *)opts, probe_cb, attach_cb, NULL); 1556 rc = nvme_probe_internal(probe_ctx, true); 1557 if (rc != 0) { 1558 free(probe_ctx); 1559 return NULL; 1560 } 1561 1562 return probe_ctx; 1563 } 1564 1565 SPDK_LOG_REGISTER_COMPONENT(nvme) 1566