xref: /spdk/lib/ftl/ftl_l2p_flat.c (revision 95d6c9fac17572b107042103439aafd696d60b0e)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2022 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "ftl_l2p.h"
7 #include "ftl_core.h"
8 #include "ftl_band.h"
9 #include "ftl_utils.h"
10 #include "ftl_l2p_flat.h"
11 #include "utils/ftl_addr_utils.h"
12 
13 static struct ftl_md *
14 get_l2p_md(struct spdk_ftl_dev *dev)
15 {
16 	return dev->layout.md[FTL_LAYOUT_REGION_TYPE_L2P];
17 }
18 
19 struct ftl_l2p_flat {
20 	void *l2p;
21 	bool is_halted;
22 };
23 
24 void
25 ftl_l2p_flat_pin(struct spdk_ftl_dev *dev, struct ftl_l2p_pin_ctx *pin_ctx)
26 {
27 	assert(dev->num_lbas >= pin_ctx->lba + pin_ctx->count);
28 
29 	ftl_l2p_pin_complete(dev, 0, pin_ctx);
30 }
31 
32 void
33 ftl_l2p_flat_unpin(struct spdk_ftl_dev *dev, uint64_t lba, uint64_t count)
34 {
35 	assert(dev->num_lbas >= lba + count);
36 }
37 
38 void
39 ftl_l2p_flat_set(struct spdk_ftl_dev *dev, uint64_t lba, ftl_addr addr)
40 {
41 	struct ftl_l2p_flat *l2p_flat = dev->l2p;
42 
43 	assert(dev->num_lbas > lba);
44 
45 	ftl_addr_store(dev, l2p_flat->l2p, lba, addr);
46 }
47 
48 ftl_addr
49 ftl_l2p_flat_get(struct spdk_ftl_dev *dev, uint64_t lba)
50 {
51 	struct ftl_l2p_flat *l2p_flat = dev->l2p;
52 
53 	assert(dev->num_lbas > lba);
54 
55 	return ftl_addr_load(dev, l2p_flat->l2p, lba);
56 }
57 
58 static void
59 md_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
60 {
61 	ftl_l2p_cb cb = md->owner.private;
62 	void *cb_ctx = md->owner.cb_ctx;
63 
64 	cb(dev, status, cb_ctx);
65 }
66 
67 void
68 ftl_l2p_flat_clear(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
69 {
70 	struct ftl_l2p_flat *l2p_flat = dev->l2p;
71 	struct ftl_md *md;
72 
73 	memset(l2p_flat->l2p, (int)FTL_ADDR_INVALID,
74 	       ftl_md_get_buffer_size(get_l2p_md(dev)));
75 
76 	md = get_l2p_md(dev);
77 	md->cb = md_cb;
78 	md->owner.cb_ctx = cb_ctx;
79 	md->owner.private = cb;
80 	ftl_md_persist(md);
81 }
82 
83 void
84 ftl_l2p_flat_restore(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
85 {
86 	struct ftl_md *md;
87 
88 	md = get_l2p_md(dev);
89 	md->cb = md_cb;
90 	md->owner.cb_ctx = cb_ctx;
91 	md->owner.private = cb;
92 	ftl_md_restore(md);
93 }
94 
95 void
96 ftl_l2p_flat_persist(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
97 {
98 	struct ftl_md *md;
99 
100 	md = get_l2p_md(dev);
101 	md->cb = md_cb;
102 	md->owner.cb_ctx = cb_ctx;
103 	md->owner.private = cb;
104 	ftl_md_persist(md);
105 }
106 
107 static int
108 ftl_l2p_flat_init_dram(struct spdk_ftl_dev *dev, struct ftl_l2p_flat *l2p_flat,
109 		       size_t l2p_size)
110 {
111 	struct ftl_md *md = get_l2p_md(dev);
112 
113 	assert(ftl_md_get_buffer_size(md) >= l2p_size);
114 
115 	l2p_flat->l2p = ftl_md_get_buffer(md);
116 	if (!l2p_flat->l2p) {
117 		FTL_ERRLOG(dev, "Failed to allocate l2p table\n");
118 		return -1;
119 	}
120 
121 	return 0;
122 }
123 
124 int
125 ftl_l2p_flat_init(struct spdk_ftl_dev *dev)
126 {
127 	size_t l2p_size = dev->num_lbas * dev->layout.l2p.addr_size;
128 	struct ftl_l2p_flat *l2p_flat;
129 	int ret;
130 
131 	if (dev->num_lbas == 0) {
132 		FTL_ERRLOG(dev, "Invalid l2p table size\n");
133 		return -1;
134 	}
135 
136 	if (dev->l2p) {
137 		FTL_ERRLOG(dev, "L2p table already allocated\n");
138 		return -1;
139 	}
140 
141 	l2p_flat = calloc(1, sizeof(*l2p_flat));
142 	if (!l2p_flat) {
143 		FTL_ERRLOG(dev, "Failed to allocate l2p_flat\n");
144 		return -1;
145 	}
146 
147 	ret = ftl_l2p_flat_init_dram(dev, l2p_flat, l2p_size);
148 
149 	if (ret) {
150 		free(l2p_flat);
151 		return ret;
152 	}
153 
154 	dev->l2p = l2p_flat;
155 	return 0;
156 }
157 
158 void
159 ftl_l2p_flat_deinit(struct spdk_ftl_dev *dev)
160 {
161 	struct ftl_l2p_flat *l2p_flat = dev->l2p;
162 
163 	if (!l2p_flat) {
164 		return;
165 	}
166 
167 	free(l2p_flat);
168 
169 	dev->l2p = NULL;
170 }
171 
172 void
173 ftl_l2p_flat_trim(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
174 {
175 	cb(dev, 0, cb_ctx);
176 }
177 
178 void
179 ftl_l2p_flat_process(struct spdk_ftl_dev *dev)
180 {
181 }
182 
183 bool
184 ftl_l2p_flat_is_halted(struct spdk_ftl_dev *dev)
185 {
186 	return true;
187 }
188 
189 void
190 ftl_l2p_flat_halt(struct spdk_ftl_dev *dev)
191 {
192 }
193 
194 void
195 ftl_l2p_flat_resume(struct spdk_ftl_dev *dev)
196 {
197 }
198