1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2016 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk/nvme.h" 9 #include "spdk/vmd.h" 10 #include "spdk/nvme_zns.h" 11 #include "spdk/env.h" 12 #include "spdk/string.h" 13 #include "spdk/log.h" 14 15 #define DATA_BUFFER_STRING "Hello world!" 16 17 struct ctrlr_entry { 18 struct spdk_nvme_ctrlr *ctrlr; 19 TAILQ_ENTRY(ctrlr_entry) link; 20 char name[1024]; 21 }; 22 23 struct ns_entry { 24 struct spdk_nvme_ctrlr *ctrlr; 25 struct spdk_nvme_ns *ns; 26 TAILQ_ENTRY(ns_entry) link; 27 struct spdk_nvme_qpair *qpair; 28 }; 29 30 static TAILQ_HEAD(, ctrlr_entry) g_controllers = TAILQ_HEAD_INITIALIZER(g_controllers); 31 static TAILQ_HEAD(, ns_entry) g_namespaces = TAILQ_HEAD_INITIALIZER(g_namespaces); 32 static struct spdk_nvme_transport_id g_trid = {}; 33 34 static bool g_vmd = false; 35 36 static void 37 register_ns(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns) 38 { 39 struct ns_entry *entry; 40 41 if (!spdk_nvme_ns_is_active(ns)) { 42 return; 43 } 44 45 entry = malloc(sizeof(struct ns_entry)); 46 if (entry == NULL) { 47 perror("ns_entry malloc"); 48 exit(1); 49 } 50 51 entry->ctrlr = ctrlr; 52 entry->ns = ns; 53 TAILQ_INSERT_TAIL(&g_namespaces, entry, link); 54 55 printf(" Namespace ID: %d size: %juGB\n", spdk_nvme_ns_get_id(ns), 56 spdk_nvme_ns_get_size(ns) / 1000000000); 57 } 58 59 struct hello_world_sequence { 60 struct ns_entry *ns_entry; 61 char *buf; 62 unsigned using_cmb_io; 63 int is_completed; 64 }; 65 66 static void 67 read_complete(void *arg, const struct spdk_nvme_cpl *completion) 68 { 69 struct hello_world_sequence *sequence = arg; 70 71 /* Assume the I/O was successful */ 72 sequence->is_completed = 1; 73 /* See if an error occurred. If so, display information 74 * about it, and set completion value so that I/O 75 * caller is aware that an error occurred. 76 */ 77 if (spdk_nvme_cpl_is_error(completion)) { 78 spdk_nvme_qpair_print_completion(sequence->ns_entry->qpair, (struct spdk_nvme_cpl *)completion); 79 fprintf(stderr, "I/O error status: %s\n", spdk_nvme_cpl_get_status_string(&completion->status)); 80 fprintf(stderr, "Read I/O failed, aborting run\n"); 81 sequence->is_completed = 2; 82 exit(1); 83 } 84 85 if (strcmp(sequence->buf, DATA_BUFFER_STRING)) { 86 fprintf(stderr, "Read data doesn't match write data\n"); 87 exit(1); 88 } 89 90 /* 91 * The read I/O has completed. Print the contents of the 92 * buffer, free the buffer, then mark the sequence as 93 * completed. This will trigger the hello_world() function 94 * to exit its polling loop. 95 */ 96 printf("%s\n", sequence->buf); 97 spdk_free(sequence->buf); 98 } 99 100 static void 101 write_complete(void *arg, const struct spdk_nvme_cpl *completion) 102 { 103 struct hello_world_sequence *sequence = arg; 104 struct ns_entry *ns_entry = sequence->ns_entry; 105 int rc; 106 107 /* See if an error occurred. If so, display information 108 * about it, and set completion value so that I/O 109 * caller is aware that an error occurred. 110 */ 111 if (spdk_nvme_cpl_is_error(completion)) { 112 spdk_nvme_qpair_print_completion(sequence->ns_entry->qpair, (struct spdk_nvme_cpl *)completion); 113 fprintf(stderr, "I/O error status: %s\n", spdk_nvme_cpl_get_status_string(&completion->status)); 114 fprintf(stderr, "Write I/O failed, aborting run\n"); 115 sequence->is_completed = 2; 116 exit(1); 117 } 118 /* 119 * The write I/O has completed. Free the buffer associated with 120 * the write I/O and allocate a new zeroed buffer for reading 121 * the data back from the NVMe namespace. 122 */ 123 if (sequence->using_cmb_io) { 124 spdk_nvme_ctrlr_unmap_cmb(ns_entry->ctrlr); 125 } else { 126 spdk_free(sequence->buf); 127 } 128 sequence->buf = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); 129 130 rc = spdk_nvme_ns_cmd_read(ns_entry->ns, ns_entry->qpair, sequence->buf, 131 0, /* LBA start */ 132 1, /* number of LBAs */ 133 read_complete, (void *)sequence, 0); 134 if (rc != 0) { 135 fprintf(stderr, "starting read I/O failed\n"); 136 exit(1); 137 } 138 } 139 140 static void 141 reset_zone_complete(void *arg, const struct spdk_nvme_cpl *completion) 142 { 143 struct hello_world_sequence *sequence = arg; 144 145 /* Assume the I/O was successful */ 146 sequence->is_completed = 1; 147 /* See if an error occurred. If so, display information 148 * about it, and set completion value so that I/O 149 * caller is aware that an error occurred. 150 */ 151 if (spdk_nvme_cpl_is_error(completion)) { 152 spdk_nvme_qpair_print_completion(sequence->ns_entry->qpair, (struct spdk_nvme_cpl *)completion); 153 fprintf(stderr, "I/O error status: %s\n", spdk_nvme_cpl_get_status_string(&completion->status)); 154 fprintf(stderr, "Reset zone I/O failed, aborting run\n"); 155 sequence->is_completed = 2; 156 exit(1); 157 } 158 } 159 160 static void 161 reset_zone_and_wait_for_completion(struct hello_world_sequence *sequence) 162 { 163 if (spdk_nvme_zns_reset_zone(sequence->ns_entry->ns, sequence->ns_entry->qpair, 164 0, /* starting LBA of the zone to reset */ 165 false, /* don't reset all zones */ 166 reset_zone_complete, 167 sequence)) { 168 fprintf(stderr, "starting reset zone I/O failed\n"); 169 exit(1); 170 } 171 while (!sequence->is_completed) { 172 spdk_nvme_qpair_process_completions(sequence->ns_entry->qpair, 0); 173 } 174 sequence->is_completed = 0; 175 } 176 177 static void 178 hello_world(void) 179 { 180 struct ns_entry *ns_entry; 181 struct hello_world_sequence sequence; 182 int rc; 183 size_t sz; 184 185 TAILQ_FOREACH(ns_entry, &g_namespaces, link) { 186 /* 187 * Allocate an I/O qpair that we can use to submit read/write requests 188 * to namespaces on the controller. NVMe controllers typically support 189 * many qpairs per controller. Any I/O qpair allocated for a controller 190 * can submit I/O to any namespace on that controller. 191 * 192 * The SPDK NVMe driver provides no synchronization for qpair accesses - 193 * the application must ensure only a single thread submits I/O to a 194 * qpair, and that same thread must also check for completions on that 195 * qpair. This enables extremely efficient I/O processing by making all 196 * I/O operations completely lockless. 197 */ 198 ns_entry->qpair = spdk_nvme_ctrlr_alloc_io_qpair(ns_entry->ctrlr, NULL, 0); 199 if (ns_entry->qpair == NULL) { 200 printf("ERROR: spdk_nvme_ctrlr_alloc_io_qpair() failed\n"); 201 return; 202 } 203 204 /* 205 * Use spdk_dma_zmalloc to allocate a 4KB zeroed buffer. This memory 206 * will be pinned, which is required for data buffers used for SPDK NVMe 207 * I/O operations. 208 */ 209 sequence.using_cmb_io = 1; 210 sequence.buf = spdk_nvme_ctrlr_map_cmb(ns_entry->ctrlr, &sz); 211 if (sequence.buf == NULL || sz < 0x1000) { 212 sequence.using_cmb_io = 0; 213 sequence.buf = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); 214 } 215 if (sequence.buf == NULL) { 216 printf("ERROR: write buffer allocation failed\n"); 217 return; 218 } 219 if (sequence.using_cmb_io) { 220 printf("INFO: using controller memory buffer for IO\n"); 221 } else { 222 printf("INFO: using host memory buffer for IO\n"); 223 } 224 sequence.is_completed = 0; 225 sequence.ns_entry = ns_entry; 226 227 /* 228 * If the namespace is a Zoned Namespace, rather than a regular 229 * NVM namespace, we need to reset the first zone, before we 230 * write to it. This not needed for regular NVM namespaces. 231 */ 232 if (spdk_nvme_ns_get_csi(ns_entry->ns) == SPDK_NVME_CSI_ZNS) { 233 reset_zone_and_wait_for_completion(&sequence); 234 } 235 236 /* 237 * Print DATA_BUFFER_STRING to sequence.buf. We will write this data to LBA 238 * 0 on the namespace, and then later read it back into a separate buffer 239 * to demonstrate the full I/O path. 240 */ 241 snprintf(sequence.buf, 0x1000, "%s", DATA_BUFFER_STRING); 242 243 /* 244 * Write the data buffer to LBA 0 of this namespace. "write_complete" and 245 * "&sequence" are specified as the completion callback function and 246 * argument respectively. write_complete() will be called with the 247 * value of &sequence as a parameter when the write I/O is completed. 248 * This allows users to potentially specify different completion 249 * callback routines for each I/O, as well as pass a unique handle 250 * as an argument so the application knows which I/O has completed. 251 * 252 * Note that the SPDK NVMe driver will only check for completions 253 * when the application calls spdk_nvme_qpair_process_completions(). 254 * It is the responsibility of the application to trigger the polling 255 * process. 256 */ 257 rc = spdk_nvme_ns_cmd_write(ns_entry->ns, ns_entry->qpair, sequence.buf, 258 0, /* LBA start */ 259 1, /* number of LBAs */ 260 write_complete, &sequence, 0); 261 if (rc != 0) { 262 fprintf(stderr, "starting write I/O failed\n"); 263 exit(1); 264 } 265 266 /* 267 * Poll for completions. 0 here means process all available completions. 268 * In certain usage models, the caller may specify a positive integer 269 * instead of 0 to signify the maximum number of completions it should 270 * process. This function will never block - if there are no 271 * completions pending on the specified qpair, it will return immediately. 272 * 273 * When the write I/O completes, write_complete() will submit a new I/O 274 * to read LBA 0 into a separate buffer, specifying read_complete() as its 275 * completion routine. When the read I/O completes, read_complete() will 276 * print the buffer contents and set sequence.is_completed = 1. That will 277 * break this loop and then exit the program. 278 */ 279 while (!sequence.is_completed) { 280 spdk_nvme_qpair_process_completions(ns_entry->qpair, 0); 281 } 282 283 /* 284 * Free the I/O qpair. This typically is done when an application exits. 285 * But SPDK does support freeing and then reallocating qpairs during 286 * operation. It is the responsibility of the caller to ensure all 287 * pending I/O are completed before trying to free the qpair. 288 */ 289 spdk_nvme_ctrlr_free_io_qpair(ns_entry->qpair); 290 } 291 } 292 293 static bool 294 probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 295 struct spdk_nvme_ctrlr_opts *opts) 296 { 297 printf("Attaching to %s\n", trid->traddr); 298 299 return true; 300 } 301 302 static void 303 attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 304 struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts) 305 { 306 int nsid; 307 struct ctrlr_entry *entry; 308 struct spdk_nvme_ns *ns; 309 const struct spdk_nvme_ctrlr_data *cdata; 310 311 entry = malloc(sizeof(struct ctrlr_entry)); 312 if (entry == NULL) { 313 perror("ctrlr_entry malloc"); 314 exit(1); 315 } 316 317 printf("Attached to %s\n", trid->traddr); 318 319 /* 320 * spdk_nvme_ctrlr is the logical abstraction in SPDK for an NVMe 321 * controller. During initialization, the IDENTIFY data for the 322 * controller is read using an NVMe admin command, and that data 323 * can be retrieved using spdk_nvme_ctrlr_get_data() to get 324 * detailed information on the controller. Refer to the NVMe 325 * specification for more details on IDENTIFY for NVMe controllers. 326 */ 327 cdata = spdk_nvme_ctrlr_get_data(ctrlr); 328 329 snprintf(entry->name, sizeof(entry->name), "%-20.20s (%-20.20s)", cdata->mn, cdata->sn); 330 331 entry->ctrlr = ctrlr; 332 TAILQ_INSERT_TAIL(&g_controllers, entry, link); 333 334 /* 335 * Each controller has one or more namespaces. An NVMe namespace is basically 336 * equivalent to a SCSI LUN. The controller's IDENTIFY data tells us how 337 * many namespaces exist on the controller. For Intel(R) P3X00 controllers, 338 * it will just be one namespace. 339 * 340 * Note that in NVMe, namespace IDs start at 1, not 0. 341 */ 342 for (nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); nsid != 0; 343 nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, nsid)) { 344 ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); 345 if (ns == NULL) { 346 continue; 347 } 348 register_ns(ctrlr, ns); 349 } 350 } 351 352 static void 353 cleanup(void) 354 { 355 struct ns_entry *ns_entry, *tmp_ns_entry; 356 struct ctrlr_entry *ctrlr_entry, *tmp_ctrlr_entry; 357 struct spdk_nvme_detach_ctx *detach_ctx = NULL; 358 359 TAILQ_FOREACH_SAFE(ns_entry, &g_namespaces, link, tmp_ns_entry) { 360 TAILQ_REMOVE(&g_namespaces, ns_entry, link); 361 free(ns_entry); 362 } 363 364 TAILQ_FOREACH_SAFE(ctrlr_entry, &g_controllers, link, tmp_ctrlr_entry) { 365 TAILQ_REMOVE(&g_controllers, ctrlr_entry, link); 366 spdk_nvme_detach_async(ctrlr_entry->ctrlr, &detach_ctx); 367 free(ctrlr_entry); 368 } 369 370 if (detach_ctx) { 371 spdk_nvme_detach_poll(detach_ctx); 372 } 373 } 374 375 static void 376 usage(const char *program_name) 377 { 378 printf("%s [options]", program_name); 379 printf("\t\n"); 380 printf("options:\n"); 381 printf("\t[-d DPDK huge memory size in MB]\n"); 382 printf("\t[-g use single file descriptor for DPDK memory segments]\n"); 383 printf("\t[-i shared memory group ID]\n"); 384 printf("\t[-r remote NVMe over Fabrics target address]\n"); 385 printf("\t[-V enumerate VMD]\n"); 386 #ifdef DEBUG 387 printf("\t[-L enable debug logging]\n"); 388 #else 389 printf("\t[-L enable debug logging (flag disabled, must reconfigure with --enable-debug)]\n"); 390 #endif 391 } 392 393 static int 394 parse_args(int argc, char **argv, struct spdk_env_opts *env_opts) 395 { 396 int op, rc; 397 398 spdk_nvme_trid_populate_transport(&g_trid, SPDK_NVME_TRANSPORT_PCIE); 399 snprintf(g_trid.subnqn, sizeof(g_trid.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN); 400 401 while ((op = getopt(argc, argv, "d:ghi:r:L:V")) != -1) { 402 switch (op) { 403 case 'V': 404 g_vmd = true; 405 break; 406 case 'i': 407 env_opts->shm_id = spdk_strtol(optarg, 10); 408 if (env_opts->shm_id < 0) { 409 fprintf(stderr, "Invalid shared memory ID\n"); 410 return env_opts->shm_id; 411 } 412 break; 413 case 'g': 414 env_opts->hugepage_single_segments = true; 415 break; 416 case 'r': 417 if (spdk_nvme_transport_id_parse(&g_trid, optarg) != 0) { 418 fprintf(stderr, "Error parsing transport address\n"); 419 return 1; 420 } 421 break; 422 case 'd': 423 env_opts->mem_size = spdk_strtol(optarg, 10); 424 if (env_opts->mem_size < 0) { 425 fprintf(stderr, "Invalid DPDK memory size\n"); 426 return env_opts->mem_size; 427 } 428 break; 429 case 'L': 430 rc = spdk_log_set_flag(optarg); 431 if (rc < 0) { 432 fprintf(stderr, "unknown flag\n"); 433 usage(argv[0]); 434 exit(EXIT_FAILURE); 435 } 436 #ifdef DEBUG 437 spdk_log_set_print_level(SPDK_LOG_DEBUG); 438 #endif 439 break; 440 case 'h': 441 usage(argv[0]); 442 exit(EXIT_SUCCESS); 443 default: 444 usage(argv[0]); 445 return 1; 446 } 447 } 448 449 return 0; 450 } 451 452 int 453 main(int argc, char **argv) 454 { 455 int rc; 456 struct spdk_env_opts opts; 457 458 /* 459 * SPDK relies on an abstraction around the local environment 460 * named env that handles memory allocation and PCI device operations. 461 * This library must be initialized first. 462 * 463 */ 464 spdk_env_opts_init(&opts); 465 rc = parse_args(argc, argv, &opts); 466 if (rc != 0) { 467 return rc; 468 } 469 470 opts.name = "hello_world"; 471 if (spdk_env_init(&opts) < 0) { 472 fprintf(stderr, "Unable to initialize SPDK env\n"); 473 return 1; 474 } 475 476 printf("Initializing NVMe Controllers\n"); 477 478 if (g_vmd && spdk_vmd_init()) { 479 fprintf(stderr, "Failed to initialize VMD." 480 " Some NVMe devices can be unavailable.\n"); 481 } 482 483 /* 484 * Start the SPDK NVMe enumeration process. probe_cb will be called 485 * for each NVMe controller found, giving our application a choice on 486 * whether to attach to each controller. attach_cb will then be 487 * called for each controller after the SPDK NVMe driver has completed 488 * initializing the controller we chose to attach. 489 */ 490 rc = spdk_nvme_probe(&g_trid, NULL, probe_cb, attach_cb, NULL); 491 if (rc != 0) { 492 fprintf(stderr, "spdk_nvme_probe() failed\n"); 493 rc = 1; 494 goto exit; 495 } 496 497 if (TAILQ_EMPTY(&g_controllers)) { 498 fprintf(stderr, "no NVMe controllers found\n"); 499 rc = 1; 500 goto exit; 501 } 502 503 printf("Initialization complete.\n"); 504 hello_world(); 505 506 exit: 507 fflush(stdout); 508 cleanup(); 509 if (g_vmd) { 510 spdk_vmd_fini(); 511 } 512 513 spdk_env_fini(); 514 return rc; 515 } 516