1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/ftl.h" 7 #include "spdk/env.h" 8 9 #include "ftl_io.h" 10 #include "ftl_core.h" 11 12 struct ftl_rq * 13 ftl_rq_new(struct spdk_ftl_dev *dev, uint32_t io_md_size) 14 { 15 struct ftl_rq *rq; 16 struct ftl_rq_entry *entry; 17 struct iovec *io_vec; 18 void *io_payload, *io_md = NULL; 19 uint64_t i; 20 size_t size; 21 uint32_t num_blocks = dev->xfer_size; 22 23 size = sizeof(*rq) + (sizeof(rq->entries[0]) * num_blocks); 24 rq = calloc(1, size); 25 if (!rq) { 26 return NULL; 27 } 28 rq->dev = dev; 29 rq->num_blocks = num_blocks; 30 31 /* Allocate payload for IO and IO vector */ 32 io_payload = rq->io_payload = spdk_zmalloc(FTL_BLOCK_SIZE * num_blocks, 33 FTL_BLOCK_SIZE, NULL, SPDK_ENV_LCORE_ID_ANY, 34 SPDK_MALLOC_DMA); 35 if (!io_payload) { 36 goto error; 37 } 38 rq->io_vec = calloc(num_blocks, sizeof(rq->io_vec[0])); 39 if (!rq->io_vec) { 40 goto error; 41 } 42 rq->io_vec_size = num_blocks; 43 44 /* Allocate extended metadata for IO */ 45 if (io_md_size) { 46 rq->io_md_size = io_md_size; 47 io_md = rq->io_md = spdk_zmalloc(io_md_size * num_blocks, 48 FTL_BLOCK_SIZE, NULL, 49 SPDK_ENV_LCORE_ID_ANY, 50 SPDK_MALLOC_DMA); 51 if (!io_md) { 52 goto error; 53 } 54 } 55 56 entry = rq->entries; 57 io_vec = rq->io_vec; 58 for (i = 0; i < num_blocks; ++i) { 59 uint64_t *index = (uint64_t *)&entry->index; 60 *index = i; 61 62 entry->addr = FTL_ADDR_INVALID; 63 entry->lba = FTL_LBA_INVALID; 64 entry->io_payload = io_payload; 65 entry->seq_id = 0; 66 67 if (io_md_size) { 68 entry->io_md = io_md; 69 } 70 71 io_vec->iov_base = io_payload; 72 io_vec->iov_len = FTL_BLOCK_SIZE; 73 74 entry++; 75 io_vec++; 76 io_payload += FTL_BLOCK_SIZE; 77 io_md += io_md_size; 78 } 79 80 return rq; 81 error: 82 ftl_rq_del(rq); 83 return NULL; 84 } 85 86 void 87 ftl_rq_del(struct ftl_rq *rq) 88 { 89 if (!rq) { 90 return; 91 } 92 93 spdk_free(rq->io_payload); 94 spdk_free(rq->io_md); 95 free(rq->io_vec); 96 97 free(rq); 98 } 99 100 void 101 ftl_rq_unpin(struct ftl_rq *rq) 102 { 103 struct ftl_l2p_pin_ctx *pin_ctx; 104 uint64_t i; 105 106 for (i = 0; i < rq->iter.count; i++) { 107 pin_ctx = &rq->entries[i].l2p_pin_ctx; 108 if (pin_ctx->lba != FTL_LBA_INVALID) { 109 ftl_l2p_unpin(rq->dev, pin_ctx->lba, pin_ctx->count); 110 } 111 } 112 } 113