1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2022 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 *
ftl_rq_new(struct spdk_ftl_dev * dev,uint32_t io_md_size)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 void *io_payload, *io_md = NULL;
18 uint64_t i;
19 size_t size;
20 uint32_t num_blocks = dev->xfer_size;
21
22 size = sizeof(*rq) + (sizeof(rq->entries[0]) * num_blocks);
23 rq = calloc(1, size);
24 if (!rq) {
25 return NULL;
26 }
27 rq->dev = dev;
28 rq->num_blocks = num_blocks;
29
30 /* Allocate payload for IO and IO vector */
31 io_payload = rq->io_payload = spdk_zmalloc(FTL_BLOCK_SIZE * num_blocks,
32 FTL_BLOCK_SIZE, NULL, SPDK_ENV_LCORE_ID_ANY,
33 SPDK_MALLOC_DMA);
34 if (!io_payload) {
35 goto error;
36 }
37
38 /* Allocate extended metadata for IO */
39 if (io_md_size) {
40 rq->io_md_size = io_md_size;
41 io_md = rq->io_md = spdk_zmalloc(io_md_size * num_blocks,
42 FTL_BLOCK_SIZE, NULL,
43 SPDK_ENV_LCORE_ID_ANY,
44 SPDK_MALLOC_DMA);
45 if (!io_md) {
46 goto error;
47 }
48 }
49
50 entry = rq->entries;
51 for (i = 0; i < num_blocks; ++i) {
52 uint64_t *index = (uint64_t *)&entry->index;
53 *index = i;
54
55 entry->addr = FTL_ADDR_INVALID;
56 entry->lba = FTL_LBA_INVALID;
57 entry->io_payload = io_payload;
58 entry->seq_id = 0;
59
60 if (io_md_size) {
61 entry->io_md = io_md;
62 }
63
64 entry++;
65 io_payload += FTL_BLOCK_SIZE;
66 io_md += io_md_size;
67 }
68
69 return rq;
70 error:
71 ftl_rq_del(rq);
72 return NULL;
73 }
74
75 void
ftl_rq_del(struct ftl_rq * rq)76 ftl_rq_del(struct ftl_rq *rq)
77 {
78 if (!rq) {
79 return;
80 }
81
82 spdk_free(rq->io_payload);
83 spdk_free(rq->io_md);
84
85 free(rq);
86 }
87
88 void
ftl_rq_unpin(struct ftl_rq * rq)89 ftl_rq_unpin(struct ftl_rq *rq)
90 {
91 struct ftl_l2p_pin_ctx *pin_ctx;
92 uint64_t i;
93
94 for (i = 0; i < rq->iter.count; i++) {
95 pin_ctx = &rq->entries[i].l2p_pin_ctx;
96 if (pin_ctx->lba != FTL_LBA_INVALID) {
97 ftl_l2p_unpin(rq->dev, pin_ctx->lba, pin_ctx->count);
98 }
99 }
100 }
101