Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2021 NVIDIA Corporation & Affiliates
3 : : */
4 : :
5 : : #include <stdlib.h>
6 : : #include <sys/queue.h>
7 : :
8 : : #include <eal_export.h>
9 : : #include <rte_eal.h>
10 : : #include <rte_tailq.h>
11 : : #include <rte_string_fns.h>
12 : : #include <rte_memzone.h>
13 : : #include <rte_malloc.h>
14 : : #include <rte_errno.h>
15 : : #include <rte_log.h>
16 : :
17 : : #include "rte_gpudev.h"
18 : : #include "gpudev_driver.h"
19 : :
20 : : /* Logging */
21 [ - + ]: 253 : RTE_LOG_REGISTER_DEFAULT(gpu_logtype, NOTICE);
22 : : #define RTE_LOGTYPE_GPUDEV gpu_logtype
23 : :
24 : : #define GPU_LOG(level, ...) \
25 : : RTE_LOG_LINE(level, GPUDEV, "" __VA_ARGS__)
26 : :
27 : : /* Set any driver error as EPERM */
28 : : #define GPU_DRV_RET(function) \
29 : : ((function != 0) ? -(rte_errno = EPERM) : (rte_errno = 0))
30 : :
31 : : /* Array of devices */
32 : : static struct rte_gpu *gpus;
33 : : /* Number of currently valid devices */
34 : : static int16_t gpu_max;
35 : : /* Number of currently valid devices */
36 : : static int16_t gpu_count;
37 : :
38 : : /* Shared memory between processes. */
39 : : static const char *GPU_MEMZONE = "rte_gpu_shared";
40 : : static struct {
41 : : __extension__ struct rte_gpu_mpshared gpus[0];
42 : : } *gpu_shared_mem;
43 : :
44 : : /* Event callback object */
45 : : struct rte_gpu_callback {
46 : : TAILQ_ENTRY(rte_gpu_callback) next;
47 : : rte_gpu_callback_t *function;
48 : : void *user_data;
49 : : enum rte_gpu_event event;
50 : : };
51 : : static rte_rwlock_t gpu_callback_lock = RTE_RWLOCK_INITIALIZER;
52 : : static void gpu_free_callbacks(struct rte_gpu *dev);
53 : :
54 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_init, 21.11)
55 : : int
56 : 0 : rte_gpu_init(size_t dev_max)
57 : : {
58 [ # # ]: 0 : if (dev_max == 0 || dev_max > INT16_MAX) {
59 : 0 : GPU_LOG(ERR, "invalid array size");
60 : 0 : rte_errno = EINVAL;
61 : 0 : return -rte_errno;
62 : : }
63 : :
64 : : /* No lock, it must be called before or during first probing. */
65 [ # # ]: 0 : if (gpus != NULL) {
66 : 0 : GPU_LOG(ERR, "already initialized");
67 : 0 : rte_errno = EBUSY;
68 : 0 : return -rte_errno;
69 : : }
70 : :
71 : 0 : gpus = calloc(dev_max, sizeof(struct rte_gpu));
72 [ # # ]: 0 : if (gpus == NULL) {
73 : 0 : GPU_LOG(ERR, "cannot initialize library");
74 : 0 : rte_errno = ENOMEM;
75 : 0 : return -rte_errno;
76 : : }
77 : :
78 : 0 : gpu_max = dev_max;
79 : 0 : return 0;
80 : : }
81 : :
82 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_count_avail, 21.11)
83 : : uint16_t
84 : 0 : rte_gpu_count_avail(void)
85 : : {
86 : 0 : return gpu_count;
87 : : }
88 : :
89 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_is_valid, 21.11)
90 : : bool
91 : 0 : rte_gpu_is_valid(int16_t dev_id)
92 : : {
93 [ # # # # ]: 0 : if (dev_id >= 0 && dev_id < gpu_max &&
94 [ # # ]: 0 : gpus[dev_id].process_state == RTE_GPU_STATE_INITIALIZED)
95 : 0 : return true;
96 : : return false;
97 : : }
98 : :
99 : : static bool
100 : : gpu_match_parent(int16_t dev_id, int16_t parent)
101 : : {
102 [ # # ]: 0 : if (parent == RTE_GPU_ID_ANY)
103 : : return true;
104 : 0 : return gpus[dev_id].mpshared->info.parent == parent;
105 : : }
106 : :
107 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_find_next, 21.11)
108 : : int16_t
109 : 0 : rte_gpu_find_next(int16_t dev_id, int16_t parent)
110 : : {
111 : : if (dev_id < 0)
112 : : dev_id = 0;
113 [ # # ]: 0 : while (dev_id < gpu_max &&
114 [ # # # # ]: 0 : (gpus[dev_id].process_state == RTE_GPU_STATE_UNUSED ||
115 : : !gpu_match_parent(dev_id, parent)))
116 : 0 : dev_id++;
117 : :
118 [ # # ]: 0 : if (dev_id >= gpu_max)
119 : 0 : return RTE_GPU_ID_NONE;
120 : : return dev_id;
121 : : }
122 : :
123 : : static int16_t
124 : : gpu_find_free_id(void)
125 : : {
126 : : int16_t dev_id;
127 : :
128 [ # # ]: 0 : for (dev_id = 0; dev_id < gpu_max; dev_id++) {
129 [ # # ]: 0 : if (gpus[dev_id].process_state == RTE_GPU_STATE_UNUSED)
130 : : return dev_id;
131 : : }
132 : : return RTE_GPU_ID_NONE;
133 : : }
134 : :
135 : : static struct rte_gpu *
136 : : gpu_get_by_id(int16_t dev_id)
137 : : {
138 [ # # # # : 0 : if (!rte_gpu_is_valid(dev_id))
# # # # #
# # # # #
# # # # #
# ]
139 : : return NULL;
140 : 0 : return &gpus[dev_id];
141 : : }
142 : :
143 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_gpu_get_by_name)
144 : : struct rte_gpu *
145 : 0 : rte_gpu_get_by_name(const char *name)
146 : : {
147 : : int16_t dev_id;
148 : : struct rte_gpu *dev;
149 : :
150 [ # # ]: 0 : if (name == NULL) {
151 : 0 : rte_errno = EINVAL;
152 : 0 : return NULL;
153 : : }
154 : :
155 [ # # ]: 0 : RTE_GPU_FOREACH(dev_id) {
156 : 0 : dev = &gpus[dev_id];
157 [ # # ]: 0 : if (strncmp(name, dev->mpshared->name, RTE_DEV_NAME_MAX_LEN) == 0)
158 : 0 : return dev;
159 : : }
160 : : return NULL;
161 : : }
162 : :
163 : : static int
164 : 0 : gpu_shared_mem_init(void)
165 : : {
166 : : const struct rte_memzone *memzone;
167 : :
168 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
169 : 0 : memzone = rte_memzone_reserve(GPU_MEMZONE,
170 : : sizeof(*gpu_shared_mem) +
171 : : sizeof(*gpu_shared_mem->gpus) * gpu_max,
172 : : SOCKET_ID_ANY, 0);
173 : : } else {
174 : 0 : memzone = rte_memzone_lookup(GPU_MEMZONE);
175 : : }
176 [ # # ]: 0 : if (memzone == NULL) {
177 : 0 : GPU_LOG(ERR, "cannot initialize shared memory");
178 : 0 : rte_errno = ENOMEM;
179 : 0 : return -rte_errno;
180 : : }
181 : :
182 : 0 : gpu_shared_mem = memzone->addr;
183 : 0 : return 0;
184 : : }
185 : :
186 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_gpu_allocate)
187 : : struct rte_gpu *
188 : 0 : rte_gpu_allocate(const char *name)
189 : : {
190 : : int16_t dev_id;
191 : : struct rte_gpu *dev;
192 : :
193 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
194 : 0 : GPU_LOG(ERR, "only primary process can allocate device");
195 : 0 : rte_errno = EPERM;
196 : 0 : return NULL;
197 : : }
198 [ # # ]: 0 : if (name == NULL) {
199 : 0 : GPU_LOG(ERR, "allocate device without a name");
200 : 0 : rte_errno = EINVAL;
201 : 0 : return NULL;
202 : : }
203 : :
204 : : /* implicit initialization of library before adding first device */
205 [ # # # # ]: 0 : if (gpus == NULL && rte_gpu_init(RTE_GPU_DEFAULT_MAX) < 0)
206 : : return NULL;
207 : :
208 : : /* initialize shared memory before adding first device */
209 [ # # # # ]: 0 : if (gpu_shared_mem == NULL && gpu_shared_mem_init() < 0)
210 : : return NULL;
211 : :
212 [ # # ]: 0 : if (rte_gpu_get_by_name(name) != NULL) {
213 : 0 : GPU_LOG(ERR, "device with name %s already exists", name);
214 : 0 : rte_errno = EEXIST;
215 : 0 : return NULL;
216 : : }
217 : : dev_id = gpu_find_free_id();
218 [ # # ]: 0 : if (dev_id == RTE_GPU_ID_NONE) {
219 : 0 : GPU_LOG(ERR, "reached maximum number of devices");
220 : 0 : rte_errno = ENOENT;
221 : 0 : return NULL;
222 : : }
223 : :
224 : 0 : dev = &gpus[dev_id];
225 : : memset(dev, 0, sizeof(*dev));
226 : :
227 : 0 : dev->mpshared = &gpu_shared_mem->gpus[dev_id];
228 : : memset(dev->mpshared, 0, sizeof(*dev->mpshared));
229 : :
230 [ # # ]: 0 : if (rte_strscpy(dev->mpshared->name, name, RTE_DEV_NAME_MAX_LEN) < 0) {
231 : 0 : GPU_LOG(ERR, "device name too long: %s", name);
232 : 0 : rte_errno = ENAMETOOLONG;
233 : 0 : return NULL;
234 : : }
235 : 0 : dev->mpshared->info.name = dev->mpshared->name;
236 : 0 : dev->mpshared->info.dev_id = dev_id;
237 : 0 : dev->mpshared->info.numa_node = -1;
238 : 0 : dev->mpshared->info.parent = RTE_GPU_ID_NONE;
239 : 0 : TAILQ_INIT(&dev->callbacks);
240 : 0 : rte_atomic_fetch_add_explicit(&dev->mpshared->process_refcnt, 1, rte_memory_order_relaxed);
241 : :
242 : 0 : gpu_count++;
243 : 0 : GPU_LOG(DEBUG, "new device %s (id %d) of total %d",
244 : : name, dev_id, gpu_count);
245 : 0 : return dev;
246 : : }
247 : :
248 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_gpu_attach)
249 : : struct rte_gpu *
250 : 0 : rte_gpu_attach(const char *name)
251 : : {
252 : : int16_t dev_id;
253 : : struct rte_gpu *dev;
254 : : struct rte_gpu_mpshared *shared_dev;
255 : :
256 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_SECONDARY) {
257 : 0 : GPU_LOG(ERR, "only secondary process can attach device");
258 : 0 : rte_errno = EPERM;
259 : 0 : return NULL;
260 : : }
261 [ # # ]: 0 : if (name == NULL) {
262 : 0 : GPU_LOG(ERR, "attach device without a name");
263 : 0 : rte_errno = EINVAL;
264 : 0 : return NULL;
265 : : }
266 : :
267 : : /* implicit initialization of library before adding first device */
268 [ # # # # ]: 0 : if (gpus == NULL && rte_gpu_init(RTE_GPU_DEFAULT_MAX) < 0)
269 : : return NULL;
270 : :
271 : : /* initialize shared memory before adding first device */
272 [ # # # # ]: 0 : if (gpu_shared_mem == NULL && gpu_shared_mem_init() < 0)
273 : : return NULL;
274 : :
275 [ # # ]: 0 : for (dev_id = 0; dev_id < gpu_max; dev_id++) {
276 : 0 : shared_dev = &gpu_shared_mem->gpus[dev_id];
277 [ # # ]: 0 : if (strncmp(name, shared_dev->name, RTE_DEV_NAME_MAX_LEN) == 0)
278 : : break;
279 : : }
280 [ # # ]: 0 : if (dev_id >= gpu_max) {
281 : 0 : GPU_LOG(ERR, "device with name %s not found", name);
282 : 0 : rte_errno = ENOENT;
283 : 0 : return NULL;
284 : : }
285 : 0 : dev = &gpus[dev_id];
286 : : memset(dev, 0, sizeof(*dev));
287 : :
288 : 0 : TAILQ_INIT(&dev->callbacks);
289 : 0 : dev->mpshared = shared_dev;
290 : 0 : rte_atomic_fetch_add_explicit(&dev->mpshared->process_refcnt, 1, rte_memory_order_relaxed);
291 : :
292 : 0 : gpu_count++;
293 : 0 : GPU_LOG(DEBUG, "attached device %s (id %d) of total %d",
294 : : name, dev_id, gpu_count);
295 : 0 : return dev;
296 : : }
297 : :
298 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_add_child, 21.11)
299 : : int16_t
300 : 0 : rte_gpu_add_child(const char *name, int16_t parent, uint64_t child_context)
301 : : {
302 : : struct rte_gpu *dev;
303 : :
304 [ # # ]: 0 : if (!rte_gpu_is_valid(parent)) {
305 : 0 : GPU_LOG(ERR, "add child to invalid parent ID %d", parent);
306 : 0 : rte_errno = ENODEV;
307 : 0 : return -rte_errno;
308 : : }
309 : :
310 : 0 : dev = rte_gpu_allocate(name);
311 [ # # ]: 0 : if (dev == NULL)
312 : 0 : return -rte_errno;
313 : :
314 : 0 : dev->mpshared->info.parent = parent;
315 : 0 : dev->mpshared->info.context = child_context;
316 : :
317 : 0 : rte_gpu_complete_new(dev);
318 : 0 : return dev->mpshared->info.dev_id;
319 : : }
320 : :
321 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_gpu_complete_new)
322 : : void
323 : 0 : rte_gpu_complete_new(struct rte_gpu *dev)
324 : : {
325 [ # # ]: 0 : if (dev == NULL)
326 : : return;
327 : :
328 : 0 : dev->process_state = RTE_GPU_STATE_INITIALIZED;
329 : 0 : rte_gpu_notify(dev, RTE_GPU_EVENT_NEW);
330 : : }
331 : :
332 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_gpu_release)
333 : : int
334 : 0 : rte_gpu_release(struct rte_gpu *dev)
335 : : {
336 : : int16_t dev_id, child;
337 : :
338 [ # # ]: 0 : if (dev == NULL) {
339 : 0 : rte_errno = ENODEV;
340 : 0 : return -rte_errno;
341 : : }
342 : 0 : dev_id = dev->mpshared->info.dev_id;
343 [ # # ]: 0 : RTE_GPU_FOREACH_CHILD(child, dev_id) {
344 : 0 : GPU_LOG(ERR, "cannot release device %d with child %d",
345 : : dev_id, child);
346 : 0 : rte_errno = EBUSY;
347 : 0 : return -rte_errno;
348 : : }
349 : :
350 : 0 : GPU_LOG(DEBUG, "free device %s (id %d)",
351 : : dev->mpshared->info.name, dev->mpshared->info.dev_id);
352 : 0 : rte_gpu_notify(dev, RTE_GPU_EVENT_DEL);
353 : :
354 : 0 : gpu_free_callbacks(dev);
355 : 0 : dev->process_state = RTE_GPU_STATE_UNUSED;
356 : 0 : rte_atomic_fetch_sub_explicit(&dev->mpshared->process_refcnt, 1, rte_memory_order_relaxed);
357 : 0 : gpu_count--;
358 : :
359 : 0 : return 0;
360 : : }
361 : :
362 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_close, 21.11)
363 : : int
364 : 0 : rte_gpu_close(int16_t dev_id)
365 : : {
366 : : int firsterr, binerr;
367 : : int *lasterr = &firsterr;
368 : : struct rte_gpu *dev;
369 : :
370 : 0 : dev = gpu_get_by_id(dev_id);
371 [ # # ]: 0 : if (dev == NULL) {
372 : 0 : GPU_LOG(ERR, "close invalid device ID %d", dev_id);
373 : 0 : rte_errno = ENODEV;
374 : 0 : return -rte_errno;
375 : : }
376 : :
377 [ # # ]: 0 : if (dev->ops.dev_close != NULL) {
378 [ # # ]: 0 : *lasterr = GPU_DRV_RET(dev->ops.dev_close(dev));
379 [ # # ]: 0 : if (*lasterr != 0)
380 : : lasterr = &binerr;
381 : : }
382 : :
383 : 0 : *lasterr = rte_gpu_release(dev);
384 : :
385 : 0 : rte_errno = -firsterr;
386 : 0 : return firsterr;
387 : : }
388 : :
389 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_callback_register, 21.11)
390 : : int
391 : 0 : rte_gpu_callback_register(int16_t dev_id, enum rte_gpu_event event,
392 : : rte_gpu_callback_t *function, void *user_data)
393 : : {
394 : : int16_t next_dev, last_dev;
395 : : struct rte_gpu_callback_list *callbacks;
396 : : struct rte_gpu_callback *callback;
397 : :
398 [ # # # # ]: 0 : if (!rte_gpu_is_valid(dev_id) && dev_id != RTE_GPU_ID_ANY) {
399 : 0 : GPU_LOG(ERR, "register callback of invalid ID %d", dev_id);
400 : 0 : rte_errno = ENODEV;
401 : 0 : return -rte_errno;
402 : : }
403 [ # # ]: 0 : if (function == NULL) {
404 : 0 : GPU_LOG(ERR, "cannot register callback without function");
405 : 0 : rte_errno = EINVAL;
406 : 0 : return -rte_errno;
407 : : }
408 : :
409 [ # # ]: 0 : if (dev_id == RTE_GPU_ID_ANY) {
410 : : next_dev = 0;
411 : 0 : last_dev = gpu_max - 1;
412 : : } else {
413 : : next_dev = last_dev = dev_id;
414 : : }
415 : :
416 : 0 : rte_rwlock_write_lock(&gpu_callback_lock);
417 : : do {
418 : 0 : callbacks = &gpus[next_dev].callbacks;
419 : :
420 : : /* check if not already registered */
421 [ # # ]: 0 : TAILQ_FOREACH(callback, callbacks, next) {
422 [ # # ]: 0 : if (callback->event == event &&
423 [ # # ]: 0 : callback->function == function &&
424 [ # # ]: 0 : callback->user_data == user_data) {
425 : 0 : GPU_LOG(INFO, "callback already registered");
426 : : rte_rwlock_write_unlock(&gpu_callback_lock);
427 : 0 : return 0;
428 : : }
429 : : }
430 : :
431 : 0 : callback = malloc(sizeof(*callback));
432 [ # # ]: 0 : if (callback == NULL) {
433 : 0 : GPU_LOG(ERR, "cannot allocate callback");
434 : : rte_rwlock_write_unlock(&gpu_callback_lock);
435 : 0 : rte_errno = ENOMEM;
436 : 0 : return -rte_errno;
437 : : }
438 : 0 : callback->function = function;
439 : 0 : callback->user_data = user_data;
440 : 0 : callback->event = event;
441 : 0 : TAILQ_INSERT_TAIL(callbacks, callback, next);
442 : :
443 [ # # ]: 0 : } while (++next_dev <= last_dev);
444 : : rte_rwlock_write_unlock(&gpu_callback_lock);
445 : :
446 : 0 : return 0;
447 : : }
448 : :
449 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_callback_unregister, 21.11)
450 : : int
451 : 0 : rte_gpu_callback_unregister(int16_t dev_id, enum rte_gpu_event event,
452 : : rte_gpu_callback_t *function, void *user_data)
453 : : {
454 : : int16_t next_dev, last_dev;
455 : : struct rte_gpu_callback_list *callbacks;
456 : : struct rte_gpu_callback *callback, *nextcb;
457 : :
458 [ # # # # ]: 0 : if (!rte_gpu_is_valid(dev_id) && dev_id != RTE_GPU_ID_ANY) {
459 : 0 : GPU_LOG(ERR, "unregister callback of invalid ID %d", dev_id);
460 : 0 : rte_errno = ENODEV;
461 : 0 : return -rte_errno;
462 : : }
463 [ # # ]: 0 : if (function == NULL) {
464 : 0 : GPU_LOG(ERR, "cannot unregister callback without function");
465 : 0 : rte_errno = EINVAL;
466 : 0 : return -rte_errno;
467 : : }
468 : :
469 [ # # ]: 0 : if (dev_id == RTE_GPU_ID_ANY) {
470 : : next_dev = 0;
471 : 0 : last_dev = gpu_max - 1;
472 : : } else {
473 : : next_dev = last_dev = dev_id;
474 : : }
475 : :
476 : 0 : rte_rwlock_write_lock(&gpu_callback_lock);
477 : : do {
478 : 0 : callbacks = &gpus[next_dev].callbacks;
479 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(callback, callbacks, next, nextcb) {
480 [ # # ]: 0 : if (callback->event != event ||
481 [ # # ]: 0 : callback->function != function ||
482 [ # # # # ]: 0 : (callback->user_data != user_data &&
483 : : user_data != (void *)-1))
484 : 0 : continue;
485 [ # # ]: 0 : TAILQ_REMOVE(callbacks, callback, next);
486 : 0 : free(callback);
487 : : }
488 [ # # ]: 0 : } while (++next_dev <= last_dev);
489 : : rte_rwlock_write_unlock(&gpu_callback_lock);
490 : :
491 : 0 : return 0;
492 : : }
493 : :
494 : : static void
495 : 0 : gpu_free_callbacks(struct rte_gpu *dev)
496 : : {
497 : : struct rte_gpu_callback_list *callbacks;
498 : : struct rte_gpu_callback *callback, *nextcb;
499 : :
500 : : callbacks = &dev->callbacks;
501 : 0 : rte_rwlock_write_lock(&gpu_callback_lock);
502 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(callback, callbacks, next, nextcb) {
503 [ # # ]: 0 : TAILQ_REMOVE(callbacks, callback, next);
504 : 0 : free(callback);
505 : : }
506 : : rte_rwlock_write_unlock(&gpu_callback_lock);
507 : 0 : }
508 : :
509 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_gpu_notify)
510 : : void
511 : 0 : rte_gpu_notify(struct rte_gpu *dev, enum rte_gpu_event event)
512 : : {
513 : : int16_t dev_id;
514 : : struct rte_gpu_callback *callback;
515 : :
516 : 0 : dev_id = dev->mpshared->info.dev_id;
517 : 0 : rte_rwlock_read_lock(&gpu_callback_lock);
518 [ # # ]: 0 : TAILQ_FOREACH(callback, &dev->callbacks, next) {
519 [ # # # # ]: 0 : if (callback->event != event || callback->function == NULL)
520 : 0 : continue;
521 : 0 : callback->function(dev_id, event, callback->user_data);
522 : : }
523 : : rte_rwlock_read_unlock(&gpu_callback_lock);
524 : 0 : }
525 : :
526 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_info_get, 21.11)
527 : : int
528 : 0 : rte_gpu_info_get(int16_t dev_id, struct rte_gpu_info *info)
529 : : {
530 : : struct rte_gpu *dev;
531 : :
532 : 0 : dev = gpu_get_by_id(dev_id);
533 [ # # ]: 0 : if (dev == NULL) {
534 : 0 : GPU_LOG(ERR, "query invalid device ID %d", dev_id);
535 : 0 : rte_errno = ENODEV;
536 : 0 : return -rte_errno;
537 : : }
538 [ # # ]: 0 : if (info == NULL) {
539 : 0 : GPU_LOG(ERR, "query without storage");
540 : 0 : rte_errno = EINVAL;
541 : 0 : return -rte_errno;
542 : : }
543 : :
544 [ # # ]: 0 : if (dev->ops.dev_info_get == NULL) {
545 : 0 : *info = dev->mpshared->info;
546 : 0 : return 0;
547 : : }
548 [ # # ]: 0 : return GPU_DRV_RET(dev->ops.dev_info_get(dev, info));
549 : : }
550 : :
551 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_mem_alloc, 21.11)
552 : : void *
553 : 0 : rte_gpu_mem_alloc(int16_t dev_id, size_t size, unsigned int align)
554 : : {
555 : : struct rte_gpu *dev;
556 : : void *ptr;
557 : : int ret;
558 : :
559 : 0 : dev = gpu_get_by_id(dev_id);
560 [ # # ]: 0 : if (dev == NULL) {
561 : 0 : GPU_LOG(ERR, "alloc mem for invalid device ID %d", dev_id);
562 : 0 : rte_errno = ENODEV;
563 : 0 : return NULL;
564 : : }
565 : :
566 [ # # ]: 0 : if (dev->ops.mem_alloc == NULL) {
567 : 0 : GPU_LOG(ERR, "mem allocation not supported");
568 : 0 : rte_errno = ENOTSUP;
569 : 0 : return NULL;
570 : : }
571 : :
572 [ # # ]: 0 : if (size == 0) /* dry-run */
573 : : return NULL;
574 : :
575 [ # # ]: 0 : if (align && !rte_is_power_of_2(align)) {
576 : 0 : GPU_LOG(ERR, "requested alignment is not a power of two %u", align);
577 : 0 : rte_errno = EINVAL;
578 : 0 : return NULL;
579 : : }
580 : :
581 : 0 : ret = dev->ops.mem_alloc(dev, size, align, &ptr);
582 : :
583 [ # # # ]: 0 : switch (ret) {
584 : 0 : case 0:
585 : 0 : return ptr;
586 : 0 : case -ENOMEM:
587 : : case -E2BIG:
588 : 0 : rte_errno = -ret;
589 : 0 : return NULL;
590 : 0 : default:
591 : 0 : rte_errno = -EPERM;
592 : 0 : return NULL;
593 : : }
594 : : }
595 : :
596 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_mem_free, 21.11)
597 : : int
598 : 0 : rte_gpu_mem_free(int16_t dev_id, void *ptr)
599 : : {
600 : : struct rte_gpu *dev;
601 : :
602 : 0 : dev = gpu_get_by_id(dev_id);
603 [ # # ]: 0 : if (dev == NULL) {
604 : 0 : GPU_LOG(ERR, "free mem for invalid device ID %d", dev_id);
605 : 0 : rte_errno = ENODEV;
606 : 0 : return -rte_errno;
607 : : }
608 : :
609 [ # # ]: 0 : if (dev->ops.mem_free == NULL) {
610 : 0 : rte_errno = ENOTSUP;
611 : 0 : return -rte_errno;
612 : : }
613 : :
614 [ # # ]: 0 : if (ptr == NULL) /* dry-run */
615 : : return 0;
616 : :
617 [ # # ]: 0 : return GPU_DRV_RET(dev->ops.mem_free(dev, ptr));
618 : : }
619 : :
620 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_mem_register, 21.11)
621 : : int
622 : 0 : rte_gpu_mem_register(int16_t dev_id, size_t size, void *ptr)
623 : : {
624 : : struct rte_gpu *dev;
625 : :
626 : 0 : dev = gpu_get_by_id(dev_id);
627 [ # # ]: 0 : if (dev == NULL) {
628 : 0 : GPU_LOG(ERR, "alloc mem for invalid device ID %d", dev_id);
629 : 0 : rte_errno = ENODEV;
630 : 0 : return -rte_errno;
631 : : }
632 : :
633 [ # # ]: 0 : if (dev->ops.mem_register == NULL) {
634 : 0 : GPU_LOG(ERR, "mem registration not supported");
635 : 0 : rte_errno = ENOTSUP;
636 : 0 : return -rte_errno;
637 : : }
638 : :
639 [ # # ]: 0 : if (ptr == NULL || size == 0) /* dry-run */
640 : : return 0;
641 : :
642 [ # # ]: 0 : return GPU_DRV_RET(dev->ops.mem_register(dev, size, ptr));
643 : : }
644 : :
645 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_mem_unregister, 21.11)
646 : : int
647 : 0 : rte_gpu_mem_unregister(int16_t dev_id, void *ptr)
648 : : {
649 : : struct rte_gpu *dev;
650 : :
651 : 0 : dev = gpu_get_by_id(dev_id);
652 [ # # ]: 0 : if (dev == NULL) {
653 : 0 : GPU_LOG(ERR, "unregister mem for invalid device ID %d", dev_id);
654 : 0 : rte_errno = ENODEV;
655 : 0 : return -rte_errno;
656 : : }
657 : :
658 [ # # ]: 0 : if (dev->ops.mem_unregister == NULL) {
659 : 0 : rte_errno = ENOTSUP;
660 : 0 : return -rte_errno;
661 : : }
662 : :
663 [ # # ]: 0 : if (ptr == NULL) /* dry-run */
664 : : return 0;
665 : :
666 [ # # ]: 0 : return GPU_DRV_RET(dev->ops.mem_unregister(dev, ptr));
667 : : }
668 : :
669 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_mem_cpu_map, 21.11)
670 : : void *
671 : 0 : rte_gpu_mem_cpu_map(int16_t dev_id, size_t size, void *ptr)
672 : : {
673 : : struct rte_gpu *dev;
674 : : void *ptr_out;
675 : : int ret;
676 : :
677 : 0 : dev = gpu_get_by_id(dev_id);
678 [ # # ]: 0 : if (dev == NULL) {
679 : 0 : GPU_LOG(ERR, "mem CPU map for invalid device ID %d", dev_id);
680 : 0 : rte_errno = ENODEV;
681 : 0 : return NULL;
682 : : }
683 : :
684 [ # # ]: 0 : if (dev->ops.mem_cpu_map == NULL) {
685 : 0 : GPU_LOG(ERR, "mem CPU map not supported");
686 : 0 : rte_errno = ENOTSUP;
687 : 0 : return NULL;
688 : : }
689 : :
690 [ # # ]: 0 : if (ptr == NULL || size == 0) /* dry-run */
691 : : return NULL;
692 : :
693 [ # # ]: 0 : ret = GPU_DRV_RET(dev->ops.mem_cpu_map(dev, size, ptr, &ptr_out));
694 : :
695 [ # # ]: 0 : switch (ret) {
696 : 0 : case 0:
697 : 0 : return ptr_out;
698 : : case -ENOMEM:
699 : : case -E2BIG:
700 : : rte_errno = -ret;
701 : : return NULL;
702 : 0 : default:
703 : 0 : rte_errno = -EPERM;
704 : 0 : return NULL;
705 : : }
706 : : }
707 : :
708 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_mem_cpu_unmap, 21.11)
709 : : int
710 : 0 : rte_gpu_mem_cpu_unmap(int16_t dev_id, void *ptr)
711 : : {
712 : : struct rte_gpu *dev;
713 : :
714 : 0 : dev = gpu_get_by_id(dev_id);
715 [ # # ]: 0 : if (dev == NULL) {
716 : 0 : GPU_LOG(ERR, "cpu_unmap mem for invalid device ID %d", dev_id);
717 : 0 : rte_errno = ENODEV;
718 : 0 : return -rte_errno;
719 : : }
720 : :
721 [ # # ]: 0 : if (dev->ops.mem_cpu_unmap == NULL) {
722 : 0 : rte_errno = ENOTSUP;
723 : 0 : return -rte_errno;
724 : : }
725 : :
726 [ # # ]: 0 : if (ptr == NULL) /* dry-run */
727 : : return 0;
728 : :
729 [ # # ]: 0 : return GPU_DRV_RET(dev->ops.mem_cpu_unmap(dev, ptr));
730 : : }
731 : :
732 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_wmb, 21.11)
733 : : int
734 : 0 : rte_gpu_wmb(int16_t dev_id)
735 : : {
736 : : struct rte_gpu *dev;
737 : :
738 : 0 : dev = gpu_get_by_id(dev_id);
739 [ # # ]: 0 : if (dev == NULL) {
740 : 0 : GPU_LOG(ERR, "memory barrier for invalid device ID %d", dev_id);
741 : 0 : rte_errno = ENODEV;
742 : 0 : return -rte_errno;
743 : : }
744 : :
745 [ # # ]: 0 : if (dev->ops.wmb == NULL) {
746 : 0 : rte_errno = ENOTSUP;
747 : 0 : return -rte_errno;
748 : : }
749 [ # # ]: 0 : return GPU_DRV_RET(dev->ops.wmb(dev));
750 : : }
751 : :
752 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_create_flag, 21.11)
753 : : int
754 : 0 : rte_gpu_comm_create_flag(uint16_t dev_id, struct rte_gpu_comm_flag *devflag,
755 : : enum rte_gpu_comm_flag_type mtype)
756 : : {
757 : : size_t flag_size;
758 : : int ret;
759 : :
760 [ # # ]: 0 : if (devflag == NULL) {
761 : 0 : rte_errno = EINVAL;
762 : 0 : return -rte_errno;
763 : : }
764 [ # # ]: 0 : if (mtype != RTE_GPU_COMM_FLAG_CPU) {
765 : 0 : rte_errno = EINVAL;
766 : 0 : return -rte_errno;
767 : : }
768 : :
769 : : flag_size = sizeof(uint32_t);
770 : :
771 : 0 : devflag->ptr = rte_zmalloc(NULL, flag_size, 0);
772 [ # # ]: 0 : if (devflag->ptr == NULL) {
773 : 0 : rte_errno = ENOMEM;
774 : 0 : return -rte_errno;
775 : : }
776 : :
777 : 0 : ret = rte_gpu_mem_register(dev_id, flag_size, devflag->ptr);
778 [ # # ]: 0 : if (ret < 0) {
779 : 0 : rte_errno = ENOMEM;
780 : 0 : return -rte_errno;
781 : : }
782 : :
783 : 0 : devflag->mtype = mtype;
784 : 0 : devflag->dev_id = dev_id;
785 : :
786 : 0 : return 0;
787 : : }
788 : :
789 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_destroy_flag, 21.11)
790 : : int
791 : 0 : rte_gpu_comm_destroy_flag(struct rte_gpu_comm_flag *devflag)
792 : : {
793 : : int ret;
794 : :
795 [ # # ]: 0 : if (devflag == NULL) {
796 : 0 : rte_errno = EINVAL;
797 : 0 : return -rte_errno;
798 : : }
799 : :
800 : 0 : ret = rte_gpu_mem_unregister(devflag->dev_id, devflag->ptr);
801 [ # # ]: 0 : if (ret < 0) {
802 : 0 : rte_errno = EINVAL;
803 : 0 : return -1;
804 : : }
805 : :
806 : 0 : rte_free(devflag->ptr);
807 : :
808 : 0 : return 0;
809 : : }
810 : :
811 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_set_flag, 21.11)
812 : : int
813 : 0 : rte_gpu_comm_set_flag(struct rte_gpu_comm_flag *devflag, uint32_t val)
814 : : {
815 [ # # ]: 0 : if (devflag == NULL) {
816 : 0 : rte_errno = EINVAL;
817 : 0 : return -rte_errno;
818 : : }
819 : :
820 [ # # ]: 0 : if (devflag->mtype != RTE_GPU_COMM_FLAG_CPU) {
821 : 0 : rte_errno = EINVAL;
822 : 0 : return -rte_errno;
823 : : }
824 : :
825 : 0 : RTE_GPU_VOLATILE(*devflag->ptr) = val;
826 : :
827 : 0 : return 0;
828 : : }
829 : :
830 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_get_flag_value, 21.11)
831 : : int
832 : 0 : rte_gpu_comm_get_flag_value(struct rte_gpu_comm_flag *devflag, uint32_t *val)
833 : : {
834 [ # # ]: 0 : if (devflag == NULL) {
835 : 0 : rte_errno = EINVAL;
836 : 0 : return -rte_errno;
837 : : }
838 [ # # ]: 0 : if (devflag->mtype != RTE_GPU_COMM_FLAG_CPU) {
839 : 0 : rte_errno = EINVAL;
840 : 0 : return -rte_errno;
841 : : }
842 : :
843 : 0 : *val = RTE_GPU_VOLATILE(*devflag->ptr);
844 : :
845 : 0 : return 0;
846 : : }
847 : :
848 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_create_list, 21.11)
849 : : struct rte_gpu_comm_list *
850 : 0 : rte_gpu_comm_create_list(uint16_t dev_id,
851 : : uint32_t num_comm_items)
852 : : {
853 : : struct rte_gpu_comm_list *comm_list;
854 : : uint32_t idx_l;
855 : : int ret;
856 : : struct rte_gpu *dev;
857 : : struct rte_gpu_info info;
858 : :
859 [ # # ]: 0 : if (num_comm_items == 0) {
860 : 0 : rte_errno = EINVAL;
861 : 0 : return NULL;
862 : : }
863 : :
864 : 0 : dev = gpu_get_by_id(dev_id);
865 [ # # ]: 0 : if (dev == NULL) {
866 : 0 : GPU_LOG(ERR, "memory barrier for invalid device ID %d", dev_id);
867 : 0 : rte_errno = ENODEV;
868 : 0 : return NULL;
869 : : }
870 : :
871 : 0 : ret = rte_gpu_info_get(dev_id, &info);
872 [ # # ]: 0 : if (ret < 0) {
873 : 0 : rte_errno = ENODEV;
874 : 0 : return NULL;
875 : : }
876 : :
877 : 0 : comm_list = rte_zmalloc(NULL,
878 : : sizeof(struct rte_gpu_comm_list) * num_comm_items, 0);
879 [ # # ]: 0 : if (comm_list == NULL) {
880 : 0 : rte_errno = ENOMEM;
881 : 0 : return NULL;
882 : : }
883 : :
884 : 0 : ret = rte_gpu_mem_register(dev_id,
885 : : sizeof(struct rte_gpu_comm_list) * num_comm_items, comm_list);
886 [ # # ]: 0 : if (ret < 0) {
887 : 0 : rte_errno = ENOMEM;
888 : 0 : return NULL;
889 : : }
890 : :
891 : : /*
892 : : * Use GPU memory CPU map feature if enabled in the driver
893 : : * to allocate the status flags of the list.
894 : : * Allocating this flag in GPU memory will reduce
895 : : * the latency when GPU workload is polling this flag.
896 : : */
897 : 0 : comm_list[0].status_d = rte_gpu_mem_alloc(dev_id,
898 : : sizeof(enum rte_gpu_comm_list_status) * num_comm_items,
899 : 0 : info.page_size);
900 : : if (ret < 0) {
901 : : rte_errno = ENOMEM;
902 : : return NULL;
903 : : }
904 : :
905 : 0 : comm_list[0].status_h = rte_gpu_mem_cpu_map(dev_id,
906 : : sizeof(enum rte_gpu_comm_list_status) * num_comm_items,
907 : : comm_list[0].status_d);
908 [ # # ]: 0 : if (comm_list[0].status_h == NULL) {
909 : : /*
910 : : * If CPU mapping is not supported by driver
911 : : * use regular CPU registered memory.
912 : : */
913 : 0 : comm_list[0].status_h = rte_zmalloc(NULL,
914 : : sizeof(enum rte_gpu_comm_list_status) * num_comm_items, 0);
915 [ # # ]: 0 : if (comm_list[0].status_h == NULL) {
916 : 0 : rte_errno = ENOMEM;
917 : 0 : return NULL;
918 : : }
919 : :
920 : 0 : ret = rte_gpu_mem_register(dev_id,
921 : : sizeof(enum rte_gpu_comm_list_status) * num_comm_items,
922 : : comm_list[0].status_h);
923 [ # # ]: 0 : if (ret < 0) {
924 : 0 : rte_errno = ENOMEM;
925 : 0 : return NULL;
926 : : }
927 : :
928 : 0 : comm_list[0].status_d = comm_list[0].status_h;
929 : : }
930 : :
931 [ # # ]: 0 : for (idx_l = 0; idx_l < num_comm_items; idx_l++) {
932 : 0 : comm_list[idx_l].pkt_list = rte_zmalloc(NULL,
933 : : sizeof(struct rte_gpu_comm_pkt) * RTE_GPU_COMM_LIST_PKTS_MAX, 0);
934 [ # # ]: 0 : if (comm_list[idx_l].pkt_list == NULL) {
935 : 0 : rte_errno = ENOMEM;
936 : 0 : return NULL;
937 : : }
938 : :
939 : 0 : ret = rte_gpu_mem_register(dev_id,
940 : : sizeof(struct rte_gpu_comm_pkt) * RTE_GPU_COMM_LIST_PKTS_MAX,
941 : : comm_list[idx_l].pkt_list);
942 [ # # ]: 0 : if (ret < 0) {
943 : 0 : rte_errno = ENOMEM;
944 : 0 : return NULL;
945 : : }
946 : :
947 : 0 : comm_list[idx_l].num_pkts = 0;
948 : 0 : comm_list[idx_l].dev_id = dev_id;
949 : :
950 : 0 : comm_list[idx_l].mbufs = rte_zmalloc(NULL,
951 : : sizeof(struct rte_mbuf *) * RTE_GPU_COMM_LIST_PKTS_MAX, 0);
952 [ # # ]: 0 : if (comm_list[idx_l].mbufs == NULL) {
953 : 0 : rte_errno = ENOMEM;
954 : 0 : return NULL;
955 : : }
956 : :
957 [ # # ]: 0 : if (idx_l > 0) {
958 : 0 : comm_list[idx_l].status_h = &(comm_list[0].status_h[idx_l]);
959 : 0 : comm_list[idx_l].status_d = &(comm_list[0].status_d[idx_l]);
960 : :
961 : 0 : ret = rte_gpu_comm_set_status(&comm_list[idx_l], RTE_GPU_COMM_LIST_FREE);
962 [ # # ]: 0 : if (ret < 0) {
963 : 0 : rte_errno = ENOMEM;
964 : 0 : return NULL;
965 : : }
966 : : }
967 : : }
968 : :
969 : : return comm_list;
970 : : }
971 : :
972 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_destroy_list, 21.11)
973 : : int
974 : 0 : rte_gpu_comm_destroy_list(struct rte_gpu_comm_list *comm_list,
975 : : uint32_t num_comm_items)
976 : : {
977 : : uint32_t idx_l;
978 : : int ret;
979 : : uint16_t dev_id;
980 : :
981 [ # # ]: 0 : if (comm_list == NULL) {
982 : 0 : rte_errno = EINVAL;
983 : 0 : return -rte_errno;
984 : : }
985 : :
986 : 0 : dev_id = comm_list[0].dev_id;
987 : :
988 [ # # ]: 0 : for (idx_l = 0; idx_l < num_comm_items; idx_l++) {
989 : 0 : ret = rte_gpu_mem_unregister(dev_id, comm_list[idx_l].pkt_list);
990 [ # # ]: 0 : if (ret < 0) {
991 : 0 : rte_errno = EINVAL;
992 : 0 : return -1;
993 : : }
994 : :
995 : 0 : rte_free(comm_list[idx_l].pkt_list);
996 : 0 : rte_free(comm_list[idx_l].mbufs);
997 : : }
998 : :
999 : 0 : ret = rte_gpu_mem_unregister(dev_id, comm_list);
1000 [ # # ]: 0 : if (ret < 0) {
1001 : 0 : rte_errno = EINVAL;
1002 : 0 : return -1;
1003 : : }
1004 : :
1005 : 0 : ret = rte_gpu_mem_cpu_unmap(dev_id, comm_list[0].status_d);
1006 [ # # ]: 0 : if (ret == 0) {
1007 : 0 : rte_gpu_mem_free(dev_id, comm_list[0].status_d);
1008 : : } else {
1009 : 0 : rte_gpu_mem_unregister(dev_id, comm_list[0].status_h);
1010 : 0 : rte_free(comm_list[0].status_h);
1011 : : }
1012 : :
1013 : 0 : rte_free(comm_list);
1014 : :
1015 : 0 : return 0;
1016 : : }
1017 : :
1018 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_populate_list_pkts, 21.11)
1019 : : int
1020 : 0 : rte_gpu_comm_populate_list_pkts(struct rte_gpu_comm_list *comm_list_item,
1021 : : struct rte_mbuf **mbufs, uint32_t num_mbufs)
1022 : : {
1023 : : uint32_t idx;
1024 : : int ret;
1025 : :
1026 [ # # # # ]: 0 : if (comm_list_item == NULL || comm_list_item->pkt_list == NULL ||
1027 [ # # ]: 0 : mbufs == NULL || num_mbufs > RTE_GPU_COMM_LIST_PKTS_MAX) {
1028 : 0 : rte_errno = EINVAL;
1029 : 0 : return -rte_errno;
1030 : : }
1031 : :
1032 [ # # ]: 0 : for (idx = 0; idx < num_mbufs; idx++) {
1033 : : /* support only unchained mbufs */
1034 [ # # # # : 0 : if (unlikely((mbufs[idx]->nb_segs > 1) ||
# # ]
1035 : : (mbufs[idx]->next != NULL) ||
1036 : : (mbufs[idx]->data_len != mbufs[idx]->pkt_len))) {
1037 : 0 : rte_errno = ENOTSUP;
1038 : 0 : return -rte_errno;
1039 : : }
1040 : 0 : comm_list_item->pkt_list[idx].addr =
1041 : 0 : rte_pktmbuf_mtod_offset(mbufs[idx], uintptr_t, 0);
1042 : 0 : comm_list_item->pkt_list[idx].size = mbufs[idx]->pkt_len;
1043 : 0 : comm_list_item->mbufs[idx] = mbufs[idx];
1044 : : }
1045 : :
1046 : 0 : RTE_GPU_VOLATILE(comm_list_item->num_pkts) = num_mbufs;
1047 : 0 : rte_gpu_wmb(comm_list_item->dev_id);
1048 : 0 : ret = rte_gpu_comm_set_status(comm_list_item, RTE_GPU_COMM_LIST_READY);
1049 [ # # ]: 0 : if (ret < 0) {
1050 : 0 : rte_errno = EINVAL;
1051 : 0 : return -rte_errno;
1052 : : }
1053 : :
1054 : : return 0;
1055 : : }
1056 : :
1057 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_set_status, 21.11)
1058 : : int
1059 : 0 : rte_gpu_comm_set_status(struct rte_gpu_comm_list *comm_list_item,
1060 : : enum rte_gpu_comm_list_status status)
1061 : : {
1062 [ # # ]: 0 : if (comm_list_item == NULL) {
1063 : 0 : rte_errno = EINVAL;
1064 : 0 : return -rte_errno;
1065 : : }
1066 : :
1067 : 0 : RTE_GPU_VOLATILE(comm_list_item->status_h[0]) = status;
1068 : :
1069 : 0 : return 0;
1070 : : }
1071 : :
1072 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_get_status, 21.11)
1073 : : int
1074 : 0 : rte_gpu_comm_get_status(struct rte_gpu_comm_list *comm_list_item,
1075 : : enum rte_gpu_comm_list_status *status)
1076 : : {
1077 [ # # ]: 0 : if (comm_list_item == NULL || status == NULL) {
1078 : 0 : rte_errno = EINVAL;
1079 : 0 : return -rte_errno;
1080 : : }
1081 : :
1082 : 0 : *status = RTE_GPU_VOLATILE(comm_list_item->status_h[0]);
1083 : :
1084 : 0 : return 0;
1085 : : }
1086 : :
1087 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_gpu_comm_cleanup_list, 21.11)
1088 : : int
1089 : 0 : rte_gpu_comm_cleanup_list(struct rte_gpu_comm_list *comm_list_item)
1090 : : {
1091 : : uint32_t idx = 0;
1092 : : enum rte_gpu_comm_list_status status;
1093 : : int ret;
1094 : :
1095 [ # # ]: 0 : if (comm_list_item == NULL) {
1096 : 0 : rte_errno = EINVAL;
1097 : 0 : return -rte_errno;
1098 : : }
1099 : :
1100 : 0 : ret = rte_gpu_comm_get_status(comm_list_item, &status);
1101 [ # # ]: 0 : if (ret < 0) {
1102 : 0 : rte_errno = EINVAL;
1103 : 0 : return -rte_errno;
1104 : : }
1105 : :
1106 [ # # ]: 0 : if (status == RTE_GPU_COMM_LIST_READY) {
1107 : 0 : GPU_LOG(ERR, "packet list is still in progress");
1108 : 0 : rte_errno = EINVAL;
1109 : 0 : return -rte_errno;
1110 : : }
1111 : :
1112 [ # # ]: 0 : for (idx = 0; idx < RTE_GPU_COMM_LIST_PKTS_MAX; idx++) {
1113 [ # # ]: 0 : if (comm_list_item->pkt_list[idx].addr == 0)
1114 : : break;
1115 : :
1116 : 0 : comm_list_item->pkt_list[idx].addr = 0;
1117 : 0 : comm_list_item->pkt_list[idx].size = 0;
1118 : 0 : comm_list_item->mbufs[idx] = NULL;
1119 : : }
1120 : :
1121 : 0 : ret = rte_gpu_comm_set_status(comm_list_item, RTE_GPU_COMM_LIST_FREE);
1122 [ # # ]: 0 : if (ret < 0) {
1123 : 0 : rte_errno = EINVAL;
1124 : 0 : return -rte_errno;
1125 : : }
1126 : 0 : RTE_GPU_VOLATILE(comm_list_item->num_pkts) = 0;
1127 : : rte_mb();
1128 : :
1129 : 0 : return 0;
1130 : : }
|