xref: /spdk/lib/ftl/ftl_rq.c (revision 307b8c112ffd90a26d53dd15fad67bd9038ef526)
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