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