Bug Summary

File:home/bhubbard/working/src/ceph/src/spdk/dpdk/lib/librte_eal/common/eal_common_dev.c
Warning:line 480, column 3
Value stored to 'ret' is never read

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation.
3 * Copyright(c) 2014 6WIND S.A.
4 */
5
6#include <stdio.h>
7#include <string.h>
8#include <inttypes.h>
9#include <sys/queue.h>
10
11#include <rte_compat.h>
12#include <rte_bus.h>
13#include <rte_class.h>
14#include <rte_dev.h>
15#include <rte_devargs.h>
16#include <rte_debug.h>
17#include <rte_errno(per_lcore__rte_errno).h>
18#include <rte_kvargs.h>
19#include <rte_log.h>
20#include <rte_spinlock.h>
21#include <rte_malloc.h>
22#include <rte_string_fns.h>
23
24#include "eal_private.h"
25#include "hotplug_mp.h"
26
27/**
28 * The device event callback description.
29 *
30 * It contains callback address to be registered by user application,
31 * the pointer to the parameters for callback, and the device name.
32 */
33struct dev_event_callback {
34 TAILQ_ENTRY(dev_event_callback)struct { struct dev_event_callback *tqe_next; struct dev_event_callback
* *tqe_prev; }
next; /**< Callbacks list */
35 rte_dev_event_cb_fn cb_fn; /**< Callback address */
36 void *cb_arg; /**< Callback parameter */
37 char *dev_name; /**< Callback device name, NULL is for all device */
38 uint32_t active; /**< Callback is executing */
39};
40
41/** @internal Structure to keep track of registered callbacks */
42TAILQ_HEAD(dev_event_cb_list, dev_event_callback)struct dev_event_cb_list { struct dev_event_callback *tqh_first
; struct dev_event_callback * *tqh_last; }
;
43
44/* The device event callback list for all registered callbacks. */
45static struct dev_event_cb_list dev_event_cbs;
46
47/* spinlock for device callbacks */
48static rte_spinlock_t dev_event_lock = RTE_SPINLOCK_INITIALIZER{ 0 };
49
50struct dev_next_ctx {
51 struct rte_dev_iterator *it;
52 const char *bus_str;
53 const char *cls_str;
54};
55
56#define CTX(it, bus_str, cls_str)(&(const struct dev_next_ctx){ .it = it, .bus_str = bus_str
, .cls_str = cls_str, })
\
57 (&(const struct dev_next_ctx){ \
58 .it = it, \
59 .bus_str = bus_str, \
60 .cls_str = cls_str, \
61 })
62
63#define ITCTX(ptr)(((struct dev_next_ctx *)(intptr_t)ptr)->it) \
64 (((struct dev_next_ctx *)(intptr_t)ptr)->it)
65
66#define BUSCTX(ptr)(((struct dev_next_ctx *)(intptr_t)ptr)->bus_str) \
67 (((struct dev_next_ctx *)(intptr_t)ptr)->bus_str)
68
69#define CLSCTX(ptr)(((struct dev_next_ctx *)(intptr_t)ptr)->cls_str) \
70 (((struct dev_next_ctx *)(intptr_t)ptr)->cls_str)
71
72static int cmp_dev_name(const struct rte_device *dev, const void *_name)
73{
74 const char *name = _name;
75
76 return strcmp(dev->name, name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(dev->name) && __builtin_constant_p (name) &&
(__s1_len = __builtin_strlen (dev->name), __s2_len = __builtin_strlen
(name), (!((size_t)(const void *)((dev->name) + 1) - (size_t
)(const void *)(dev->name) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((name) + 1) - (size_t)(const void *
)(name) == 1) || __s2_len >= 4)) ? __builtin_strcmp (dev->
name, name) : (__builtin_constant_p (dev->name) &&
((size_t)(const void *)((dev->name) + 1) - (size_t)(const
void *)(dev->name) == 1) && (__s1_len = __builtin_strlen
(dev->name), __s1_len < 4) ? (__builtin_constant_p (name
) && ((size_t)(const void *)((name) + 1) - (size_t)(const
void *)(name) == 1) ? __builtin_strcmp (dev->name, name) :
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (name); int __result = (((const unsigned
char *) (const char *) (dev->name))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (dev->name))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (dev->name))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (dev->name))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p (name) && ((size_t)(const
void *)((name) + 1) - (size_t)(const void *)(name) == 1) &&
(__s2_len = __builtin_strlen (name), __s2_len < 4) ? (__builtin_constant_p
(dev->name) && ((size_t)(const void *)((dev->name
) + 1) - (size_t)(const void *)(dev->name) == 1) ? __builtin_strcmp
(dev->name, name) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (dev->name
); int __result = (((const unsigned char *) (const char *) (name
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (name
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (name
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (name))
[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (dev->
name, name)))); })
;
77}
78
79int
80rte_dev_is_probed(const struct rte_device *dev)
81{
82 /* The field driver should be set only when the probe is successful. */
83 return dev->driver != NULL((void*)0);
84}
85
86/* helper function to build devargs, caller should free the memory */
87static int
88build_devargs(const char *busname, const char *devname,
89 const char *drvargs, char **devargs)
90{
91 int length;
92
93 length = snprintf(NULL((void*)0), 0, "%s:%s,%s", busname, devname, drvargs);
94 if (length < 0)
95 return -EINVAL22;
96
97 *devargs = malloc(length + 1);
98 if (*devargs == NULL((void*)0))
99 return -ENOMEM12;
100
101 length = snprintf(*devargs, length + 1, "%s:%s,%s",
102 busname, devname, drvargs);
103 if (length < 0) {
104 free(*devargs);
105 return -EINVAL22;
106 }
107
108 return 0;
109}
110
111int
112rte_eal_hotplug_add(const char *busname, const char *devname,
113 const char *drvargs)
114{
115
116 char *devargs;
117 int ret;
118
119 ret = build_devargs(busname, devname, drvargs, &devargs);
120 if (ret != 0)
121 return ret;
122
123 ret = rte_dev_probe(devargs);
124 free(devargs);
125
126 return ret;
127}
128
129/* probe device at local process. */
130int
131local_dev_probe(const char *devargs, struct rte_device **new_dev)
132{
133 struct rte_device *dev;
134 struct rte_devargs *da;
135 int ret;
136
137 *new_dev = NULL((void*)0);
138 da = calloc(1, sizeof(*da));
139 if (da == NULL((void*)0))
140 return -ENOMEM12;
141
142 ret = rte_devargs_parse(da, devargs);
143 if (ret)
144 goto err_devarg;
145
146 if (da->bus->plug == NULL((void*)0)) {
147 RTE_LOG(ERR, EAL, "Function plug not supported by bus (%s)\n",rte_log(4U, 0, "EAL" ": " "Function plug not supported by bus (%s)\n"
, da->bus->name)
148 da->bus->name)rte_log(4U, 0, "EAL" ": " "Function plug not supported by bus (%s)\n"
, da->bus->name)
;
149 ret = -ENOTSUP95;
150 goto err_devarg;
151 }
152
153 ret = rte_devargs_insert(&da);
154 if (ret)
155 goto err_devarg;
156
157 /* the rte_devargs will be referenced in the matching rte_device */
158 ret = da->bus->scan();
159 if (ret)
160 goto err_devarg;
161
162 dev = da->bus->find_device(NULL((void*)0), cmp_dev_name, da->name);
163 if (dev == NULL((void*)0)) {
164 RTE_LOG(ERR, EAL, "Cannot find device (%s)\n",rte_log(4U, 0, "EAL" ": " "Cannot find device (%s)\n", da->
name)
165 da->name)rte_log(4U, 0, "EAL" ": " "Cannot find device (%s)\n", da->
name)
;
166 ret = -ENODEV19;
167 goto err_devarg;
168 }
169 /* Since there is a matching device, it is now its responsibility
170 * to manage the devargs we've just inserted. From this point
171 * those devargs shouldn't be removed manually anymore.
172 */
173
174 ret = dev->bus->plug(dev);
175 if (ret && !rte_dev_is_probed(dev)) { /* if hasn't ever succeeded */
176 RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",rte_log(4U, 0, "EAL" ": " "Driver cannot attach the device (%s)\n"
, dev->name)
177 dev->name)rte_log(4U, 0, "EAL" ": " "Driver cannot attach the device (%s)\n"
, dev->name)
;
178 return ret;
179 }
180
181 *new_dev = dev;
182 return ret;
183
184err_devarg:
185 if (rte_devargs_remove(da) != 0) {
186 free(da->args);
187 free(da);
188 }
189 return ret;
190}
191
192int
193rte_dev_probe(const char *devargs)
194{
195 struct eal_dev_mp_req req;
196 struct rte_device *dev;
197 int ret;
198
199 memset(&req, 0, sizeof(req));
200 req.t = EAL_DEV_REQ_TYPE_ATTACH;
201 strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN)rte_strlcpy(req.devargs, devargs, 128);
202
203 if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
204 /**
205 * If in secondary process, just send IPC request to
206 * primary process.
207 */
208 ret = eal_dev_hotplug_request_to_primary(&req);
209 if (ret != 0) {
210 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to send hotplug request to primary\n"
)
211 "Failed to send hotplug request to primary\n")rte_log(4U, 0, "EAL" ": " "Failed to send hotplug request to primary\n"
)
;
212 return -ENOMSG42;
213 }
214 if (req.result != 0)
215 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to hotplug add device\n")
216 "Failed to hotplug add device\n")rte_log(4U, 0, "EAL" ": " "Failed to hotplug add device\n");
217 return req.result;
218 }
219
220 /* attach a shared device from primary start from here: */
221
222 /* primary attach the new device itself. */
223 ret = local_dev_probe(devargs, &dev);
224
225 if (ret != 0) {
226 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to attach device on primary process\n"
)
227 "Failed to attach device on primary process\n")rte_log(4U, 0, "EAL" ": " "Failed to attach device on primary process\n"
)
;
228
229 /**
230 * it is possible that secondary process failed to attached a
231 * device that primary process have during initialization,
232 * so for -EEXIST case, we still need to sync with secondary
233 * process.
234 */
235 if (ret != -EEXIST17)
236 return ret;
237 }
238
239 /* primary send attach sync request to secondary. */
240 ret = eal_dev_hotplug_request_to_secondary(&req);
241
242 /* if any communication error, we need to rollback. */
243 if (ret != 0) {
244 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to send hotplug add request to secondary\n"
)
245 "Failed to send hotplug add request to secondary\n")rte_log(4U, 0, "EAL" ": " "Failed to send hotplug add request to secondary\n"
)
;
246 ret = -ENOMSG42;
247 goto rollback;
248 }
249
250 /**
251 * if any secondary failed to attach, we need to consider if rollback
252 * is necessary.
253 */
254 if (req.result != 0) {
255 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to attach device on secondary process\n"
)
256 "Failed to attach device on secondary process\n")rte_log(4U, 0, "EAL" ": " "Failed to attach device on secondary process\n"
)
;
257 ret = req.result;
258
259 /* for -EEXIST, we don't need to rollback. */
260 if (ret == -EEXIST17)
261 return ret;
262 goto rollback;
263 }
264
265 return 0;
266
267rollback:
268 req.t = EAL_DEV_REQ_TYPE_ATTACH_ROLLBACK;
269
270 /* primary send rollback request to secondary. */
271 if (eal_dev_hotplug_request_to_secondary(&req) != 0)
272 RTE_LOG(WARNING, EAL,rte_log(5U, 0, "EAL" ": " "Failed to rollback device attach on secondary."
"Devices in secondary may not sync with primary\n")
273 "Failed to rollback device attach on secondary."rte_log(5U, 0, "EAL" ": " "Failed to rollback device attach on secondary."
"Devices in secondary may not sync with primary\n")
274 "Devices in secondary may not sync with primary\n")rte_log(5U, 0, "EAL" ": " "Failed to rollback device attach on secondary."
"Devices in secondary may not sync with primary\n")
;
275
276 /* primary rollback itself. */
277 if (local_dev_remove(dev) != 0)
278 RTE_LOG(WARNING, EAL,rte_log(5U, 0, "EAL" ": " "Failed to rollback device attach on primary."
"Devices in secondary may not sync with primary\n")
279 "Failed to rollback device attach on primary."rte_log(5U, 0, "EAL" ": " "Failed to rollback device attach on primary."
"Devices in secondary may not sync with primary\n")
280 "Devices in secondary may not sync with primary\n")rte_log(5U, 0, "EAL" ": " "Failed to rollback device attach on primary."
"Devices in secondary may not sync with primary\n")
;
281
282 return ret;
283}
284
285int
286rte_eal_hotplug_remove(const char *busname, const char *devname)
287{
288 struct rte_device *dev;
289 struct rte_bus *bus;
290
291 bus = rte_bus_find_by_name(busname);
292 if (bus == NULL((void*)0)) {
293 RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", busname)rte_log(4U, 0, "EAL" ": " "Cannot find bus (%s)\n", busname);
294 return -ENOENT2;
295 }
296
297 dev = bus->find_device(NULL((void*)0), cmp_dev_name, devname);
298 if (dev == NULL((void*)0)) {
299 RTE_LOG(ERR, EAL, "Cannot find plugged device (%s)\n", devname)rte_log(4U, 0, "EAL" ": " "Cannot find plugged device (%s)\n"
, devname)
;
300 return -EINVAL22;
301 }
302
303 return rte_dev_remove(dev);
304}
305
306/* remove device at local process. */
307int
308local_dev_remove(struct rte_device *dev)
309{
310 int ret;
311
312 if (dev->bus->unplug == NULL((void*)0)) {
313 RTE_LOG(ERR, EAL, "Function unplug not supported by bus (%s)\n",rte_log(4U, 0, "EAL" ": " "Function unplug not supported by bus (%s)\n"
, dev->bus->name)
314 dev->bus->name)rte_log(4U, 0, "EAL" ": " "Function unplug not supported by bus (%s)\n"
, dev->bus->name)
;
315 return -ENOTSUP95;
316 }
317
318 ret = dev->bus->unplug(dev);
319 if (ret) {
320 RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",rte_log(4U, 0, "EAL" ": " "Driver cannot detach the device (%s)\n"
, dev->name)
321 dev->name)rte_log(4U, 0, "EAL" ": " "Driver cannot detach the device (%s)\n"
, dev->name)
;
322 return ret;
323 }
324
325 return 0;
326}
327
328int
329rte_dev_remove(struct rte_device *dev)
330{
331 struct eal_dev_mp_req req;
332 char *devargs;
333 int ret;
334
335 if (!rte_dev_is_probed(dev)) {
336 RTE_LOG(ERR, EAL, "Device is not probed\n")rte_log(4U, 0, "EAL" ": " "Device is not probed\n");
337 return -ENOENT2;
338 }
339
340 ret = build_devargs(dev->bus->name, dev->name, "", &devargs);
341 if (ret != 0)
342 return ret;
343
344 memset(&req, 0, sizeof(req));
345 req.t = EAL_DEV_REQ_TYPE_DETACH;
346 strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN)rte_strlcpy(req.devargs, devargs, 128);
347 free(devargs);
348
349 if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
350 /**
351 * If in secondary process, just send IPC request to
352 * primary process.
353 */
354 ret = eal_dev_hotplug_request_to_primary(&req);
355 if (ret != 0) {
356 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to send hotplug request to primary\n"
)
357 "Failed to send hotplug request to primary\n")rte_log(4U, 0, "EAL" ": " "Failed to send hotplug request to primary\n"
)
;
358 return -ENOMSG42;
359 }
360 if (req.result != 0)
361 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to hotplug remove device\n"
)
362 "Failed to hotplug remove device\n")rte_log(4U, 0, "EAL" ": " "Failed to hotplug remove device\n"
)
;
363 return req.result;
364 }
365
366 /* detach a device from primary start from here: */
367
368 /* primary send detach sync request to secondary */
369 ret = eal_dev_hotplug_request_to_secondary(&req);
370
371 /**
372 * if communication error, we need to rollback, because it is possible
373 * part of the secondary processes still detached it successfully.
374 */
375 if (ret != 0) {
376 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to send device detach request to secondary\n"
)
377 "Failed to send device detach request to secondary\n")rte_log(4U, 0, "EAL" ": " "Failed to send device detach request to secondary\n"
)
;
378 ret = -ENOMSG42;
379 goto rollback;
380 }
381
382 /**
383 * if any secondary failed to detach, we need to consider if rollback
384 * is necessary.
385 */
386 if (req.result != 0) {
387 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to detach device on secondary process\n"
)
388 "Failed to detach device on secondary process\n")rte_log(4U, 0, "EAL" ": " "Failed to detach device on secondary process\n"
)
;
389 ret = req.result;
390 /**
391 * if -ENOENT, we don't need to rollback, since devices is
392 * already detached on secondary process.
393 */
394 if (ret != -ENOENT2)
395 goto rollback;
396 }
397
398 /* primary detach the device itself. */
399 ret = local_dev_remove(dev);
400
401 /* if primary failed, still need to consider if rollback is necessary */
402 if (ret != 0) {
403 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to detach device on primary process\n"
)
404 "Failed to detach device on primary process\n")rte_log(4U, 0, "EAL" ": " "Failed to detach device on primary process\n"
)
;
405 /* if -ENOENT, we don't need to rollback */
406 if (ret == -ENOENT2)
407 return ret;
408 goto rollback;
409 }
410
411 return 0;
412
413rollback:
414 req.t = EAL_DEV_REQ_TYPE_DETACH_ROLLBACK;
415
416 /* primary send rollback request to secondary. */
417 if (eal_dev_hotplug_request_to_secondary(&req) != 0)
418 RTE_LOG(WARNING, EAL,rte_log(5U, 0, "EAL" ": " "Failed to rollback device detach on secondary."
"Devices in secondary may not sync with primary\n")
419 "Failed to rollback device detach on secondary."rte_log(5U, 0, "EAL" ": " "Failed to rollback device detach on secondary."
"Devices in secondary may not sync with primary\n")
420 "Devices in secondary may not sync with primary\n")rte_log(5U, 0, "EAL" ": " "Failed to rollback device detach on secondary."
"Devices in secondary may not sync with primary\n")
;
421
422 return ret;
423}
424
425int __rte_experimental__attribute__((section(".text.experimental")))
426rte_dev_event_callback_register(const char *device_name,
427 rte_dev_event_cb_fn cb_fn,
428 void *cb_arg)
429{
430 struct dev_event_callback *event_cb;
431 int ret;
432
433 if (!cb_fn)
434 return -EINVAL22;
435
436 rte_spinlock_lock(&dev_event_lock);
437
438 if (TAILQ_EMPTY(&dev_event_cbs)((&dev_event_cbs)->tqh_first == ((void*)0)))
439 TAILQ_INIT(&dev_event_cbs)do { (&dev_event_cbs)->tqh_first = ((void*)0); (&dev_event_cbs
)->tqh_last = &(&dev_event_cbs)->tqh_first; } while
( 0)
;
440
441 TAILQ_FOREACH(event_cb, &dev_event_cbs, next)for ((event_cb) = ((&dev_event_cbs)->tqh_first); (event_cb
); (event_cb) = ((event_cb)->next.tqe_next))
{
442 if (event_cb->cb_fn == cb_fn && event_cb->cb_arg == cb_arg) {
443 if (device_name == NULL((void*)0) && event_cb->dev_name == NULL((void*)0))
444 break;
445 if (device_name == NULL((void*)0) || event_cb->dev_name == NULL((void*)0))
446 continue;
447 if (!strcmp(event_cb->dev_name, device_name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(event_cb->dev_name) && __builtin_constant_p (device_name
) && (__s1_len = __builtin_strlen (event_cb->dev_name
), __s2_len = __builtin_strlen (device_name), (!((size_t)(const
void *)((event_cb->dev_name) + 1) - (size_t)(const void *
)(event_cb->dev_name) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((device_name) + 1) - (size_t)(const
void *)(device_name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(event_cb->dev_name, device_name) : (__builtin_constant_p
(event_cb->dev_name) && ((size_t)(const void *)((
event_cb->dev_name) + 1) - (size_t)(const void *)(event_cb
->dev_name) == 1) && (__s1_len = __builtin_strlen (
event_cb->dev_name), __s1_len < 4) ? (__builtin_constant_p
(device_name) && ((size_t)(const void *)((device_name
) + 1) - (size_t)(const void *)(device_name) == 1) ? __builtin_strcmp
(event_cb->dev_name, device_name) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(device_name); int __result = (((const unsigned char *) (const
char *) (event_cb->dev_name))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (event_cb->dev_name))[1] - __s2[1]
); if (__s1_len > 1 && __result == 0) { __result =
(((const unsigned char *) (const char *) (event_cb->dev_name
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (event_cb
->dev_name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(device_name) && ((size_t)(const void *)((device_name
) + 1) - (size_t)(const void *)(device_name) == 1) &&
(__s2_len = __builtin_strlen (device_name), __s2_len < 4)
? (__builtin_constant_p (event_cb->dev_name) && (
(size_t)(const void *)((event_cb->dev_name) + 1) - (size_t
)(const void *)(event_cb->dev_name) == 1) ? __builtin_strcmp
(event_cb->dev_name, device_name) : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(event_cb->dev_name); int __result = (((const unsigned char
*) (const char *) (device_name))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (device_name))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (device_name))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (device_name))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (event_cb->dev_name, device_name
)))); })
)
448 break;
449 }
450 }
451
452 /* create a new callback. */
453 if (event_cb == NULL((void*)0)) {
454 event_cb = malloc(sizeof(struct dev_event_callback));
455 if (event_cb != NULL((void*)0)) {
456 event_cb->cb_fn = cb_fn;
457 event_cb->cb_arg = cb_arg;
458 event_cb->active = 0;
459 if (!device_name) {
460 event_cb->dev_name = NULL((void*)0);
461 } else {
462 event_cb->dev_name = strdup(device_name)(__extension__ (__builtin_constant_p (device_name) &&
((size_t)(const void *)((device_name) + 1) - (size_t)(const void
*)(device_name) == 1) ? (((const char *) (device_name))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (device_name) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, device_name, __len); __retval; })) : __strdup (device_name
)))
;
463 if (event_cb->dev_name == NULL((void*)0)) {
464 ret = -ENOMEM12;
465 goto error;
466 }
467 }
468 TAILQ_INSERT_TAIL(&dev_event_cbs, event_cb, next)do { (event_cb)->next.tqe_next = ((void*)0); (event_cb)->
next.tqe_prev = (&dev_event_cbs)->tqh_last; *(&dev_event_cbs
)->tqh_last = (event_cb); (&dev_event_cbs)->tqh_last
= &(event_cb)->next.tqe_next; } while ( 0)
;
469 } else {
470 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Failed to allocate memory for device "
"event callback.")
471 "Failed to allocate memory for device "rte_log(4U, 0, "EAL" ": " "Failed to allocate memory for device "
"event callback.")
472 "event callback.")rte_log(4U, 0, "EAL" ": " "Failed to allocate memory for device "
"event callback.")
;
473 ret = -ENOMEM12;
474 goto error;
475 }
476 } else {
477 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "The callback is already exist, no need "
"to register again.\n")
478 "The callback is already exist, no need "rte_log(4U, 0, "EAL" ": " "The callback is already exist, no need "
"to register again.\n")
479 "to register again.\n")rte_log(4U, 0, "EAL" ": " "The callback is already exist, no need "
"to register again.\n")
;
480 ret = -EEXIST17;
Value stored to 'ret' is never read
481 }
482
483 rte_spinlock_unlock(&dev_event_lock);
484 return 0;
485error:
486 free(event_cb);
487 rte_spinlock_unlock(&dev_event_lock);
488 return ret;
489}
490
491int __rte_experimental__attribute__((section(".text.experimental")))
492rte_dev_event_callback_unregister(const char *device_name,
493 rte_dev_event_cb_fn cb_fn,
494 void *cb_arg)
495{
496 int ret = 0;
497 struct dev_event_callback *event_cb, *next;
498
499 if (!cb_fn)
500 return -EINVAL22;
501
502 rte_spinlock_lock(&dev_event_lock);
503 /*walk through the callbacks and remove all that match. */
504 for (event_cb = TAILQ_FIRST(&dev_event_cbs)((&dev_event_cbs)->tqh_first); event_cb != NULL((void*)0);
505 event_cb = next) {
506
507 next = TAILQ_NEXT(event_cb, next)((event_cb)->next.tqe_next);
508
509 if (device_name != NULL((void*)0) && event_cb->dev_name != NULL((void*)0)) {
510 if (!strcmp(event_cb->dev_name, device_name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(event_cb->dev_name) && __builtin_constant_p (device_name
) && (__s1_len = __builtin_strlen (event_cb->dev_name
), __s2_len = __builtin_strlen (device_name), (!((size_t)(const
void *)((event_cb->dev_name) + 1) - (size_t)(const void *
)(event_cb->dev_name) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((device_name) + 1) - (size_t)(const
void *)(device_name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(event_cb->dev_name, device_name) : (__builtin_constant_p
(event_cb->dev_name) && ((size_t)(const void *)((
event_cb->dev_name) + 1) - (size_t)(const void *)(event_cb
->dev_name) == 1) && (__s1_len = __builtin_strlen (
event_cb->dev_name), __s1_len < 4) ? (__builtin_constant_p
(device_name) && ((size_t)(const void *)((device_name
) + 1) - (size_t)(const void *)(device_name) == 1) ? __builtin_strcmp
(event_cb->dev_name, device_name) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(device_name); int __result = (((const unsigned char *) (const
char *) (event_cb->dev_name))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (event_cb->dev_name))[1] - __s2[1]
); if (__s1_len > 1 && __result == 0) { __result =
(((const unsigned char *) (const char *) (event_cb->dev_name
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (event_cb
->dev_name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(device_name) && ((size_t)(const void *)((device_name
) + 1) - (size_t)(const void *)(device_name) == 1) &&
(__s2_len = __builtin_strlen (device_name), __s2_len < 4)
? (__builtin_constant_p (event_cb->dev_name) && (
(size_t)(const void *)((event_cb->dev_name) + 1) - (size_t
)(const void *)(event_cb->dev_name) == 1) ? __builtin_strcmp
(event_cb->dev_name, device_name) : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(event_cb->dev_name); int __result = (((const unsigned char
*) (const char *) (device_name))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (device_name))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (device_name))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (device_name))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (event_cb->dev_name, device_name
)))); })
) {
511 if (event_cb->cb_fn != cb_fn ||
512 (cb_arg != (void *)-1 &&
513 event_cb->cb_arg != cb_arg))
514 continue;
515 }
516 } else if (device_name != NULL((void*)0)) {
517 continue;
518 }
519
520 /*
521 * if this callback is not executing right now,
522 * then remove it.
523 */
524 if (event_cb->active == 0) {
525 TAILQ_REMOVE(&dev_event_cbs, event_cb, next)do { if (((event_cb)->next.tqe_next) != ((void*)0)) (event_cb
)->next.tqe_next->next.tqe_prev = (event_cb)->next.tqe_prev
; else (&dev_event_cbs)->tqh_last = (event_cb)->next
.tqe_prev; *(event_cb)->next.tqe_prev = (event_cb)->next
.tqe_next; } while ( 0)
;
526 free(event_cb);
527 ret++;
528 } else {
529 continue;
530 }
531 }
532 rte_spinlock_unlock(&dev_event_lock);
533 return ret;
534}
535
536void __rte_experimental__attribute__((section(".text.experimental")))
537rte_dev_event_callback_process(const char *device_name,
538 enum rte_dev_event_type event)
539{
540 struct dev_event_callback *cb_lst;
541
542 if (device_name == NULL((void*)0))
543 return;
544
545 rte_spinlock_lock(&dev_event_lock);
546
547 TAILQ_FOREACH(cb_lst, &dev_event_cbs, next)for ((cb_lst) = ((&dev_event_cbs)->tqh_first); (cb_lst
); (cb_lst) = ((cb_lst)->next.tqe_next))
{
548 if (cb_lst->dev_name) {
549 if (strcmp(cb_lst->dev_name, device_name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cb_lst->dev_name) && __builtin_constant_p (device_name
) && (__s1_len = __builtin_strlen (cb_lst->dev_name
), __s2_len = __builtin_strlen (device_name), (!((size_t)(const
void *)((cb_lst->dev_name) + 1) - (size_t)(const void *)(
cb_lst->dev_name) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)((device_name) + 1) - (size_t)(const void
*)(device_name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(cb_lst->dev_name, device_name) : (__builtin_constant_p (
cb_lst->dev_name) && ((size_t)(const void *)((cb_lst
->dev_name) + 1) - (size_t)(const void *)(cb_lst->dev_name
) == 1) && (__s1_len = __builtin_strlen (cb_lst->dev_name
), __s1_len < 4) ? (__builtin_constant_p (device_name) &&
((size_t)(const void *)((device_name) + 1) - (size_t)(const void
*)(device_name) == 1) ? __builtin_strcmp (cb_lst->dev_name
, device_name) : (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (device_name); int __result
= (((const unsigned char *) (const char *) (cb_lst->dev_name
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (cb_lst
->dev_name))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cb_lst->dev_name))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (cb_lst->dev_name))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p (device_name) && ((size_t
)(const void *)((device_name) + 1) - (size_t)(const void *)(device_name
) == 1) && (__s2_len = __builtin_strlen (device_name)
, __s2_len < 4) ? (__builtin_constant_p (cb_lst->dev_name
) && ((size_t)(const void *)((cb_lst->dev_name) + 1
) - (size_t)(const void *)(cb_lst->dev_name) == 1) ? __builtin_strcmp
(cb_lst->dev_name, device_name) : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(cb_lst->dev_name); int __result = (((const unsigned char
*) (const char *) (device_name))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (device_name))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (device_name))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (device_name))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (cb_lst->dev_name, device_name)
))); })
)
550 continue;
551 }
552 cb_lst->active = 1;
553 rte_spinlock_unlock(&dev_event_lock);
554 cb_lst->cb_fn(device_name, event,
555 cb_lst->cb_arg);
556 rte_spinlock_lock(&dev_event_lock);
557 cb_lst->active = 0;
558 }
559 rte_spinlock_unlock(&dev_event_lock);
560}
561
562__rte_experimental__attribute__((section(".text.experimental")))
563int
564rte_dev_iterator_init(struct rte_dev_iterator *it,
565 const char *dev_str)
566{
567 struct rte_devargs devargs;
568 struct rte_class *cls = NULL((void*)0);
569 struct rte_bus *bus = NULL((void*)0);
570
571 /* Having both bus_str and cls_str NULL is illegal,
572 * marking this iterator as invalid unless
573 * everything goes well.
574 */
575 it->bus_str = NULL((void*)0);
576 it->cls_str = NULL((void*)0);
577
578 devargs.data = dev_str;
579 if (rte_devargs_layers_parse(&devargs, dev_str))
580 goto get_out;
581
582 bus = devargs.bus;
583 cls = devargs.cls;
584 /* The string should have at least
585 * one layer specified.
586 */
587 if (bus == NULL((void*)0) && cls == NULL((void*)0)) {
588 RTE_LOG(ERR, EAL,rte_log(4U, 0, "EAL" ": " "Either bus or class must be specified.\n"
)
589 "Either bus or class must be specified.\n")rte_log(4U, 0, "EAL" ": " "Either bus or class must be specified.\n"
)
;
590 rte_errno(per_lcore__rte_errno) = EINVAL22;
591 goto get_out;
592 }
593 if (bus != NULL((void*)0) && bus->dev_iterate == NULL((void*)0)) {
594 RTE_LOG(ERR, EAL, "Bus %s not supported\n", bus->name)rte_log(4U, 0, "EAL" ": " "Bus %s not supported\n", bus->name
)
;
595 rte_errno(per_lcore__rte_errno) = ENOTSUP95;
596 goto get_out;
597 }
598 if (cls != NULL((void*)0) && cls->dev_iterate == NULL((void*)0)) {
599 RTE_LOG(ERR, EAL, "Class %s not supported\n", cls->name)rte_log(4U, 0, "EAL" ": " "Class %s not supported\n", cls->
name)
;
600 rte_errno(per_lcore__rte_errno) = ENOTSUP95;
601 goto get_out;
602 }
603 it->bus_str = devargs.bus_str;
604 it->cls_str = devargs.cls_str;
605 it->dev_str = dev_str;
606 it->bus = bus;
607 it->cls = cls;
608 it->device = NULL((void*)0);
609 it->class_device = NULL((void*)0);
610get_out:
611 return -rte_errno(per_lcore__rte_errno);
612}
613
614static char *
615dev_str_sane_copy(const char *str)
616{
617 size_t end;
618 char *copy;
619
620 end = strcspn(str, ",/")__extension__ ({ char __r0, __r1, __r2; (__builtin_constant_p
(",/") && ((size_t)(const void *)((",/") + 1) - (size_t
)(const void *)(",/") == 1) ? ((__builtin_constant_p (str) &&
((size_t)(const void *)((str) + 1) - (size_t)(const void *)(
str) == 1)) ? __builtin_strcspn (str, ",/") : ((__r0 = ((const
char *) (",/"))[0], __r0 == '\0') ? strlen (str) : ((__r1 = (
(const char *) (",/"))[1], __r1 == '\0') ? __strcspn_c1 (str,
__r0) : ((__r2 = ((const char *) (",/"))[2], __r2 == '\0') ?
__strcspn_c2 (str, __r0, __r1) : (((const char *) (",/"))[3]
== '\0' ? __strcspn_c3 (str, __r0, __r1, __r2) : __builtin_strcspn
(str, ",/")))))) : __builtin_strcspn (str, ",/")); })
;
621 if (str[end] == ',') {
622 copy = strdup(&str[end + 1])(__extension__ (__builtin_constant_p (&str[end + 1]) &&
((size_t)(const void *)((&str[end + 1]) + 1) - (size_t)(
const void *)(&str[end + 1]) == 1) ? (((const char *) (&
str[end + 1]))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (&str[end + 1]) + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, &str[end + 1],
__len); __retval; })) : __strdup (&str[end + 1])))
;
623 } else {
624 /* '/' or '\0' */
625 copy = strdup("")(__extension__ (__builtin_constant_p ("") && ((size_t
)(const void *)(("") + 1) - (size_t)(const void *)("") == 1) ?
(((const char *) (""))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen ("") + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, "", __len); __retval; })) : __strdup
("")))
;
626 }
627 if (copy == NULL((void*)0)) {
628 rte_errno(per_lcore__rte_errno) = ENOMEM12;
629 } else {
630 char *slash;
631
632 slash = strchr(copy, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(copy) && ('/') == '\0' ? (char *) __rawmemchr (copy
, '/') : __builtin_strchr (copy, '/')))
;
633 if (slash != NULL((void*)0))
634 slash[0] = '\0';
635 }
636 return copy;
637}
638
639static int
640class_next_dev_cmp(const struct rte_class *cls,
641 const void *ctx)
642{
643 struct rte_dev_iterator *it;
644 const char *cls_str = NULL((void*)0);
645 void *dev;
646
647 if (cls->dev_iterate == NULL((void*)0))
648 return 1;
649 it = ITCTX(ctx)(((struct dev_next_ctx *)(intptr_t)ctx)->it);
650 cls_str = CLSCTX(ctx)(((struct dev_next_ctx *)(intptr_t)ctx)->cls_str);
651 dev = it->class_device;
652 /* it->cls_str != NULL means a class
653 * was specified in the devstr.
654 */
655 if (it->cls_str != NULL((void*)0) && cls != it->cls)
656 return 1;
657 /* If an error occurred previously,
658 * no need to test further.
659 */
660 if (rte_errno(per_lcore__rte_errno) != 0)
661 return -1;
662 dev = cls->dev_iterate(dev, cls_str, it);
663 it->class_device = dev;
664 return dev == NULL((void*)0);
665}
666
667static int
668bus_next_dev_cmp(const struct rte_bus *bus,
669 const void *ctx)
670{
671 struct rte_device *dev = NULL((void*)0);
672 struct rte_class *cls = NULL((void*)0);
673 struct rte_dev_iterator *it;
674 const char *bus_str = NULL((void*)0);
675
676 if (bus->dev_iterate == NULL((void*)0))
677 return 1;
678 it = ITCTX(ctx)(((struct dev_next_ctx *)(intptr_t)ctx)->it);
679 bus_str = BUSCTX(ctx)(((struct dev_next_ctx *)(intptr_t)ctx)->bus_str);
680 dev = it->device;
681 /* it->bus_str != NULL means a bus
682 * was specified in the devstr.
683 */
684 if (it->bus_str != NULL((void*)0) && bus != it->bus)
685 return 1;
686 /* If an error occurred previously,
687 * no need to test further.
688 */
689 if (rte_errno(per_lcore__rte_errno) != 0)
690 return -1;
691 if (it->cls_str == NULL((void*)0)) {
692 dev = bus->dev_iterate(dev, bus_str, it);
693 goto end;
694 }
695 /* cls_str != NULL */
696 if (dev == NULL((void*)0)) {
697next_dev_on_bus:
698 dev = bus->dev_iterate(dev, bus_str, it);
699 it->device = dev;
700 }
701 if (dev == NULL((void*)0))
702 return 1;
703 if (it->cls != NULL((void*)0))
704 cls = TAILQ_PREV(it->cls, rte_class_list, next)(*(((struct rte_class_list *)((it->cls)->next.tqe_prev)
)->tqh_last))
;
705 cls = rte_class_find(cls, class_next_dev_cmp, ctx);
706 if (cls != NULL((void*)0)) {
707 it->cls = cls;
708 goto end;
709 }
710 goto next_dev_on_bus;
711end:
712 it->device = dev;
713 return dev == NULL((void*)0);
714}
715__rte_experimental__attribute__((section(".text.experimental")))
716struct rte_device *
717rte_dev_iterator_next(struct rte_dev_iterator *it)
718{
719 struct rte_bus *bus = NULL((void*)0);
720 int old_errno = rte_errno(per_lcore__rte_errno);
721 char *bus_str = NULL((void*)0);
722 char *cls_str = NULL((void*)0);
723
724 rte_errno(per_lcore__rte_errno) = 0;
725 if (it->bus_str == NULL((void*)0) && it->cls_str == NULL((void*)0)) {
726 /* Invalid iterator. */
727 rte_errno(per_lcore__rte_errno) = EINVAL22;
728 return NULL((void*)0);
729 }
730 if (it->bus != NULL((void*)0))
731 bus = TAILQ_PREV(it->bus, rte_bus_list, next)(*(((struct rte_bus_list *)((it->bus)->next.tqe_prev))->
tqh_last))
;
732 if (it->bus_str != NULL((void*)0)) {
733 bus_str = dev_str_sane_copy(it->bus_str);
734 if (bus_str == NULL((void*)0))
735 goto out;
736 }
737 if (it->cls_str != NULL((void*)0)) {
738 cls_str = dev_str_sane_copy(it->cls_str);
739 if (cls_str == NULL((void*)0))
740 goto out;
741 }
742 while ((bus = rte_bus_find(bus, bus_next_dev_cmp,
743 CTX(it, bus_str, cls_str)(&(const struct dev_next_ctx){ .it = it, .bus_str = bus_str
, .cls_str = cls_str, })
))) {
744 if (it->device != NULL((void*)0)) {
745 it->bus = bus;
746 goto out;
747 }
748 if (it->bus_str != NULL((void*)0) ||
749 rte_errno(per_lcore__rte_errno) != 0)
750 break;
751 }
752 if (rte_errno(per_lcore__rte_errno) == 0)
753 rte_errno(per_lcore__rte_errno) = old_errno;
754out:
755 free(bus_str);
756 free(cls_str);
757 return it->device;
758}
759
760int
761rte_dev_dma_map(struct rte_device *dev, void *addr, uint64_t iova,
762 size_t len)
763{
764 if (dev->bus->dma_map == NULL((void*)0) || len == 0) {
765 rte_errno(per_lcore__rte_errno) = ENOTSUP95;
766 return -1;
767 }
768 /* Memory must be registered through rte_extmem_* APIs */
769 if (rte_mem_virt2memseg_list(addr) == NULL((void*)0)) {
770 rte_errno(per_lcore__rte_errno) = EINVAL22;
771 return -1;
772 }
773
774 return dev->bus->dma_map(dev, addr, iova, len);
775}
776
777int
778rte_dev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,
779 size_t len)
780{
781 if (dev->bus->dma_unmap == NULL((void*)0) || len == 0) {
782 rte_errno(per_lcore__rte_errno) = ENOTSUP95;
783 return -1;
784 }
785 /* Memory must be registered through rte_extmem_* APIs */
786 if (rte_mem_virt2memseg_list(addr) == NULL((void*)0)) {
787 rte_errno(per_lcore__rte_errno) = EINVAL22;
788 return -1;
789 }
790
791 return dev->bus->dma_unmap(dev, addr, iova, len);
792}