Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 : : */
4 : :
5 : : #include "spdk/dma.h"
6 : : #include "spdk/log.h"
7 : : #include "spdk/util.h"
8 : : #include "spdk/likely.h"
9 : :
10 : : static pthread_mutex_t g_dma_mutex = PTHREAD_MUTEX_INITIALIZER;
11 : : static TAILQ_HEAD(, spdk_memory_domain) g_dma_memory_domains = TAILQ_HEAD_INITIALIZER(
12 : : g_dma_memory_domains);
13 : :
14 : : struct spdk_memory_domain {
15 : : enum spdk_dma_device_type type;
16 : : spdk_memory_domain_pull_data_cb pull_cb;
17 : : spdk_memory_domain_push_data_cb push_cb;
18 : : spdk_memory_domain_translate_memory_cb translate_cb;
19 : : spdk_memory_domain_invalidate_data_cb invalidate_cb;
20 : : spdk_memory_domain_memzero_cb memzero_cb;
21 : : TAILQ_ENTRY(spdk_memory_domain) link;
22 : : struct spdk_memory_domain_ctx *ctx;
23 : : char *id;
24 : : };
25 : :
26 : : static struct spdk_memory_domain g_system_domain = {
27 : : .type = SPDK_DMA_DEVICE_TYPE_DMA,
28 : : .id = "system",
29 : : };
30 : :
31 : : static void
32 : : __attribute__((constructor))
33 : 2551 : _memory_domain_register(void)
34 : : {
35 : 2551 : TAILQ_INSERT_TAIL(&g_dma_memory_domains, &g_system_domain, link);
36 : 2551 : }
37 : :
38 : : struct spdk_memory_domain *
39 : 156517 : spdk_memory_domain_get_system_domain(void)
40 : : {
41 : 156517 : return &g_system_domain;
42 : : }
43 : :
44 : : int
45 : 2321 : spdk_memory_domain_create(struct spdk_memory_domain **_domain, enum spdk_dma_device_type type,
46 : : struct spdk_memory_domain_ctx *ctx, const char *id)
47 : : {
48 : : struct spdk_memory_domain *domain;
49 : : size_t ctx_size;
50 : :
51 [ + + ]: 2321 : if (!_domain) {
52 : 5 : return -EINVAL;
53 : : }
54 : :
55 [ + + + + ]: 2316 : if (ctx && ctx->size == 0) {
56 : 5 : SPDK_ERRLOG("Context size can't be 0\n");
57 : 5 : return -EINVAL;
58 : : }
59 : :
60 : 2311 : domain = calloc(1, sizeof(*domain));
61 [ - + ]: 2311 : if (!domain) {
62 : 0 : SPDK_ERRLOG("Failed to allocate memory");
63 : 0 : return -ENOMEM;
64 : : }
65 : :
66 [ + - ]: 2311 : if (id) {
67 [ - + ]: 2311 : domain->id = strdup(id);
68 [ - + ]: 2311 : if (!domain->id) {
69 : 0 : SPDK_ERRLOG("Failed to allocate memory");
70 : 0 : free(domain);
71 : 0 : return -ENOMEM;
72 : : }
73 : : }
74 : :
75 [ + + ]: 2311 : if (ctx) {
76 : 324 : domain->ctx = calloc(1, sizeof(*domain->ctx));
77 [ - + ]: 324 : if (!domain->ctx) {
78 : 0 : SPDK_ERRLOG("Failed to allocate memory");
79 : 0 : free(domain->id);
80 : 0 : free(domain);
81 : 0 : return -ENOMEM;
82 : : }
83 : :
84 : 324 : ctx_size = spdk_min(sizeof(*domain->ctx), ctx->size);
85 [ - + - + ]: 324 : memcpy(domain->ctx, ctx, ctx_size);
86 : 324 : domain->ctx->size = ctx_size;
87 : : }
88 : :
89 : 2311 : domain->type = type;
90 : :
91 [ - + ]: 2311 : pthread_mutex_lock(&g_dma_mutex);
92 : 2311 : TAILQ_INSERT_TAIL(&g_dma_memory_domains, domain, link);
93 [ - + ]: 2311 : pthread_mutex_unlock(&g_dma_mutex);
94 : :
95 : 2311 : *_domain = domain;
96 : :
97 : 2311 : return 0;
98 : : }
99 : :
100 : : void
101 : 2002 : spdk_memory_domain_set_translation(struct spdk_memory_domain *domain,
102 : : spdk_memory_domain_translate_memory_cb translate_cb)
103 : : {
104 [ - + ]: 2002 : assert(domain);
105 : :
106 : 2002 : domain->translate_cb = translate_cb;
107 : 2002 : }
108 : :
109 : : void
110 : 1983 : spdk_memory_domain_set_invalidate(struct spdk_memory_domain *domain,
111 : : spdk_memory_domain_invalidate_data_cb invalidate_cb)
112 : : {
113 [ - + ]: 1983 : assert(domain);
114 : :
115 : 1983 : domain->invalidate_cb = invalidate_cb;
116 : 1983 : }
117 : :
118 : : void
119 : 19 : spdk_memory_domain_set_pull(struct spdk_memory_domain *domain,
120 : : spdk_memory_domain_pull_data_cb pull_cb)
121 : : {
122 [ - + ]: 19 : assert(domain);
123 : :
124 : 19 : domain->pull_cb = pull_cb;
125 : 19 : }
126 : :
127 : : void
128 : 9 : spdk_memory_domain_set_push(struct spdk_memory_domain *domain,
129 : : spdk_memory_domain_push_data_cb push_cb)
130 : : {
131 [ - + ]: 9 : assert(domain);
132 : :
133 : 9 : domain->push_cb = push_cb;
134 : 9 : }
135 : :
136 : : void
137 : 19 : spdk_memory_domain_set_memzero(struct spdk_memory_domain *domain,
138 : : spdk_memory_domain_memzero_cb memzero_cb)
139 : : {
140 [ - + ]: 19 : assert(domain);
141 : :
142 : 19 : domain->memzero_cb = memzero_cb;
143 : 19 : }
144 : :
145 : : struct spdk_memory_domain_ctx *
146 : 5 : spdk_memory_domain_get_context(struct spdk_memory_domain *domain)
147 : : {
148 [ - + ]: 5 : assert(domain);
149 : :
150 : 5 : return domain->ctx;
151 : : }
152 : :
153 : : /* We have to use the typedef in the function declaration to appease astyle. */
154 : : typedef enum spdk_dma_device_type spdk_dma_device_type_t;
155 : :
156 : : spdk_dma_device_type_t
157 : 39597 : spdk_memory_domain_get_dma_device_type(struct spdk_memory_domain *domain)
158 : : {
159 [ - + ]: 39597 : assert(domain);
160 : :
161 : 39597 : return domain->type;
162 : : }
163 : :
164 : : const char *
165 : 39592 : spdk_memory_domain_get_dma_device_id(struct spdk_memory_domain *domain)
166 : : {
167 [ - + ]: 39592 : assert(domain);
168 : :
169 : 39592 : return domain->id;
170 : : }
171 : :
172 : : void
173 : 2305 : spdk_memory_domain_destroy(struct spdk_memory_domain *domain)
174 : : {
175 [ + + ]: 2305 : if (!domain) {
176 : 5 : return;
177 : : }
178 : :
179 [ - + ]: 2300 : assert(domain != &g_system_domain);
180 : :
181 [ - + ]: 2300 : pthread_mutex_lock(&g_dma_mutex);
182 [ + + ]: 2300 : TAILQ_REMOVE(&g_dma_memory_domains, domain, link);
183 [ - + ]: 2300 : pthread_mutex_unlock(&g_dma_mutex);
184 : :
185 : 2300 : free(domain->ctx);
186 : 2300 : free(domain->id);
187 : 2300 : free(domain);
188 : : }
189 : :
190 : : int
191 : 171458 : spdk_memory_domain_pull_data(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
192 : : struct iovec *src_iov, uint32_t src_iov_cnt, struct iovec *dst_iov, uint32_t dst_iov_cnt,
193 : : spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
194 : : {
195 [ - + ]: 171458 : assert(src_domain);
196 [ - + ]: 171458 : assert(src_iov);
197 [ - + ]: 171458 : assert(dst_iov);
198 : :
199 [ + + ]: 171458 : if (spdk_unlikely(!src_domain->pull_cb)) {
200 : 5 : return -ENOTSUP;
201 : : }
202 : :
203 : 171453 : return src_domain->pull_cb(src_domain, src_domain_ctx, src_iov, src_iov_cnt, dst_iov, dst_iov_cnt,
204 : : cpl_cb, cpl_cb_arg);
205 : : }
206 : :
207 : : int
208 : 400694 : spdk_memory_domain_push_data(struct spdk_memory_domain *dst_domain, void *dst_domain_ctx,
209 : : struct iovec *dst_iov, uint32_t dst_iovcnt, struct iovec *src_iov, uint32_t src_iovcnt,
210 : : spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
211 : : {
212 [ - + ]: 400694 : assert(dst_domain);
213 [ - + ]: 400694 : assert(dst_iov);
214 [ - + ]: 400694 : assert(src_iov);
215 : :
216 [ + + ]: 400694 : if (spdk_unlikely(!dst_domain->push_cb)) {
217 : 5 : return -ENOTSUP;
218 : : }
219 : :
220 : 400689 : return dst_domain->push_cb(dst_domain, dst_domain_ctx, dst_iov, dst_iovcnt, src_iov, src_iovcnt,
221 : : cpl_cb, cpl_cb_arg);
222 : : }
223 : :
224 : : int
225 : 487750 : spdk_memory_domain_translate_data(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
226 : : struct spdk_memory_domain *dst_domain, struct spdk_memory_domain_translation_ctx *dst_domain_ctx,
227 : : void *addr, size_t len, struct spdk_memory_domain_translation_result *result)
228 : : {
229 [ - + ]: 487750 : assert(src_domain);
230 [ - + ]: 487750 : assert(dst_domain);
231 [ - + ]: 487750 : assert(result);
232 : :
233 [ + + ]: 487750 : if (spdk_unlikely(!src_domain->translate_cb)) {
234 : 5 : return -ENOTSUP;
235 : : }
236 : :
237 : 487745 : return src_domain->translate_cb(src_domain, src_domain_ctx, dst_domain, dst_domain_ctx, addr, len,
238 : : result);
239 : : }
240 : :
241 : : void
242 : 78148 : spdk_memory_domain_invalidate_data(struct spdk_memory_domain *domain, void *domain_ctx,
243 : : struct iovec *iov, uint32_t iovcnt)
244 : : {
245 [ - + ]: 78148 : assert(domain);
246 : :
247 [ - + ]: 78148 : if (spdk_unlikely(!domain->invalidate_cb)) {
248 : 0 : return;
249 : : }
250 : :
251 : 78148 : domain->invalidate_cb(domain, domain_ctx, iov, iovcnt);
252 : : }
253 : :
254 : : int
255 : 816644 : spdk_memory_domain_memzero(struct spdk_memory_domain *domain, void *domain_ctx, struct iovec *iov,
256 : : uint32_t iovcnt, spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
257 : : {
258 [ - + ]: 816644 : assert(domain);
259 [ - + ]: 816644 : assert(iov);
260 [ - + ]: 816644 : assert(iovcnt);
261 : :
262 [ + + ]: 816644 : if (spdk_unlikely(!domain->memzero_cb)) {
263 : 5 : return -ENOTSUP;
264 : : }
265 : :
266 : 816639 : return domain->memzero_cb(domain, domain_ctx, iov, iovcnt, cpl_cb, cpl_cb_arg);
267 : : }
268 : :
269 : : struct spdk_memory_domain *
270 : 76086 : spdk_memory_domain_get_first(const char *id)
271 : : {
272 : : struct spdk_memory_domain *domain;
273 : :
274 [ + + ]: 76086 : if (!id) {
275 : 76071 : pthread_mutex_lock(&g_dma_mutex);
276 : 76071 : domain = TAILQ_FIRST(&g_dma_memory_domains);
277 : 76071 : pthread_mutex_unlock(&g_dma_mutex);
278 : :
279 : 76071 : return domain;
280 : : }
281 : :
282 : 15 : pthread_mutex_lock(&g_dma_mutex);
283 [ + + ]: 40 : TAILQ_FOREACH(domain, &g_dma_memory_domains, link) {
284 [ + + - + : 35 : if (!strcmp(domain->id, id)) {
+ + ]
285 : 10 : break;
286 : : }
287 : : }
288 : 15 : pthread_mutex_unlock(&g_dma_mutex);
289 : :
290 : 15 : return domain;
291 : : }
292 : :
293 : : struct spdk_memory_domain *
294 : 152154 : spdk_memory_domain_get_next(struct spdk_memory_domain *prev, const char *id)
295 : : {
296 : : struct spdk_memory_domain *domain;
297 : :
298 [ - + ]: 152154 : if (!prev) {
299 : 0 : return NULL;
300 : : }
301 : :
302 : 152154 : pthread_mutex_lock(&g_dma_mutex);
303 : 152154 : domain = TAILQ_NEXT(prev, link);
304 : 152154 : pthread_mutex_unlock(&g_dma_mutex);
305 : :
306 [ + + + + ]: 152154 : if (!id || !domain) {
307 : 152144 : return domain;
308 : : }
309 : :
310 : 10 : pthread_mutex_lock(&g_dma_mutex);
311 [ - + + + ]: 20 : TAILQ_FOREACH_FROM(domain, &g_dma_memory_domains, link) {
312 [ + + - + : 15 : if (!strcmp(domain->id, id)) {
+ + ]
313 : 5 : break;
314 : : }
315 : : }
316 : 10 : pthread_mutex_unlock(&g_dma_mutex);
317 : :
318 : 10 : return domain;
319 : : }
|