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