1c976353bSAnkit Kumar /* SPDX-License-Identifier: BSD-3-Clause 2c976353bSAnkit Kumar * Copyright (c) 2023 Samsung Electronics Co., Ltd. 3c976353bSAnkit Kumar * All rights reserved. 4c976353bSAnkit Kumar */ 5c976353bSAnkit Kumar 6c976353bSAnkit Kumar #include "spdk/stdinc.h" 7c976353bSAnkit Kumar #include "spdk/nvme.h" 8c976353bSAnkit Kumar #include "spdk/env.h" 91d77eec8SKonrad Sztyber #include "spdk/util.h" 10c976353bSAnkit Kumar 11c976353bSAnkit Kumar #define MAX_FDP_EVENTS 0xFF 12c976353bSAnkit Kumar 13c976353bSAnkit Kumar #define SET_EVENT_TYPES ((uint8_t[]){0x0, 0x1, 0x2, 0x3, 0x80, 0x81}) 14c976353bSAnkit Kumar 15c976353bSAnkit Kumar struct ns_entry { 16c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr; 17c976353bSAnkit Kumar struct spdk_nvme_ns *ns; 18c976353bSAnkit Kumar struct ns_entry *next; 19c976353bSAnkit Kumar }; 20c976353bSAnkit Kumar 21c976353bSAnkit Kumar static struct ns_entry *g_namespaces = NULL; 22c976353bSAnkit Kumar static struct spdk_nvme_transport_id g_trid; 23c976353bSAnkit Kumar static bool g_use_trid = false; 24c976353bSAnkit Kumar 25c976353bSAnkit Kumar static int g_outstanding_commands; 26c976353bSAnkit Kumar static int g_fdp_command_result; 27c976353bSAnkit Kumar static uint32_t g_feat_result; 28c976353bSAnkit Kumar static uint16_t ph_for_fdp_event; 29c976353bSAnkit Kumar static uint8_t rgif; 30c976353bSAnkit Kumar static uint8_t fdpci; 31c976353bSAnkit Kumar static uint16_t pid_for_ruhu; 32c976353bSAnkit Kumar static uint32_t g_spdk_sge_size = 4096; 33c976353bSAnkit Kumar 34c976353bSAnkit Kumar static union spdk_nvme_feat_fdp_cdw12 fdp_res; 35c976353bSAnkit Kumar 36c976353bSAnkit Kumar struct io_request { 37c976353bSAnkit Kumar void *contig; 38c976353bSAnkit Kumar uint32_t sgl_offset; 39c976353bSAnkit Kumar uint32_t buf_size; 40c976353bSAnkit Kumar }; 41c976353bSAnkit Kumar 42c976353bSAnkit Kumar static void 43c976353bSAnkit Kumar nvme_req_reset_sgl(void *cb_arg, uint32_t sgl_offset) 44c976353bSAnkit Kumar { 45c976353bSAnkit Kumar struct io_request *req = (struct io_request *)cb_arg; 46c976353bSAnkit Kumar 47c976353bSAnkit Kumar req->sgl_offset = sgl_offset; 48c976353bSAnkit Kumar } 49c976353bSAnkit Kumar 50c976353bSAnkit Kumar static int 51c976353bSAnkit Kumar nvme_req_next_sge(void *cb_arg, void **address, uint32_t *length) 52c976353bSAnkit Kumar { 53c976353bSAnkit Kumar struct io_request *req = (struct io_request *)cb_arg; 54c976353bSAnkit Kumar uint32_t iov_len; 55c976353bSAnkit Kumar 56c976353bSAnkit Kumar *address = req->contig; 57c976353bSAnkit Kumar 58c976353bSAnkit Kumar if (req->sgl_offset) { 59c976353bSAnkit Kumar *address += req->sgl_offset; 60c976353bSAnkit Kumar } 61c976353bSAnkit Kumar 62c976353bSAnkit Kumar iov_len = req->buf_size - req->sgl_offset; 63c976353bSAnkit Kumar if (iov_len > g_spdk_sge_size) { 64c976353bSAnkit Kumar iov_len = g_spdk_sge_size; 65c976353bSAnkit Kumar } 66c976353bSAnkit Kumar 67c976353bSAnkit Kumar req->sgl_offset += iov_len; 68c976353bSAnkit Kumar *length = iov_len; 69c976353bSAnkit Kumar 70c976353bSAnkit Kumar return 0; 71c976353bSAnkit Kumar } 72c976353bSAnkit Kumar 73c976353bSAnkit Kumar static void 74c976353bSAnkit Kumar get_feat_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl) 75c976353bSAnkit Kumar { 76c976353bSAnkit Kumar if (spdk_nvme_cpl_is_error(cpl)) { 77c976353bSAnkit Kumar g_fdp_command_result = -1; 78c976353bSAnkit Kumar } else { 79c976353bSAnkit Kumar g_fdp_command_result = 0; 80c976353bSAnkit Kumar g_feat_result = cpl->cdw0; 81c976353bSAnkit Kumar } 82c976353bSAnkit Kumar 83c976353bSAnkit Kumar g_outstanding_commands--; 84c976353bSAnkit Kumar } 85c976353bSAnkit Kumar 86c976353bSAnkit Kumar static void 87c976353bSAnkit Kumar cmd_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl) 88c976353bSAnkit Kumar { 89c976353bSAnkit Kumar if (spdk_nvme_cpl_is_error(cpl)) { 90c976353bSAnkit Kumar g_fdp_command_result = -1; 91c976353bSAnkit Kumar } else { 92c976353bSAnkit Kumar g_fdp_command_result = 0; 93c976353bSAnkit Kumar } 94c976353bSAnkit Kumar 95c976353bSAnkit Kumar g_outstanding_commands--; 96c976353bSAnkit Kumar } 97c976353bSAnkit Kumar 98c976353bSAnkit Kumar static void 99c976353bSAnkit Kumar print_uint128_hex(uint64_t *v) 100c976353bSAnkit Kumar { 101c976353bSAnkit Kumar unsigned long long lo = v[0], hi = v[1]; 102c976353bSAnkit Kumar if (hi) { 103c976353bSAnkit Kumar printf("0x%llX%016llX", hi, lo); 104c976353bSAnkit Kumar } else { 105c976353bSAnkit Kumar printf("0x%llX", lo); 106c976353bSAnkit Kumar } 107c976353bSAnkit Kumar } 108c976353bSAnkit Kumar 109c976353bSAnkit Kumar static void 110c976353bSAnkit Kumar print_uint128_dec(uint64_t *v) 111c976353bSAnkit Kumar { 112c976353bSAnkit Kumar unsigned long long lo = v[0], hi = v[1]; 113c976353bSAnkit Kumar if (hi) { 114c976353bSAnkit Kumar /* can't handle large (>64-bit) decimal values for now, so fall back to hex */ 115c976353bSAnkit Kumar print_uint128_hex(v); 116c976353bSAnkit Kumar } else { 117c976353bSAnkit Kumar printf("%llu", (unsigned long long)lo); 118c976353bSAnkit Kumar } 119c976353bSAnkit Kumar } 120c976353bSAnkit Kumar 121c976353bSAnkit Kumar static int 122c976353bSAnkit Kumar set_fdp_events(struct spdk_nvme_ns *ns) 123c976353bSAnkit Kumar { 124c976353bSAnkit Kumar int ret; 125c976353bSAnkit Kumar uint8_t fdp_event_type_list[6] = {}; 126c976353bSAnkit Kumar uint32_t nfdp_events = 6; 127c976353bSAnkit Kumar uint32_t cdw11, cdw12; 128c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); 129c976353bSAnkit Kumar int nsid = spdk_nvme_ns_get_id(ns); 130c976353bSAnkit Kumar 131c976353bSAnkit Kumar memcpy(fdp_event_type_list, SET_EVENT_TYPES, nfdp_events); 132c976353bSAnkit Kumar g_outstanding_commands = 0; 133c976353bSAnkit Kumar g_fdp_command_result = -1; 134c976353bSAnkit Kumar 135c976353bSAnkit Kumar cdw11 = (nfdp_events << 16) | ph_for_fdp_event; 136c976353bSAnkit Kumar /* Enable FDP event */ 137c976353bSAnkit Kumar cdw12 = 1; 138c976353bSAnkit Kumar 139c976353bSAnkit Kumar ret = spdk_nvme_ctrlr_cmd_set_feature_ns(ctrlr, SPDK_NVME_FEAT_FDP_EVENTS, cdw11, cdw12, 140c976353bSAnkit Kumar fdp_event_type_list, nfdp_events, 141c976353bSAnkit Kumar get_feat_completion, NULL, nsid); 142c976353bSAnkit Kumar if (ret) { 143c976353bSAnkit Kumar fprintf(stderr, "Set Feature (fdp events) failed\n\n"); 144c976353bSAnkit Kumar return -1; 145c976353bSAnkit Kumar } 146c976353bSAnkit Kumar 147c976353bSAnkit Kumar g_outstanding_commands++; 148c976353bSAnkit Kumar while (g_outstanding_commands) { 149c976353bSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 150c976353bSAnkit Kumar } 151c976353bSAnkit Kumar 152c976353bSAnkit Kumar if (g_fdp_command_result) { 153c976353bSAnkit Kumar fprintf(stderr, "Set Feature (fdp events) failed\n\n"); 154c976353bSAnkit Kumar return -1; 155c976353bSAnkit Kumar } 156c976353bSAnkit Kumar 157c976353bSAnkit Kumar fprintf(stdout, "Set Feature: Enabling FDP events on Placement handle: #%u Success\n\n", 158c976353bSAnkit Kumar ph_for_fdp_event); 159c976353bSAnkit Kumar return 0; 160c976353bSAnkit Kumar } 161c976353bSAnkit Kumar 162c976353bSAnkit Kumar static int 163c976353bSAnkit Kumar get_fdp_events(struct spdk_nvme_ns *ns) 164c976353bSAnkit Kumar { 165c976353bSAnkit Kumar int ret; 166c976353bSAnkit Kumar uint32_t i, cdw11; 167c976353bSAnkit Kumar struct spdk_nvme_fdp_event_desc events[MAX_FDP_EVENTS]; 168c976353bSAnkit Kumar struct spdk_nvme_fdp_event_desc *event_desc; 169c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); 170c976353bSAnkit Kumar int nsid = spdk_nvme_ns_get_id(ns); 171c976353bSAnkit Kumar 172c976353bSAnkit Kumar g_outstanding_commands = 0; 173c976353bSAnkit Kumar g_fdp_command_result = -1; 174c976353bSAnkit Kumar g_feat_result = 0; 175c976353bSAnkit Kumar 176c976353bSAnkit Kumar cdw11 = (MAX_FDP_EVENTS << 16) | ph_for_fdp_event; 177c976353bSAnkit Kumar 178c976353bSAnkit Kumar ret = spdk_nvme_ctrlr_cmd_get_feature_ns(ctrlr, SPDK_NVME_FEAT_FDP_EVENTS, cdw11, 179c976353bSAnkit Kumar events, MAX_FDP_EVENTS * sizeof(struct spdk_nvme_fdp_event_desc), 180c976353bSAnkit Kumar get_feat_completion, NULL, nsid); 181c976353bSAnkit Kumar if (ret) { 182c976353bSAnkit Kumar fprintf(stderr, "Get Feature (fdp events) failed\n\n"); 183c976353bSAnkit Kumar return -1; 184c976353bSAnkit Kumar } 185c976353bSAnkit Kumar 186c976353bSAnkit Kumar g_outstanding_commands++; 187c976353bSAnkit Kumar while (g_outstanding_commands) { 188c976353bSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 189c976353bSAnkit Kumar } 190c976353bSAnkit Kumar 191c976353bSAnkit Kumar if (g_fdp_command_result) { 192c976353bSAnkit Kumar fprintf(stderr, "Get Feature (fdp events) failed\n\n"); 193c976353bSAnkit Kumar return -1; 194c976353bSAnkit Kumar } 195c976353bSAnkit Kumar 196c976353bSAnkit Kumar fprintf(stdout, "Get Feature: FDP Events for Placement handle: #%u\n", ph_for_fdp_event); 197c976353bSAnkit Kumar fprintf(stdout, "========================\n"); 198c976353bSAnkit Kumar fprintf(stdout, "Number of FDP Events: %u\n", g_feat_result); 199c976353bSAnkit Kumar 200c976353bSAnkit Kumar event_desc = events; 201c976353bSAnkit Kumar for (i = 0; i < g_feat_result; i++) { 202c976353bSAnkit Kumar fprintf(stdout, "FDP Event: #%u Type: %s", i, 203c976353bSAnkit Kumar event_desc->fdp_etype == SPDK_NVME_FDP_EVENT_RU_NOT_WRITTEN_CAPACITY ? 204c976353bSAnkit Kumar "RU Not Written to Capacity " : 205c976353bSAnkit Kumar event_desc->fdp_etype == SPDK_NVME_FDP_EVENT_RU_TIME_LIMIT_EXCEEDED ? 206c976353bSAnkit Kumar "RU Time Limit Exceeded " : 207c976353bSAnkit Kumar event_desc->fdp_etype == SPDK_NVME_FDP_EVENT_CTRLR_RESET_MODIFY_RUH ? 208c976353bSAnkit Kumar "Ctrlr Reset Modified RUH's " : 209c976353bSAnkit Kumar event_desc->fdp_etype == SPDK_NVME_FDP_EVENT_INVALID_PLACEMENT_ID ? 210c976353bSAnkit Kumar "Invalid Placement Identifier " : 211c976353bSAnkit Kumar event_desc->fdp_etype == SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED ? "Media Reallocated " : 212c976353bSAnkit Kumar event_desc->fdp_etype == SPDK_NVME_FDP_EVENT_IMPLICIT_MODIFIED_RUH ? 213c976353bSAnkit Kumar "Implicitly modified RUH " : 214c976353bSAnkit Kumar "Reserved"); 215c976353bSAnkit Kumar fprintf(stdout, " Enabled: %s\n", 216c976353bSAnkit Kumar event_desc->fdpeta.bits.fdp_ee ? "Yes" : "No"); 217c976353bSAnkit Kumar event_desc++; 218c976353bSAnkit Kumar } 219c976353bSAnkit Kumar 220c976353bSAnkit Kumar fprintf(stdout, "\n"); 221c976353bSAnkit Kumar return 0; 222c976353bSAnkit Kumar } 223c976353bSAnkit Kumar 224c976353bSAnkit Kumar static int 225c976353bSAnkit Kumar get_fdp(struct spdk_nvme_ns *ns) 226c976353bSAnkit Kumar { 227c976353bSAnkit Kumar int ret; 228c976353bSAnkit Kumar uint32_t cdw11; 229c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); 230c976353bSAnkit Kumar const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); 231c976353bSAnkit Kumar 232c976353bSAnkit Kumar g_outstanding_commands = 0; 233c976353bSAnkit Kumar g_fdp_command_result = -1; 234c976353bSAnkit Kumar g_feat_result = 0; 235c976353bSAnkit Kumar 236c976353bSAnkit Kumar cdw11 = nsdata->endgid; 237c976353bSAnkit Kumar 238c976353bSAnkit Kumar ret = spdk_nvme_ctrlr_cmd_get_feature(ctrlr, SPDK_NVME_FEAT_FDP, cdw11, NULL, 0, 239c976353bSAnkit Kumar get_feat_completion, NULL); 240c976353bSAnkit Kumar if (ret) { 241c976353bSAnkit Kumar fprintf(stderr, "Get Feature (fdp) failed\n\n"); 242c976353bSAnkit Kumar return -1; 243c976353bSAnkit Kumar } 244c976353bSAnkit Kumar 245c976353bSAnkit Kumar g_outstanding_commands++; 246c976353bSAnkit Kumar while (g_outstanding_commands) { 247c976353bSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 248c976353bSAnkit Kumar } 249c976353bSAnkit Kumar 250c976353bSAnkit Kumar if (g_fdp_command_result) { 251c976353bSAnkit Kumar fprintf(stderr, "Get Feature (fdp) failed\n\n"); 252c976353bSAnkit Kumar return -1; 253c976353bSAnkit Kumar } 254c976353bSAnkit Kumar 255c976353bSAnkit Kumar fdp_res.raw = g_feat_result; 256c976353bSAnkit Kumar 257c976353bSAnkit Kumar fprintf(stdout, "Get Feature: FDP:\n"); 258c976353bSAnkit Kumar fprintf(stdout, "=================\n"); 259c976353bSAnkit Kumar fprintf(stdout, " Enabled: %s\n", 260c976353bSAnkit Kumar fdp_res.bits.fdpe ? "Yes" : "No"); 261c976353bSAnkit Kumar fprintf(stdout, " FDP configuration Index: %u\n\n", fdp_res.bits.fdpci); 262c976353bSAnkit Kumar 263c976353bSAnkit Kumar return 0; 264c976353bSAnkit Kumar } 265c976353bSAnkit Kumar 266c976353bSAnkit Kumar static int 267c976353bSAnkit Kumar check_fdp_write(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair) 268c976353bSAnkit Kumar { 269c976353bSAnkit Kumar int ret; 270c976353bSAnkit Kumar uint32_t sector_size, lba_count; 271c976353bSAnkit Kumar uint64_t lba; 272c976353bSAnkit Kumar struct io_request *req; 273c976353bSAnkit Kumar struct spdk_nvme_ns_cmd_ext_io_opts ext_opts; 274c976353bSAnkit Kumar 275c976353bSAnkit Kumar g_outstanding_commands = 0; 276c976353bSAnkit Kumar g_fdp_command_result = -1; 277c976353bSAnkit Kumar 2781d77eec8SKonrad Sztyber ext_opts.size = SPDK_SIZEOF(&ext_opts, cdw13); 279c976353bSAnkit Kumar ext_opts.io_flags = SPDK_NVME_IO_FLAGS_DATA_PLACEMENT_DIRECTIVE; 280c976353bSAnkit Kumar ext_opts.metadata = NULL; 281c976353bSAnkit Kumar ext_opts.cdw13 = (pid_for_ruhu << 16); 282c976353bSAnkit Kumar 283c976353bSAnkit Kumar sector_size = spdk_nvme_ns_get_sector_size(ns); 284c976353bSAnkit Kumar 285c976353bSAnkit Kumar req = spdk_zmalloc(sizeof(*req), 0, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA); 286c976353bSAnkit Kumar assert(req); 287c976353bSAnkit Kumar 288c976353bSAnkit Kumar lba = 0; 289c976353bSAnkit Kumar lba_count = 8; 290c976353bSAnkit Kumar req->buf_size = sector_size * lba_count; 291c976353bSAnkit Kumar req->contig = spdk_zmalloc(req->buf_size, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, 292c976353bSAnkit Kumar SPDK_MALLOC_DMA); 293c976353bSAnkit Kumar assert(req->contig); 294c976353bSAnkit Kumar 295c976353bSAnkit Kumar ret = spdk_nvme_ns_cmd_writev_ext(ns, qpair, lba, lba_count, cmd_completion, req, 296c976353bSAnkit Kumar nvme_req_reset_sgl, nvme_req_next_sge, &ext_opts); 297c976353bSAnkit Kumar 298c976353bSAnkit Kumar if (ret) { 299c976353bSAnkit Kumar fprintf(stderr, "spdk_nvme_ns_cmd_writev_ext failed\n\n"); 3004ab55a0cSAnkit Kumar spdk_free(req->contig); 3014ab55a0cSAnkit Kumar spdk_free(req); 302c976353bSAnkit Kumar return -1; 303c976353bSAnkit Kumar } 304c976353bSAnkit Kumar 305c976353bSAnkit Kumar g_outstanding_commands++; 306c976353bSAnkit Kumar while (g_outstanding_commands) { 307c976353bSAnkit Kumar spdk_nvme_qpair_process_completions(qpair, 100); 308c976353bSAnkit Kumar } 309c976353bSAnkit Kumar 310c976353bSAnkit Kumar if (g_fdp_command_result) { 311c976353bSAnkit Kumar fprintf(stderr, "FDP write on placement id: %u failed\n\n", pid_for_ruhu); 312c976353bSAnkit Kumar } else { 313c976353bSAnkit Kumar fprintf(stdout, "FDP write on placement id: %u success\n\n", pid_for_ruhu); 314c976353bSAnkit Kumar } 315c976353bSAnkit Kumar 316c976353bSAnkit Kumar spdk_free(req->contig); 317c976353bSAnkit Kumar spdk_free(req); 318c976353bSAnkit Kumar return g_fdp_command_result; 319c976353bSAnkit Kumar } 320c976353bSAnkit Kumar 321c976353bSAnkit Kumar static int 322c976353bSAnkit Kumar reclaim_unit_handle_update(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair) 323c976353bSAnkit Kumar { 324c976353bSAnkit Kumar int ret; 325c976353bSAnkit Kumar uint32_t npids = 1; 326c976353bSAnkit Kumar uint16_t pid_list[1] = {}; 327c976353bSAnkit Kumar 328c976353bSAnkit Kumar memcpy(pid_list, &pid_for_ruhu, sizeof(pid_list)); 329c976353bSAnkit Kumar g_outstanding_commands = 0; 330c976353bSAnkit Kumar g_fdp_command_result = -1; 331c976353bSAnkit Kumar 332c976353bSAnkit Kumar ret = spdk_nvme_ns_cmd_io_mgmt_send(ns, qpair, pid_list, npids * sizeof(uint16_t), 333c976353bSAnkit Kumar SPDK_NVME_FDP_IO_MGMT_SEND_RUHU, npids - 1, cmd_completion, NULL); 334c976353bSAnkit Kumar if (ret) { 335c976353bSAnkit Kumar fprintf(stderr, "IO management send: RUH update failed\n\n"); 336c976353bSAnkit Kumar return -1; 337c976353bSAnkit Kumar } 338c976353bSAnkit Kumar 339c976353bSAnkit Kumar g_outstanding_commands++; 340c976353bSAnkit Kumar while (g_outstanding_commands) { 341c976353bSAnkit Kumar spdk_nvme_qpair_process_completions(qpair, 100); 342c976353bSAnkit Kumar } 343c976353bSAnkit Kumar 344c976353bSAnkit Kumar if (g_fdp_command_result) { 345c976353bSAnkit Kumar fprintf(stderr, "IO management send: RUH update failed\n\n"); 346c976353bSAnkit Kumar return -1; 347c976353bSAnkit Kumar } 348c976353bSAnkit Kumar 349c976353bSAnkit Kumar fprintf(stdout, "IO mgmt send: RUH update for Placement ID: #%u Success\n\n", 350c976353bSAnkit Kumar pid_for_ruhu); 351c976353bSAnkit Kumar return 0; 352c976353bSAnkit Kumar } 353c976353bSAnkit Kumar 354c976353bSAnkit Kumar static int 355c976353bSAnkit Kumar reclaim_unit_handle_status(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair) 356c976353bSAnkit Kumar { 357c976353bSAnkit Kumar int ret; 358c976353bSAnkit Kumar uint32_t i; 359c976353bSAnkit Kumar size_t fdp_ruhs_size; 360c976353bSAnkit Kumar struct spdk_nvme_fdp_ruhs *fdp_ruhs; 361c976353bSAnkit Kumar struct spdk_nvme_fdp_ruhs_desc *ruhs_desc; 362c976353bSAnkit Kumar 363c976353bSAnkit Kumar g_outstanding_commands = 0; 364c976353bSAnkit Kumar g_fdp_command_result = -1; 365c976353bSAnkit Kumar 3664ab55a0cSAnkit Kumar fdp_ruhs_size = sizeof(struct spdk_nvme_fdp_ruhs); 367c976353bSAnkit Kumar fdp_ruhs = calloc(1, fdp_ruhs_size); 3684ab55a0cSAnkit Kumar if (!fdp_ruhs) { 369c976353bSAnkit Kumar fprintf(stderr, "FDP reclaim unit handle status allocation failed!\n\n"); 370c976353bSAnkit Kumar return -1; 371c976353bSAnkit Kumar } 372c976353bSAnkit Kumar 3734ab55a0cSAnkit Kumar /* Fetch the reclaim unit handle status header */ 3744ab55a0cSAnkit Kumar ret = spdk_nvme_ns_cmd_io_mgmt_recv(ns, qpair, fdp_ruhs, fdp_ruhs_size, 3754ab55a0cSAnkit Kumar SPDK_NVME_FDP_IO_MGMT_RECV_RUHS, 0, cmd_completion, NULL); 3764ab55a0cSAnkit Kumar if (ret) { 3774ab55a0cSAnkit Kumar fprintf(stderr, "IO management receive: RUH status failed\n\n"); 3784ab55a0cSAnkit Kumar free(fdp_ruhs); 3794ab55a0cSAnkit Kumar return -1; 3804ab55a0cSAnkit Kumar } 3814ab55a0cSAnkit Kumar 3824ab55a0cSAnkit Kumar g_outstanding_commands++; 3834ab55a0cSAnkit Kumar while (g_outstanding_commands) { 3844ab55a0cSAnkit Kumar spdk_nvme_qpair_process_completions(qpair, 100); 3854ab55a0cSAnkit Kumar } 3864ab55a0cSAnkit Kumar 3874ab55a0cSAnkit Kumar if (g_fdp_command_result) { 3884ab55a0cSAnkit Kumar fprintf(stderr, "IO management receive: RUH status failed\n\n"); 3894ab55a0cSAnkit Kumar free(fdp_ruhs); 3904ab55a0cSAnkit Kumar return -1; 3914ab55a0cSAnkit Kumar } 3924ab55a0cSAnkit Kumar 3934ab55a0cSAnkit Kumar fdp_ruhs_size += fdp_ruhs->nruhsd * sizeof(struct spdk_nvme_fdp_ruhs_desc); 3944ab55a0cSAnkit Kumar fdp_ruhs = realloc(fdp_ruhs, fdp_ruhs_size); 3954ab55a0cSAnkit Kumar if (!fdp_ruhs) { 3964ab55a0cSAnkit Kumar fprintf(stderr, "FDP reclaim unit handle status buffer reallocation failed!\n\n"); 3974ab55a0cSAnkit Kumar return -1; 3984ab55a0cSAnkit Kumar } 3994ab55a0cSAnkit Kumar 400c976353bSAnkit Kumar ret = spdk_nvme_ns_cmd_io_mgmt_recv(ns, qpair, fdp_ruhs, fdp_ruhs_size, 401c976353bSAnkit Kumar SPDK_NVME_FDP_IO_MGMT_RECV_RUHS, 0, cmd_completion, NULL); 402c976353bSAnkit Kumar if (ret) { 403c976353bSAnkit Kumar fprintf(stderr, "IO management receive: RUH status failed\n\n"); 404c976353bSAnkit Kumar free(fdp_ruhs); 405c976353bSAnkit Kumar return -1; 406c976353bSAnkit Kumar } 407c976353bSAnkit Kumar 408c976353bSAnkit Kumar g_outstanding_commands++; 409c976353bSAnkit Kumar while (g_outstanding_commands) { 410c976353bSAnkit Kumar spdk_nvme_qpair_process_completions(qpair, 100); 411c976353bSAnkit Kumar } 412c976353bSAnkit Kumar 413c976353bSAnkit Kumar if (g_fdp_command_result) { 414c976353bSAnkit Kumar fprintf(stderr, "IO management receive: RUH status failed\n\n"); 415c976353bSAnkit Kumar free(fdp_ruhs); 416c976353bSAnkit Kumar return -1; 417c976353bSAnkit Kumar } 418c976353bSAnkit Kumar 419c976353bSAnkit Kumar fprintf(stdout, "FDP Reclaim unit handle status\n"); 420c976353bSAnkit Kumar fprintf(stdout, "==============================\n"); 421c976353bSAnkit Kumar 422c976353bSAnkit Kumar fprintf(stdout, "Number of RUHS descriptors: %u\n", fdp_ruhs->nruhsd); 423c976353bSAnkit Kumar for (i = 0; i < fdp_ruhs->nruhsd; i++) { 424c976353bSAnkit Kumar ruhs_desc = &fdp_ruhs->ruhs_desc[i]; 425c976353bSAnkit Kumar 426c976353bSAnkit Kumar fprintf(stdout, 427c976353bSAnkit Kumar "RUHS Desc: #%04u PID: 0x%04x RUHID: 0x%04x ERUT: 0x%08x RUAMW: 0x%016"PRIx64"\n", 428c976353bSAnkit Kumar i, ruhs_desc->pid, ruhs_desc->ruhid, ruhs_desc->earutr, ruhs_desc->ruamw); 429c976353bSAnkit Kumar } 430c976353bSAnkit Kumar fprintf(stdout, "\n"); 431c976353bSAnkit Kumar 432c976353bSAnkit Kumar /* Use this Placement Identifier for Reclaim unit handle Update */ 433c976353bSAnkit Kumar pid_for_ruhu = (&fdp_ruhs->ruhs_desc[0])->pid; 434c976353bSAnkit Kumar 435c976353bSAnkit Kumar /* Use this Placement Handle to enable FDP events */ 436c976353bSAnkit Kumar ph_for_fdp_event = pid_for_ruhu & ((1 << (16 - rgif)) - 1); 437c976353bSAnkit Kumar 438c976353bSAnkit Kumar free(fdp_ruhs); 439c976353bSAnkit Kumar return 0; 440c976353bSAnkit Kumar } 441c976353bSAnkit Kumar 442c976353bSAnkit Kumar static int 443c976353bSAnkit Kumar get_fdp_cfg_log_page(struct spdk_nvme_ns *ns) 444c976353bSAnkit Kumar { 445c976353bSAnkit Kumar uint32_t i, j; 4464ab55a0cSAnkit Kumar size_t fdp_cfg_size; 4474ab55a0cSAnkit Kumar struct spdk_nvme_fdp_cfg_log_page *fdp_cfg_log_page; 448c976353bSAnkit Kumar struct spdk_nvme_fdp_cfg_descriptor *cfg_desc; 449c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); 450c976353bSAnkit Kumar const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); 451c976353bSAnkit Kumar void *log; 452c976353bSAnkit Kumar 453c976353bSAnkit Kumar g_outstanding_commands = 0; 454c976353bSAnkit Kumar g_fdp_command_result = -1; 455c976353bSAnkit Kumar 4564ab55a0cSAnkit Kumar fdp_cfg_size = sizeof(struct spdk_nvme_fdp_cfg_log_page); 4574ab55a0cSAnkit Kumar fdp_cfg_log_page = calloc(1, fdp_cfg_size); 4584ab55a0cSAnkit Kumar if (!fdp_cfg_log_page) { 4594ab55a0cSAnkit Kumar fprintf(stderr, "FDP config log page allocation failed!\n\n"); 4604ab55a0cSAnkit Kumar return -1; 4614ab55a0cSAnkit Kumar } 4624ab55a0cSAnkit Kumar 4634ab55a0cSAnkit Kumar /* Fetch the FDP configurations log page header */ 464c976353bSAnkit Kumar if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_CONFIGURATIONS, 0, 4654ab55a0cSAnkit Kumar fdp_cfg_log_page, fdp_cfg_size, 0, 0, (nsdata->endgid << 16), 466c976353bSAnkit Kumar 0, cmd_completion, NULL) == 0) { 467c976353bSAnkit Kumar g_outstanding_commands++; 468c976353bSAnkit Kumar } else { 469c976353bSAnkit Kumar fprintf(stderr, "spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP config) failed\n\n"); 4704ab55a0cSAnkit Kumar free(fdp_cfg_log_page); 471c976353bSAnkit Kumar return -1; 472c976353bSAnkit Kumar } 473c976353bSAnkit Kumar 474c976353bSAnkit Kumar while (g_outstanding_commands) { 475c976353bSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 476c976353bSAnkit Kumar } 477c976353bSAnkit Kumar 478c976353bSAnkit Kumar if (g_fdp_command_result) { 479c976353bSAnkit Kumar fprintf(stderr, "Failed to get FDP configuration log page\n\n"); 4804ab55a0cSAnkit Kumar free(fdp_cfg_log_page); 4814ab55a0cSAnkit Kumar return -1; 4824ab55a0cSAnkit Kumar } 4834ab55a0cSAnkit Kumar 4844ab55a0cSAnkit Kumar fdp_cfg_size = fdp_cfg_log_page->size; 4854ab55a0cSAnkit Kumar fdp_cfg_log_page = realloc(fdp_cfg_log_page, fdp_cfg_size); 4864ab55a0cSAnkit Kumar if (!fdp_cfg_log_page) { 4874ab55a0cSAnkit Kumar fprintf(stderr, "FDP config log page reallocation failed!\n\n"); 4884ab55a0cSAnkit Kumar return -1; 4894ab55a0cSAnkit Kumar } 4904ab55a0cSAnkit Kumar 4914ab55a0cSAnkit Kumar if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_CONFIGURATIONS, 0, 4924ab55a0cSAnkit Kumar fdp_cfg_log_page, fdp_cfg_size, 0, 0, (nsdata->endgid << 16), 4934ab55a0cSAnkit Kumar 0, cmd_completion, NULL) == 0) { 4944ab55a0cSAnkit Kumar g_outstanding_commands++; 4954ab55a0cSAnkit Kumar } else { 4964ab55a0cSAnkit Kumar fprintf(stderr, "spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP config) failed\n\n"); 4974ab55a0cSAnkit Kumar free(fdp_cfg_log_page); 4984ab55a0cSAnkit Kumar return -1; 4994ab55a0cSAnkit Kumar } 5004ab55a0cSAnkit Kumar 5014ab55a0cSAnkit Kumar while (g_outstanding_commands) { 5024ab55a0cSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 5034ab55a0cSAnkit Kumar } 5044ab55a0cSAnkit Kumar 5054ab55a0cSAnkit Kumar if (g_fdp_command_result) { 5064ab55a0cSAnkit Kumar fprintf(stderr, "Failed to get FDP configuration log page\n\n"); 5074ab55a0cSAnkit Kumar free(fdp_cfg_log_page); 508c976353bSAnkit Kumar return -1; 509c976353bSAnkit Kumar } 510c976353bSAnkit Kumar 511c976353bSAnkit Kumar fprintf(stdout, "FDP configurations log page\n"); 512c976353bSAnkit Kumar fprintf(stdout, "===========================\n"); 513c976353bSAnkit Kumar 5144ab55a0cSAnkit Kumar fprintf(stdout, "Number of FDP configurations: %u\n", fdp_cfg_log_page->ncfg + 1); 5154ab55a0cSAnkit Kumar fprintf(stdout, "Version: %u\n", fdp_cfg_log_page->version); 5164ab55a0cSAnkit Kumar fprintf(stdout, "Size: %u\n", fdp_cfg_log_page->size); 517c976353bSAnkit Kumar 5184ab55a0cSAnkit Kumar log = fdp_cfg_log_page->cfg_desc; 5194ab55a0cSAnkit Kumar for (i = 0; i <= fdp_cfg_log_page->ncfg; i++) { 520c976353bSAnkit Kumar cfg_desc = log; 521c976353bSAnkit Kumar fprintf(stdout, "FDP Configuration Descriptor: %u\n", i); 522c976353bSAnkit Kumar fprintf(stdout, " Descriptor Size: %u\n", cfg_desc->ds); 523c976353bSAnkit Kumar fprintf(stdout, " Reclaim Group Identifier format: %u\n", 524c976353bSAnkit Kumar cfg_desc->fdpa.bits.rgif); 525c976353bSAnkit Kumar fprintf(stdout, " FDP Volatile Write Cache: %s\n", 526c976353bSAnkit Kumar cfg_desc->fdpa.bits.fdpvwc ? "Present" : "Not Present"); 527c976353bSAnkit Kumar fprintf(stdout, " FDP Configuration: %s\n", 528c976353bSAnkit Kumar cfg_desc->fdpa.bits.fdpcv ? "Valid" : "Invalid"); 529c976353bSAnkit Kumar fprintf(stdout, " Vendor Specific Size: %u\n", cfg_desc->vss); 530c976353bSAnkit Kumar fprintf(stdout, " Number of Reclaim Groups: %u\n", cfg_desc->nrg); 531c976353bSAnkit Kumar fprintf(stdout, " Number of Recalim Unit Handles: %u\n", cfg_desc->nruh); 532c976353bSAnkit Kumar fprintf(stdout, " Max Placement Identifiers: %u\n", cfg_desc->maxpids + 1); 533c976353bSAnkit Kumar fprintf(stdout, " Number of Namespaces Suppprted: %u\n", cfg_desc->nns); 534c976353bSAnkit Kumar fprintf(stdout, " Reclaim unit Nominal Size: %" PRIx64 " bytes\n", cfg_desc->runs); 535c976353bSAnkit Kumar fprintf(stdout, " Estimated Reclaim Unit Time Limit: "); 536c976353bSAnkit Kumar if (cfg_desc->erutl) { 537c976353bSAnkit Kumar fprintf(stdout, "%u seconds\n", cfg_desc->erutl); 538c976353bSAnkit Kumar } else { 539c976353bSAnkit Kumar fprintf(stdout, "Not Reported\n"); 540c976353bSAnkit Kumar } 541c976353bSAnkit Kumar for (j = 0; j < cfg_desc->nruh; j++) { 542c976353bSAnkit Kumar fprintf(stdout, " RUH Desc #%03d: RUH Type: %s\n", j, 543c976353bSAnkit Kumar cfg_desc->ruh_desc[j].ruht == SPDK_NVME_FDP_RUHT_INITIALLY_ISOLATED ? "Initially Isolated" : 544c976353bSAnkit Kumar cfg_desc->ruh_desc[j].ruht == SPDK_NVME_FDP_RUHT_PERSISTENTLY_ISOLATED ? "Persistently Isolated" : 545c976353bSAnkit Kumar "Reserved"); 546c976353bSAnkit Kumar } 547c976353bSAnkit Kumar if (i == fdpci) { 548c976353bSAnkit Kumar rgif = cfg_desc->fdpa.bits.rgif; 549c976353bSAnkit Kumar } 550c976353bSAnkit Kumar log += cfg_desc->ds; 551c976353bSAnkit Kumar } 552c976353bSAnkit Kumar 553c976353bSAnkit Kumar fprintf(stdout, "\n"); 5544ab55a0cSAnkit Kumar free(fdp_cfg_log_page); 5554ab55a0cSAnkit Kumar 556c976353bSAnkit Kumar return 0; 557c976353bSAnkit Kumar } 558c976353bSAnkit Kumar 559c976353bSAnkit Kumar static int 560c976353bSAnkit Kumar get_fdp_ruhu_log_page(struct spdk_nvme_ns *ns) 561c976353bSAnkit Kumar { 562c976353bSAnkit Kumar uint32_t i; 5634ab55a0cSAnkit Kumar size_t fdp_ruhu_size; 5644ab55a0cSAnkit Kumar struct spdk_nvme_fdp_ruhu_log_page *fdp_ruhu_log_page; 565c976353bSAnkit Kumar struct spdk_nvme_fdp_ruhu_descriptor *ruhu_desc; 566c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); 567c976353bSAnkit Kumar const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); 568c976353bSAnkit Kumar 569c976353bSAnkit Kumar g_outstanding_commands = 0; 570c976353bSAnkit Kumar g_fdp_command_result = -1; 571c976353bSAnkit Kumar 5724ab55a0cSAnkit Kumar fdp_ruhu_size = sizeof(struct spdk_nvme_fdp_ruhu_log_page); 5734ab55a0cSAnkit Kumar fdp_ruhu_log_page = calloc(1, fdp_ruhu_size); 5744ab55a0cSAnkit Kumar if (!fdp_ruhu_log_page) { 5754ab55a0cSAnkit Kumar fprintf(stderr, "FDP Reclaim Unit Handle usage log page allocation failed!\n\n"); 5764ab55a0cSAnkit Kumar return -1; 5774ab55a0cSAnkit Kumar } 5784ab55a0cSAnkit Kumar 5794ab55a0cSAnkit Kumar /* Fetch the FDP RUH usage log page header */ 580c976353bSAnkit Kumar if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE, 0, 5814ab55a0cSAnkit Kumar fdp_ruhu_log_page, fdp_ruhu_size, 0, 0, (nsdata->endgid << 16), 582c976353bSAnkit Kumar 0, cmd_completion, NULL) == 0) { 583c976353bSAnkit Kumar g_outstanding_commands++; 584c976353bSAnkit Kumar } else { 585c976353bSAnkit Kumar fprintf(stderr, "spdk_nvme_ctrlr_cmd_get_log_page_ext(RUH usage) failed\n\n"); 5864ab55a0cSAnkit Kumar free(fdp_ruhu_log_page); 587c976353bSAnkit Kumar return -1; 588c976353bSAnkit Kumar } 589c976353bSAnkit Kumar 590c976353bSAnkit Kumar while (g_outstanding_commands) { 591c976353bSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 592c976353bSAnkit Kumar } 593c976353bSAnkit Kumar 594c976353bSAnkit Kumar if (g_fdp_command_result) { 595c976353bSAnkit Kumar fprintf(stderr, "Failed to get Reclaim Unit Handle usage log page\n\n"); 5964ab55a0cSAnkit Kumar free(fdp_ruhu_log_page); 5974ab55a0cSAnkit Kumar return -1; 5984ab55a0cSAnkit Kumar } 5994ab55a0cSAnkit Kumar 6004ab55a0cSAnkit Kumar fdp_ruhu_size += fdp_ruhu_log_page->nruh * sizeof(struct spdk_nvme_fdp_ruhu_descriptor); 6014ab55a0cSAnkit Kumar fdp_ruhu_log_page = realloc(fdp_ruhu_log_page, fdp_ruhu_size); 6024ab55a0cSAnkit Kumar if (!fdp_ruhu_log_page) { 6034ab55a0cSAnkit Kumar fprintf(stderr, "FDP Reclaim Unit Handle usage log page reallocation failed!\n\n"); 6044ab55a0cSAnkit Kumar return -1; 6054ab55a0cSAnkit Kumar } 6064ab55a0cSAnkit Kumar 6074ab55a0cSAnkit Kumar if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE, 0, 6084ab55a0cSAnkit Kumar fdp_ruhu_log_page, fdp_ruhu_size, 0, 0, (nsdata->endgid << 16), 6094ab55a0cSAnkit Kumar 0, cmd_completion, NULL) == 0) { 6104ab55a0cSAnkit Kumar g_outstanding_commands++; 6114ab55a0cSAnkit Kumar } else { 6124ab55a0cSAnkit Kumar fprintf(stderr, "spdk_nvme_ctrlr_cmd_get_log_page_ext(RUH usage) failed\n\n"); 6134ab55a0cSAnkit Kumar free(fdp_ruhu_log_page); 6144ab55a0cSAnkit Kumar return -1; 6154ab55a0cSAnkit Kumar } 6164ab55a0cSAnkit Kumar 6174ab55a0cSAnkit Kumar while (g_outstanding_commands) { 6184ab55a0cSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 6194ab55a0cSAnkit Kumar } 6204ab55a0cSAnkit Kumar 6214ab55a0cSAnkit Kumar if (g_fdp_command_result) { 6224ab55a0cSAnkit Kumar fprintf(stderr, "Failed to get Reclaim Unit Handle usage log page\n\n"); 6234ab55a0cSAnkit Kumar free(fdp_ruhu_log_page); 624c976353bSAnkit Kumar return -1; 625c976353bSAnkit Kumar } 626c976353bSAnkit Kumar 627c976353bSAnkit Kumar fprintf(stdout, "FDP reclaim unit handle usage log page\n"); 628c976353bSAnkit Kumar fprintf(stdout, "======================================\n"); 629c976353bSAnkit Kumar 6304ab55a0cSAnkit Kumar fprintf(stdout, "Number of Reclaim Unit Handles: %u\n", fdp_ruhu_log_page->nruh); 631c976353bSAnkit Kumar 6324ab55a0cSAnkit Kumar for (i = 0; i < fdp_ruhu_log_page->nruh; i++) { 6334ab55a0cSAnkit Kumar ruhu_desc = &fdp_ruhu_log_page->ruhu_desc[i]; 634c976353bSAnkit Kumar 635c976353bSAnkit Kumar fprintf(stdout, " RUH Usage Desc #%03d: RUH Attributes: %s\n", i, 636c976353bSAnkit Kumar ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_UNUSED ? "Unused" : 637c976353bSAnkit Kumar ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_HOST_SPECIFIED ? "Host Specified" : 638c976353bSAnkit Kumar ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_CTRLR_SPECIFIED ? "Controller Specified" : 639c976353bSAnkit Kumar "Reserved"); 640c976353bSAnkit Kumar } 641c976353bSAnkit Kumar 642c976353bSAnkit Kumar fprintf(stdout, "\n"); 6434ab55a0cSAnkit Kumar free(fdp_ruhu_log_page); 6444ab55a0cSAnkit Kumar 645c976353bSAnkit Kumar return 0; 646c976353bSAnkit Kumar } 647c976353bSAnkit Kumar 648c976353bSAnkit Kumar static int 649c976353bSAnkit Kumar get_fdp_stats_log_page(struct spdk_nvme_ns *ns) 650c976353bSAnkit Kumar { 6514ab55a0cSAnkit Kumar struct spdk_nvme_fdp_stats_log_page fdp_stats_log_page; 652c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); 653c976353bSAnkit Kumar const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); 654c976353bSAnkit Kumar 655c976353bSAnkit Kumar g_outstanding_commands = 0; 656c976353bSAnkit Kumar g_fdp_command_result = -1; 657c976353bSAnkit Kumar 658c976353bSAnkit Kumar if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_STATISTICS, 0, 6594ab55a0cSAnkit Kumar &fdp_stats_log_page, 64, 0, 0, (nsdata->endgid << 16), 0, 660c976353bSAnkit Kumar cmd_completion, NULL) == 0) { 661c976353bSAnkit Kumar g_outstanding_commands++; 662c976353bSAnkit Kumar } else { 663c976353bSAnkit Kumar fprintf(stderr, "spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP stats) failed\n\n"); 664c976353bSAnkit Kumar return -1; 665c976353bSAnkit Kumar } 666c976353bSAnkit Kumar 667c976353bSAnkit Kumar while (g_outstanding_commands) { 668c976353bSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 669c976353bSAnkit Kumar } 670c976353bSAnkit Kumar 671c976353bSAnkit Kumar if (g_fdp_command_result) { 672c976353bSAnkit Kumar fprintf(stderr, "Failed to get FDP statistics log page\n\n"); 673c976353bSAnkit Kumar return -1; 674c976353bSAnkit Kumar } 675c976353bSAnkit Kumar 676c976353bSAnkit Kumar fprintf(stdout, "FDP statistics log page\n"); 677c976353bSAnkit Kumar fprintf(stdout, "=======================\n"); 678c976353bSAnkit Kumar 679c976353bSAnkit Kumar fprintf(stdout, "Host bytes with metadata written: "); 6804ab55a0cSAnkit Kumar print_uint128_dec(fdp_stats_log_page.hbmw); 681c976353bSAnkit Kumar fprintf(stdout, "\n"); 682c976353bSAnkit Kumar fprintf(stdout, "Media bytes with metadata written: "); 6834ab55a0cSAnkit Kumar print_uint128_dec(fdp_stats_log_page.mbmw); 684c976353bSAnkit Kumar fprintf(stdout, "\n"); 685c976353bSAnkit Kumar fprintf(stdout, "Media bytes erased: "); 6864ab55a0cSAnkit Kumar print_uint128_dec(fdp_stats_log_page.mbe); 687c976353bSAnkit Kumar fprintf(stdout, "\n\n"); 688c976353bSAnkit Kumar 689c976353bSAnkit Kumar return 0; 690c976353bSAnkit Kumar } 691c976353bSAnkit Kumar 692c976353bSAnkit Kumar static int 693c976353bSAnkit Kumar get_fdp_events_log_page(struct spdk_nvme_ns *ns) 694c976353bSAnkit Kumar { 695c976353bSAnkit Kumar uint32_t i; 6964ab55a0cSAnkit Kumar size_t fdp_event_size; 6974ab55a0cSAnkit Kumar struct spdk_nvme_fdp_events_log_page *fdp_events_log_page; 698c976353bSAnkit Kumar struct spdk_nvme_fdp_event *event; 699c976353bSAnkit Kumar struct spdk_nvme_fdp_event_media_reallocated *media_reallocated; 700c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); 701c976353bSAnkit Kumar const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); 702c976353bSAnkit Kumar 703c976353bSAnkit Kumar g_outstanding_commands = 0; 704c976353bSAnkit Kumar g_fdp_command_result = -1; 705c976353bSAnkit Kumar 7064ab55a0cSAnkit Kumar fdp_event_size = sizeof(struct spdk_nvme_fdp_events_log_page); 7074ab55a0cSAnkit Kumar fdp_events_log_page = calloc(1, fdp_event_size); 7084ab55a0cSAnkit Kumar if (!fdp_events_log_page) { 7094ab55a0cSAnkit Kumar fprintf(stderr, "FDP events log page allocation failed!\n\n"); 7104ab55a0cSAnkit Kumar return -1; 7114ab55a0cSAnkit Kumar } 7124ab55a0cSAnkit Kumar 7134ab55a0cSAnkit Kumar /* Fetch the FDP events log page header */ 714c976353bSAnkit Kumar if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_EVENTS, 0, 7154ab55a0cSAnkit Kumar fdp_events_log_page, fdp_event_size, 0, 716c976353bSAnkit Kumar (SPDK_NVME_FDP_REPORT_HOST_EVENTS << 8), (nsdata->endgid << 16), 717c976353bSAnkit Kumar 0, cmd_completion, NULL) == 0) { 718c976353bSAnkit Kumar g_outstanding_commands++; 719c976353bSAnkit Kumar } else { 720c976353bSAnkit Kumar fprintf(stderr, "spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP events) failed\n\n"); 7214ab55a0cSAnkit Kumar free(fdp_events_log_page); 722c976353bSAnkit Kumar return -1; 723c976353bSAnkit Kumar } 724c976353bSAnkit Kumar 725c976353bSAnkit Kumar while (g_outstanding_commands) { 726c976353bSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 727c976353bSAnkit Kumar } 728c976353bSAnkit Kumar 729c976353bSAnkit Kumar if (g_fdp_command_result) { 730c976353bSAnkit Kumar fprintf(stderr, "Failed to get eventss log page\n\n"); 7314ab55a0cSAnkit Kumar free(fdp_events_log_page); 7324ab55a0cSAnkit Kumar return -1; 7334ab55a0cSAnkit Kumar } 7344ab55a0cSAnkit Kumar 7354ab55a0cSAnkit Kumar fdp_event_size += fdp_events_log_page->nevents * sizeof(struct spdk_nvme_fdp_event); 7364ab55a0cSAnkit Kumar fdp_events_log_page = realloc(fdp_events_log_page, fdp_event_size); 7374ab55a0cSAnkit Kumar if (!fdp_events_log_page) { 7384ab55a0cSAnkit Kumar fprintf(stderr, "FDP events log page reallocation failed!\n\n"); 7394ab55a0cSAnkit Kumar return -1; 7404ab55a0cSAnkit Kumar } 7414ab55a0cSAnkit Kumar 7424ab55a0cSAnkit Kumar /* Only fetch FDP host events here */ 7434ab55a0cSAnkit Kumar if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_EVENTS, 0, 7444ab55a0cSAnkit Kumar fdp_events_log_page, fdp_event_size, 0, 7454ab55a0cSAnkit Kumar (SPDK_NVME_FDP_REPORT_HOST_EVENTS << 8), (nsdata->endgid << 16), 7464ab55a0cSAnkit Kumar 0, cmd_completion, NULL) == 0) { 7474ab55a0cSAnkit Kumar g_outstanding_commands++; 7484ab55a0cSAnkit Kumar } else { 7494ab55a0cSAnkit Kumar fprintf(stderr, "spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP events) failed\n\n"); 7504ab55a0cSAnkit Kumar free(fdp_events_log_page); 7514ab55a0cSAnkit Kumar return -1; 7524ab55a0cSAnkit Kumar } 7534ab55a0cSAnkit Kumar 7544ab55a0cSAnkit Kumar while (g_outstanding_commands) { 7554ab55a0cSAnkit Kumar spdk_nvme_ctrlr_process_admin_completions(ctrlr); 7564ab55a0cSAnkit Kumar } 7574ab55a0cSAnkit Kumar 7584ab55a0cSAnkit Kumar if (g_fdp_command_result) { 7594ab55a0cSAnkit Kumar fprintf(stderr, "Failed to get eventss log page\n\n"); 7604ab55a0cSAnkit Kumar free(fdp_events_log_page); 761c976353bSAnkit Kumar return -1; 762c976353bSAnkit Kumar } 763c976353bSAnkit Kumar 764c976353bSAnkit Kumar fprintf(stdout, "FDP events log page\n"); 765c976353bSAnkit Kumar fprintf(stdout, "===================\n"); 7664ab55a0cSAnkit Kumar fprintf(stdout, "Number of FDP events: %u\n", fdp_events_log_page->nevents); 767c976353bSAnkit Kumar 7684ab55a0cSAnkit Kumar for (i = 0; i < fdp_events_log_page->nevents; i++) { 7694ab55a0cSAnkit Kumar event = &fdp_events_log_page->event[i]; 770c976353bSAnkit Kumar 771c976353bSAnkit Kumar fprintf(stdout, "FDP Event #%u:\n", i); 772c976353bSAnkit Kumar fprintf(stdout, " Event Type: %s\n", 773c976353bSAnkit Kumar event->etype == SPDK_NVME_FDP_EVENT_RU_NOT_WRITTEN_CAPACITY ? "RU Not Written to Capacity" : 774c976353bSAnkit Kumar event->etype == SPDK_NVME_FDP_EVENT_RU_TIME_LIMIT_EXCEEDED ? "RU Time Limit Exceeded" : 775c976353bSAnkit Kumar event->etype == SPDK_NVME_FDP_EVENT_CTRLR_RESET_MODIFY_RUH ? "Ctrlr Reset Modified RUH's" : 776c976353bSAnkit Kumar event->etype == SPDK_NVME_FDP_EVENT_INVALID_PLACEMENT_ID ? "Invalid Placement Identifier" : 777c976353bSAnkit Kumar event->etype == SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED ? "Media Reallocated" : 778c976353bSAnkit Kumar event->etype == SPDK_NVME_FDP_EVENT_IMPLICIT_MODIFIED_RUH ? "Implicitly modified RUH" : 779c976353bSAnkit Kumar "Reserved"); 780c976353bSAnkit Kumar fprintf(stdout, " Placement Identifier: %s\n", 781c976353bSAnkit Kumar event->fdpef.bits.piv ? "Valid" : "Invalid"); 782c976353bSAnkit Kumar fprintf(stdout, " NSID: %s\n", 783c976353bSAnkit Kumar event->fdpef.bits.nsidv ? "Valid" : "Invalid"); 784c976353bSAnkit Kumar fprintf(stdout, " Location: %s\n", 785c976353bSAnkit Kumar event->fdpef.bits.lv ? "Valid" : "Invalid"); 786c976353bSAnkit Kumar if (event->fdpef.bits.piv) { 787c976353bSAnkit Kumar fprintf(stdout, " Placement Identifier: %u\n", event->pid); 788c976353bSAnkit Kumar } else { 789c976353bSAnkit Kumar fprintf(stdout, " Placement Identifier: Reserved\n"); 790c976353bSAnkit Kumar } 791c976353bSAnkit Kumar fprintf(stdout, " Event Timestamp: %" PRIx64 "\n", event->timestamp); 792c976353bSAnkit Kumar if (event->fdpef.bits.nsidv) { 793c976353bSAnkit Kumar fprintf(stdout, " Namespace Identifier: %u\n", event->nsid); 794c976353bSAnkit Kumar } else { 795c976353bSAnkit Kumar fprintf(stdout, " Namespace Identifier: Ignore\n"); 796c976353bSAnkit Kumar } 797c976353bSAnkit Kumar 798c976353bSAnkit Kumar if (event->etype == SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED) { 799c976353bSAnkit Kumar media_reallocated = (struct spdk_nvme_fdp_event_media_reallocated *)&event->event_type_specific; 800c976353bSAnkit Kumar 801c976353bSAnkit Kumar fprintf(stdout, " LBA: %s\n", 802c976353bSAnkit Kumar media_reallocated->sef.bits.lbav ? "Valid" : "Invalid"); 803c976353bSAnkit Kumar fprintf(stdout, " Number of LBA's Moved: %u\n", media_reallocated->nlbam); 804c976353bSAnkit Kumar if (media_reallocated->sef.bits.lbav) { 805c976353bSAnkit Kumar fprintf(stdout, " Logical Block Address: %u\n", event->nsid); 806c976353bSAnkit Kumar } else { 807c976353bSAnkit Kumar fprintf(stdout, " Logical Block Address: Ignore\n"); 808c976353bSAnkit Kumar } 809c976353bSAnkit Kumar } 810c976353bSAnkit Kumar 811c976353bSAnkit Kumar if (event->fdpef.bits.lv) { 812c976353bSAnkit Kumar fprintf(stdout, " Reclaim Group Identifier: %u\n", event->rgid); 813c976353bSAnkit Kumar } else { 814c976353bSAnkit Kumar fprintf(stdout, " Reclaim Group Identifier: Ignore\n"); 815c976353bSAnkit Kumar } 816c976353bSAnkit Kumar if (event->fdpef.bits.lv) { 817c976353bSAnkit Kumar fprintf(stdout, " Reclaim Unit Handle Identifier: %u\n", event->ruhid); 818c976353bSAnkit Kumar } else { 819c976353bSAnkit Kumar fprintf(stdout, " Reclaim Unit Handle Identifier: Ignore\n"); 820c976353bSAnkit Kumar } 821c976353bSAnkit Kumar } 822c976353bSAnkit Kumar 823c976353bSAnkit Kumar fprintf(stdout, "\n"); 8244ab55a0cSAnkit Kumar free(fdp_events_log_page); 8254ab55a0cSAnkit Kumar 826c976353bSAnkit Kumar return 0; 827c976353bSAnkit Kumar } 828c976353bSAnkit Kumar 829c976353bSAnkit Kumar static int 830c976353bSAnkit Kumar fdp_tests(struct spdk_nvme_ns *ns) 831c976353bSAnkit Kumar { 832c976353bSAnkit Kumar struct spdk_nvme_qpair *qpair; 833c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); 834c976353bSAnkit Kumar int ret, err; 835c976353bSAnkit Kumar 836c976353bSAnkit Kumar qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, NULL, 0); 837c976353bSAnkit Kumar if (!qpair) { 838c976353bSAnkit Kumar fprintf(stderr, "spdk_nvme_ctrlr_alloc_io_qpair() failed\n"); 839c976353bSAnkit Kumar return -EIO; 840c976353bSAnkit Kumar } 841c976353bSAnkit Kumar 842c976353bSAnkit Kumar ret = 0; 843c976353bSAnkit Kumar 844c976353bSAnkit Kumar fprintf(stdout, "==================================\n"); 845c976353bSAnkit Kumar fprintf(stdout, "== FDP tests for Namespace: #%02u ==\n", spdk_nvme_ns_get_id(ns)); 846c976353bSAnkit Kumar fprintf(stdout, "==================================\n\n"); 847c976353bSAnkit Kumar err = get_fdp(ns); 848c976353bSAnkit Kumar if (err) { 849c976353bSAnkit Kumar spdk_nvme_ctrlr_free_io_qpair(qpair); 850c976353bSAnkit Kumar return err; 851c976353bSAnkit Kumar } 852c976353bSAnkit Kumar 853c976353bSAnkit Kumar if (!fdp_res.bits.fdpe) { 854c976353bSAnkit Kumar fprintf(stdout, "FDP support disabled\n"); 855c976353bSAnkit Kumar spdk_nvme_ctrlr_free_io_qpair(qpair); 856c976353bSAnkit Kumar return 0; 857c976353bSAnkit Kumar } 858c976353bSAnkit Kumar 859c976353bSAnkit Kumar fdpci = fdp_res.bits.fdpci; 860c976353bSAnkit Kumar err = get_fdp_cfg_log_page(ns); 861c976353bSAnkit Kumar if (err) { 862c976353bSAnkit Kumar spdk_nvme_ctrlr_free_io_qpair(qpair); 863c976353bSAnkit Kumar return err; 864c976353bSAnkit Kumar } 865c976353bSAnkit Kumar 866c976353bSAnkit Kumar ret += get_fdp_ruhu_log_page(ns); 867c976353bSAnkit Kumar ret += get_fdp_stats_log_page(ns); 868c976353bSAnkit Kumar 869c976353bSAnkit Kumar err = reclaim_unit_handle_status(ns, qpair); 870c976353bSAnkit Kumar if (err) { 871c976353bSAnkit Kumar spdk_nvme_ctrlr_free_io_qpair(qpair); 872c976353bSAnkit Kumar return err; 873c976353bSAnkit Kumar } 874c976353bSAnkit Kumar 875c976353bSAnkit Kumar err = check_fdp_write(ns, qpair); 876c976353bSAnkit Kumar if (err) { 877c976353bSAnkit Kumar spdk_nvme_ctrlr_free_io_qpair(qpair); 878c976353bSAnkit Kumar return err; 879c976353bSAnkit Kumar } 880c976353bSAnkit Kumar 881c976353bSAnkit Kumar ret += set_fdp_events(ns); 882c976353bSAnkit Kumar ret += reclaim_unit_handle_update(ns, qpair); 883c976353bSAnkit Kumar 884c976353bSAnkit Kumar ret += get_fdp_events(ns); 885c976353bSAnkit Kumar ret += get_fdp_events_log_page(ns); 886c976353bSAnkit Kumar 887c976353bSAnkit Kumar return ret; 888c976353bSAnkit Kumar } 889c976353bSAnkit Kumar 890c976353bSAnkit Kumar static void 891c976353bSAnkit Kumar register_ns(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns) 892c976353bSAnkit Kumar { 893c976353bSAnkit Kumar struct ns_entry *entry; 894c976353bSAnkit Kumar const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); 895c976353bSAnkit Kumar 896c976353bSAnkit Kumar entry = malloc(sizeof(struct ns_entry)); 897c976353bSAnkit Kumar if (entry == NULL) { 898c976353bSAnkit Kumar perror("ns_entry malloc"); 899c976353bSAnkit Kumar exit(1); 900c976353bSAnkit Kumar } 901c976353bSAnkit Kumar 902c976353bSAnkit Kumar entry->ctrlr = ctrlr; 903c976353bSAnkit Kumar entry->ns = ns; 904c976353bSAnkit Kumar entry->next = g_namespaces; 905c976353bSAnkit Kumar g_namespaces = entry; 906c976353bSAnkit Kumar 907c976353bSAnkit Kumar printf("Namespace ID: %d Endurance Group ID: %d\n", spdk_nvme_ns_get_id(ns), 908c976353bSAnkit Kumar nsdata->endgid); 909c976353bSAnkit Kumar } 910c976353bSAnkit Kumar 911c976353bSAnkit Kumar static bool 912c976353bSAnkit Kumar probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 913c976353bSAnkit Kumar struct spdk_nvme_ctrlr_opts *opts) 914c976353bSAnkit Kumar { 915c976353bSAnkit Kumar fprintf(stdout, "Attaching to %s\n", trid->traddr); 916c976353bSAnkit Kumar 917c976353bSAnkit Kumar return true; 918c976353bSAnkit Kumar } 919c976353bSAnkit Kumar 920c976353bSAnkit Kumar static void 921c976353bSAnkit Kumar attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 922c976353bSAnkit Kumar struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts) 923c976353bSAnkit Kumar { 924c976353bSAnkit Kumar int num_ns, nsid; 925c976353bSAnkit Kumar struct spdk_nvme_ns *ns; 926c976353bSAnkit Kumar const struct spdk_nvme_ctrlr_data *cdata; 927c976353bSAnkit Kumar 928c976353bSAnkit Kumar cdata = spdk_nvme_ctrlr_get_data(ctrlr); 929c976353bSAnkit Kumar 930b4d406b7SAnkit Kumar if (cdata->ctratt.bits.fdps) { 931c976353bSAnkit Kumar fprintf(stdout, "Controller supports FDP Attached to %s\n", trid->traddr); 932c976353bSAnkit Kumar num_ns = spdk_nvme_ctrlr_get_num_ns(ctrlr); 933c976353bSAnkit Kumar if (num_ns < 1) { 934c976353bSAnkit Kumar printf("No valid namespaces in controller\n"); 935c976353bSAnkit Kumar } else { 936c976353bSAnkit Kumar for (nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); nsid != 0; 937c976353bSAnkit Kumar nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, nsid)) { 938c976353bSAnkit Kumar ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); 939c976353bSAnkit Kumar register_ns(ctrlr, ns); 940c976353bSAnkit Kumar } 941c976353bSAnkit Kumar } 942c976353bSAnkit Kumar } else { 943c976353bSAnkit Kumar fprintf(stdout, "Controller attached to: %s doesn't support FDP\n", trid->traddr); 944c976353bSAnkit Kumar } 945c976353bSAnkit Kumar } 946c976353bSAnkit Kumar 947c976353bSAnkit Kumar static void 948c976353bSAnkit Kumar cleanup(void) 949c976353bSAnkit Kumar { 950c976353bSAnkit Kumar struct ns_entry *ns_entry = g_namespaces; 951c976353bSAnkit Kumar struct spdk_nvme_detach_ctx *detach_ctx = NULL; 952c976353bSAnkit Kumar 953c976353bSAnkit Kumar while (ns_entry) { 954c976353bSAnkit Kumar struct ns_entry *next = ns_entry->next; 955c976353bSAnkit Kumar 956c976353bSAnkit Kumar spdk_nvme_detach_async(ns_entry->ctrlr, &detach_ctx); 957c976353bSAnkit Kumar 958c976353bSAnkit Kumar free(ns_entry); 959c976353bSAnkit Kumar ns_entry = next; 960c976353bSAnkit Kumar } 961c976353bSAnkit Kumar 962c976353bSAnkit Kumar if (detach_ctx) { 963c976353bSAnkit Kumar spdk_nvme_detach_poll(detach_ctx); 964c976353bSAnkit Kumar } 965c976353bSAnkit Kumar } 966c976353bSAnkit Kumar 967c976353bSAnkit Kumar static void 968c976353bSAnkit Kumar usage(const char *program_name) 969c976353bSAnkit Kumar { 970c976353bSAnkit Kumar printf("%s [options]", program_name); 971c976353bSAnkit Kumar printf("\n"); 972c976353bSAnkit Kumar printf("options:\n"); 973c976353bSAnkit Kumar printf(" -r trid remote NVMe over Fabrics target address\n"); 974c976353bSAnkit Kumar printf(" Format: 'key:value [key:value] ...'\n"); 975c976353bSAnkit Kumar printf(" Keys:\n"); 976c976353bSAnkit Kumar printf(" trtype Transport type (e.g. RDMA)\n"); 977c976353bSAnkit Kumar printf(" adrfam Address family (e.g. IPv4, IPv6)\n"); 978c976353bSAnkit Kumar printf(" traddr Transport address (e.g. 192.168.100.8)\n"); 979c976353bSAnkit Kumar printf(" trsvcid Transport service identifier (e.g. 4420)\n"); 980c976353bSAnkit Kumar printf(" subnqn Subsystem NQN (default: %s)\n", SPDK_NVMF_DISCOVERY_NQN); 981c976353bSAnkit Kumar printf(" Example: -r 'trtype:RDMA adrfam:IPv4 traddr:192.168.100.8 trsvcid:4420'\n"); 982c976353bSAnkit Kumar printf(" -h show this usage\n"); 983c976353bSAnkit Kumar } 984c976353bSAnkit Kumar 985c976353bSAnkit Kumar static int 986c976353bSAnkit Kumar parse_args(int argc, char **argv, struct spdk_env_opts *env_opts) 987c976353bSAnkit Kumar { 988c976353bSAnkit Kumar int op; 989c976353bSAnkit Kumar 990c976353bSAnkit Kumar spdk_nvme_trid_populate_transport(&g_trid, SPDK_NVME_TRANSPORT_PCIE); 991c976353bSAnkit Kumar snprintf(g_trid.subnqn, sizeof(g_trid.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN); 992c976353bSAnkit Kumar 993c976353bSAnkit Kumar while ((op = getopt(argc, argv, "r:h")) != -1) { 994c976353bSAnkit Kumar switch (op) { 995c976353bSAnkit Kumar case 'r': 996c976353bSAnkit Kumar if (spdk_nvme_transport_id_parse(&g_trid, optarg) != 0) { 997c976353bSAnkit Kumar fprintf(stderr, "Error parsing transport address\n"); 998c976353bSAnkit Kumar return 1; 999c976353bSAnkit Kumar } 1000c976353bSAnkit Kumar 1001c976353bSAnkit Kumar g_use_trid = true; 1002c976353bSAnkit Kumar break; 1003c976353bSAnkit Kumar case 'h': 1004c976353bSAnkit Kumar usage(argv[0]); 1005c976353bSAnkit Kumar exit(EXIT_SUCCESS); 1006c976353bSAnkit Kumar default: 1007c976353bSAnkit Kumar usage(argv[0]); 1008c976353bSAnkit Kumar return 1; 1009c976353bSAnkit Kumar } 1010c976353bSAnkit Kumar } 1011c976353bSAnkit Kumar 1012c976353bSAnkit Kumar return 0; 1013c976353bSAnkit Kumar } 1014c976353bSAnkit Kumar 1015c976353bSAnkit Kumar int 1016c976353bSAnkit Kumar main(int argc, char **argv) 1017c976353bSAnkit Kumar { 1018c976353bSAnkit Kumar int rc; 1019c976353bSAnkit Kumar struct spdk_env_opts opts; 1020c976353bSAnkit Kumar struct ns_entry *ns_entry; 1021c976353bSAnkit Kumar 1022*57fd99b9SJim Harris opts.opts_size = sizeof(opts); 1023c976353bSAnkit Kumar spdk_env_opts_init(&opts); 1024c976353bSAnkit Kumar rc = parse_args(argc, argv, &opts); 1025c976353bSAnkit Kumar if (rc != 0) { 1026c976353bSAnkit Kumar return rc; 1027c976353bSAnkit Kumar } 1028c976353bSAnkit Kumar 1029c976353bSAnkit Kumar opts.name = "fdp"; 1030c976353bSAnkit Kumar opts.core_mask = "0x1"; 1031c976353bSAnkit Kumar opts.shm_id = 0; 1032c976353bSAnkit Kumar if (spdk_env_init(&opts) < 0) { 1033c976353bSAnkit Kumar fprintf(stderr, "Unable to initialize SPDK env\n"); 1034c976353bSAnkit Kumar return 1; 1035c976353bSAnkit Kumar } 1036c976353bSAnkit Kumar 1037c976353bSAnkit Kumar printf("Initializing NVMe Controllers\n"); 1038c976353bSAnkit Kumar 1039c976353bSAnkit Kumar rc = spdk_nvme_probe(g_use_trid ? &g_trid : NULL, NULL, probe_cb, attach_cb, NULL); 1040c976353bSAnkit Kumar if (rc != 0) { 1041c976353bSAnkit Kumar fprintf(stderr, "spdk_nvme_probe() failed\n"); 1042c976353bSAnkit Kumar return 1; 1043c976353bSAnkit Kumar } 1044c976353bSAnkit Kumar 1045c976353bSAnkit Kumar if (g_namespaces == NULL) { 1046c976353bSAnkit Kumar fprintf(stderr, "no NVMe controllers found\n"); 1047c976353bSAnkit Kumar return 1; 1048c976353bSAnkit Kumar } 1049c976353bSAnkit Kumar 1050c976353bSAnkit Kumar printf("Initialization complete.\n\n"); 1051c976353bSAnkit Kumar 1052c976353bSAnkit Kumar ns_entry = g_namespaces; 1053c976353bSAnkit Kumar while (ns_entry != NULL) { 1054c976353bSAnkit Kumar rc = fdp_tests(ns_entry->ns); 1055c976353bSAnkit Kumar if (rc) { 1056c976353bSAnkit Kumar break; 1057c976353bSAnkit Kumar } 1058c976353bSAnkit Kumar ns_entry = ns_entry->next; 1059c976353bSAnkit Kumar } 1060c976353bSAnkit Kumar 1061c976353bSAnkit Kumar printf("FDP test %s\n", rc ? "failed" : "passed"); 1062c976353bSAnkit Kumar cleanup(); 1063c976353bSAnkit Kumar 1064c976353bSAnkit Kumar return 0; 1065c976353bSAnkit Kumar } 1066