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 : : pthread_mutex_t g_dma_mutex = PTHREAD_MUTEX_INITIALIZER;
11 : : 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_memzero_cb memzero_cb;
20 : : TAILQ_ENTRY(spdk_memory_domain) link;
21 : : struct spdk_memory_domain_ctx *ctx;
22 : : char *id;
23 : : };
24 : :
25 : : int
26 : 3051 : spdk_memory_domain_create(struct spdk_memory_domain **_domain, enum spdk_dma_device_type type,
27 : : struct spdk_memory_domain_ctx *ctx, const char *id)
28 : : {
29 : : struct spdk_memory_domain *domain;
30 : : size_t ctx_size;
31 : :
32 [ + + ]: 3051 : if (!_domain) {
33 : 6 : return -EINVAL;
34 : : }
35 : :
36 [ + + + + ]: 3045 : if (ctx && ctx->size == 0) {
37 : 6 : SPDK_ERRLOG("Context size can't be 0\n");
38 : 6 : return -EINVAL;
39 : : }
40 : :
41 : 3039 : domain = calloc(1, sizeof(*domain));
42 [ - + ]: 3039 : if (!domain) {
43 : 0 : SPDK_ERRLOG("Failed to allocate memory");
44 : 0 : return -ENOMEM;
45 : : }
46 : :
47 [ + - ]: 3039 : if (id) {
48 [ - + ]: 3039 : domain->id = strdup(id);
49 [ - + ]: 3039 : if (!domain->id) {
50 : 0 : SPDK_ERRLOG("Failed to allocate memory");
51 : 0 : free(domain);
52 : 0 : return -ENOMEM;
53 : : }
54 : : }
55 : :
56 [ + + ]: 3039 : if (ctx) {
57 : 164 : domain->ctx = calloc(1, sizeof(*domain->ctx));
58 [ - + ]: 164 : if (!domain->ctx) {
59 : 0 : SPDK_ERRLOG("Failed to allocate memory");
60 : 0 : free(domain->id);
61 : 0 : free(domain);
62 : 0 : return -ENOMEM;
63 : : }
64 : :
65 : 164 : ctx_size = spdk_min(sizeof(*domain->ctx), ctx->size);
66 [ - + - + ]: 164 : memcpy(domain->ctx, ctx, ctx_size);
67 : 164 : domain->ctx->size = ctx_size;
68 : : }
69 : :
70 : 3039 : domain->type = type;
71 : :
72 [ - + ]: 3039 : pthread_mutex_lock(&g_dma_mutex);
73 : 3039 : TAILQ_INSERT_TAIL(&g_dma_memory_domains, domain, link);
74 [ - + ]: 3039 : pthread_mutex_unlock(&g_dma_mutex);
75 : :
76 : 3039 : *_domain = domain;
77 : :
78 : 3039 : return 0;
79 : : }
80 : :
81 : : void
82 : 22 : spdk_memory_domain_set_translation(struct spdk_memory_domain *domain,
83 : : spdk_memory_domain_translate_memory_cb translate_cb)
84 : : {
85 [ - + ]: 22 : if (!domain) {
86 : 0 : return;
87 : : }
88 : :
89 : 22 : domain->translate_cb = translate_cb;
90 : : }
91 : :
92 : : void
93 : 22 : spdk_memory_domain_set_pull(struct spdk_memory_domain *domain,
94 : : spdk_memory_domain_pull_data_cb pull_cb)
95 : : {
96 [ - + ]: 22 : if (!domain) {
97 : 0 : return;
98 : : }
99 : :
100 : 22 : domain->pull_cb = pull_cb;
101 : : }
102 : :
103 : : void
104 : 10 : spdk_memory_domain_set_push(struct spdk_memory_domain *domain,
105 : : spdk_memory_domain_push_data_cb push_cb)
106 : : {
107 [ - + ]: 10 : if (!domain) {
108 : 0 : return;
109 : : }
110 : :
111 : 10 : domain->push_cb = push_cb;
112 : : }
113 : :
114 : : void
115 : 22 : spdk_memory_domain_set_memzero(struct spdk_memory_domain *domain,
116 : : spdk_memory_domain_memzero_cb memzero_cb)
117 : : {
118 [ - + ]: 22 : if (!domain) {
119 : 0 : return;
120 : : }
121 : :
122 : 22 : domain->memzero_cb = memzero_cb;
123 : : }
124 : :
125 : : struct spdk_memory_domain_ctx *
126 : 6 : spdk_memory_domain_get_context(struct spdk_memory_domain *domain)
127 : : {
128 [ - + ]: 6 : assert(domain);
129 : :
130 : 6 : return domain->ctx;
131 : : }
132 : :
133 : : /* We have to use the typedef in the function declaration to appease astyle. */
134 : : typedef enum spdk_dma_device_type spdk_dma_device_type_t;
135 : :
136 : : spdk_dma_device_type_t
137 : 20237 : spdk_memory_domain_get_dma_device_type(struct spdk_memory_domain *domain)
138 : : {
139 [ - + ]: 20237 : assert(domain);
140 : :
141 : 20237 : return domain->type;
142 : : }
143 : :
144 : : const char *
145 : 20233 : spdk_memory_domain_get_dma_device_id(struct spdk_memory_domain *domain)
146 : : {
147 [ - + ]: 20233 : assert(domain);
148 : :
149 : 20233 : return domain->id;
150 : : }
151 : :
152 : : void
153 : 3034 : spdk_memory_domain_destroy(struct spdk_memory_domain *domain)
154 : : {
155 [ + + ]: 3034 : if (!domain) {
156 : 6 : return;
157 : : }
158 : :
159 [ - + ]: 3028 : pthread_mutex_lock(&g_dma_mutex);
160 [ + + ]: 3028 : TAILQ_REMOVE(&g_dma_memory_domains, domain, link);
161 [ - + ]: 3028 : pthread_mutex_unlock(&g_dma_mutex);
162 : :
163 : 3028 : free(domain->ctx);
164 : 3028 : free(domain->id);
165 : 3028 : free(domain);
166 : : }
167 : :
168 : : int
169 : 178748 : spdk_memory_domain_pull_data(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
170 : : struct iovec *src_iov, uint32_t src_iov_cnt, struct iovec *dst_iov, uint32_t dst_iov_cnt,
171 : : spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
172 : : {
173 [ - + ]: 178748 : assert(src_domain);
174 [ - + ]: 178748 : assert(src_iov);
175 [ - + ]: 178748 : assert(dst_iov);
176 : :
177 [ + + ]: 178748 : if (spdk_unlikely(!src_domain->pull_cb)) {
178 : 6 : return -ENOTSUP;
179 : : }
180 : :
181 : 178742 : return src_domain->pull_cb(src_domain, src_domain_ctx, src_iov, src_iov_cnt, dst_iov, dst_iov_cnt,
182 : : cpl_cb, cpl_cb_arg);
183 : : }
184 : :
185 : : int
186 : 417888 : spdk_memory_domain_push_data(struct spdk_memory_domain *dst_domain, void *dst_domain_ctx,
187 : : struct iovec *dst_iov, uint32_t dst_iovcnt, struct iovec *src_iov, uint32_t src_iovcnt,
188 : : spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
189 : : {
190 [ - + ]: 417888 : assert(dst_domain);
191 [ - + ]: 417888 : assert(dst_iov);
192 [ - + ]: 417888 : assert(src_iov);
193 : :
194 [ + + ]: 417888 : if (spdk_unlikely(!dst_domain->push_cb)) {
195 : 6 : return -ENOTSUP;
196 : : }
197 : :
198 : 417882 : return dst_domain->push_cb(dst_domain, dst_domain_ctx, dst_iov, dst_iovcnt, src_iov, src_iovcnt,
199 : : cpl_cb, cpl_cb_arg);
200 : : }
201 : :
202 : : int
203 : 411890 : spdk_memory_domain_translate_data(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
204 : : struct spdk_memory_domain *dst_domain, struct spdk_memory_domain_translation_ctx *dst_domain_ctx,
205 : : void *addr, size_t len, struct spdk_memory_domain_translation_result *result)
206 : : {
207 [ - + ]: 411890 : assert(src_domain);
208 [ - + ]: 411890 : assert(dst_domain);
209 [ - + ]: 411890 : assert(result);
210 : :
211 [ + + ]: 411890 : if (spdk_unlikely(!src_domain->translate_cb)) {
212 : 6 : return -ENOTSUP;
213 : : }
214 : :
215 : 411884 : return src_domain->translate_cb(src_domain, src_domain_ctx, dst_domain, dst_domain_ctx, addr, len,
216 : : result);
217 : : }
218 : :
219 : : int
220 : 724597 : spdk_memory_domain_memzero(struct spdk_memory_domain *domain, void *domain_ctx, struct iovec *iov,
221 : : uint32_t iovcnt, spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
222 : : {
223 [ - + ]: 724597 : assert(domain);
224 [ - + ]: 724597 : assert(iov);
225 [ - + ]: 724597 : assert(iovcnt);
226 : :
227 [ + + ]: 724597 : if (spdk_unlikely(!domain->memzero_cb)) {
228 : 6 : return -ENOTSUP;
229 : : }
230 : :
231 : 724591 : return domain->memzero_cb(domain, domain_ctx, iov, iovcnt, cpl_cb, cpl_cb_arg);
232 : : }
233 : :
234 : : struct spdk_memory_domain *
235 : 86988 : spdk_memory_domain_get_first(const char *id)
236 : : {
237 : : struct spdk_memory_domain *domain;
238 : :
239 [ + + ]: 86988 : if (!id) {
240 : 86970 : pthread_mutex_lock(&g_dma_mutex);
241 : 86970 : domain = TAILQ_FIRST(&g_dma_memory_domains);
242 : 86970 : pthread_mutex_unlock(&g_dma_mutex);
243 : :
244 : 86970 : return domain;
245 : : }
246 : :
247 : 18 : pthread_mutex_lock(&g_dma_mutex);
248 [ + + ]: 30 : TAILQ_FOREACH(domain, &g_dma_memory_domains, link) {
249 [ + + - + : 24 : if (!strcmp(domain->id, id)) {
+ + ]
250 : 12 : break;
251 : : }
252 : : }
253 : 18 : pthread_mutex_unlock(&g_dma_mutex);
254 : :
255 : 18 : return domain;
256 : : }
257 : :
258 : : struct spdk_memory_domain *
259 : 86996 : spdk_memory_domain_get_next(struct spdk_memory_domain *prev, const char *id)
260 : : {
261 : : struct spdk_memory_domain *domain;
262 : :
263 [ - + ]: 86996 : if (!prev) {
264 : 0 : return NULL;
265 : : }
266 : :
267 : 86996 : pthread_mutex_lock(&g_dma_mutex);
268 : 86996 : domain = TAILQ_NEXT(prev, link);
269 : 86996 : pthread_mutex_unlock(&g_dma_mutex);
270 : :
271 [ + + + + ]: 86996 : if (!id || !domain) {
272 : 86984 : return domain;
273 : : }
274 : :
275 : 12 : pthread_mutex_lock(&g_dma_mutex);
276 [ - + + + ]: 24 : TAILQ_FOREACH_FROM(domain, &g_dma_memory_domains, link) {
277 [ + + - + : 18 : if (!strcmp(domain->id, id)) {
+ + ]
278 : 6 : break;
279 : : }
280 : : }
281 : 12 : pthread_mutex_unlock(&g_dma_mutex);
282 : :
283 : 12 : return domain;
284 : : }
|