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