]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/net/failsafe/failsafe_eal.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / failsafe / failsafe_eal.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2017 6WIND S.A.
3 * Copyright 2017 Mellanox Technologies, Ltd
4 */
5
6 #include <rte_string_fns.h>
7 #include <rte_malloc.h>
8
9 #include "failsafe_private.h"
10
11 static int
12 fs_ethdev_portid_get(const char *name, uint16_t *port_id)
13 {
14 uint16_t pid;
15 size_t len;
16
17 if (name == NULL) {
18 DEBUG("Null pointer is specified\n");
19 return -EINVAL;
20 }
21 len = strlen(name);
22 for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) {
23 if (rte_eth_dev_is_valid_port(pid) &&
24 !strncmp(name, rte_eth_devices[pid].device->name, len)) {
25 *port_id = pid;
26 return 0;
27 }
28 }
29 return -ENODEV;
30 }
31
32 static int
33 fs_bus_init(struct rte_eth_dev *dev)
34 {
35 struct sub_device *sdev;
36 struct rte_devargs *da;
37 uint8_t i;
38 uint16_t pid;
39 int ret;
40
41 FOREACH_SUBDEV(sdev, i, dev) {
42 if (sdev->state != DEV_PARSED)
43 continue;
44 da = &sdev->devargs;
45 if (fs_ethdev_portid_get(da->name, &pid) != 0) {
46 struct rte_eth_dev_owner pid_owner;
47
48 ret = rte_eal_hotplug_add(da->bus->name,
49 da->name,
50 da->args);
51 if (ret) {
52 ERROR("sub_device %d probe failed %s%s%s", i,
53 rte_errno ? "(" : "",
54 rte_errno ? strerror(rte_errno) : "",
55 rte_errno ? ")" : "");
56 continue;
57 }
58 if (fs_ethdev_portid_get(da->name, &pid) != 0) {
59 ERROR("sub_device %d init went wrong", i);
60 return -ENODEV;
61 }
62 /*
63 * The NEW callback tried to take ownership, check
64 * whether it succeed or didn't.
65 */
66 rte_eth_dev_owner_get(pid, &pid_owner);
67 if (pid_owner.id != PRIV(dev)->my_owner.id) {
68 INFO("sub_device %d owner(%s_%016"PRIX64") is not my,"
69 " owner(%s_%016"PRIX64"), will try again later",
70 i, pid_owner.name, pid_owner.id,
71 PRIV(dev)->my_owner.name,
72 PRIV(dev)->my_owner.id);
73 continue;
74 }
75 } else {
76 /* The sub-device port was found. */
77 char devstr[DEVARGS_MAXLEN] = "";
78 struct rte_devargs *probed_da =
79 rte_eth_devices[pid].device->devargs;
80
81 /* Take control of probed device. */
82 free(da->args);
83 memset(da, 0, sizeof(*da));
84 if (probed_da != NULL)
85 snprintf(devstr, sizeof(devstr), "%s,%s",
86 probed_da->name, probed_da->args);
87 else
88 strlcpy(devstr,
89 rte_eth_devices[pid].device->name,
90 sizeof(devstr));
91 ret = rte_devargs_parse(da, devstr);
92 if (ret) {
93 ERROR("Probed devargs parsing failed with code"
94 " %d", ret);
95 return ret;
96 }
97 INFO("Taking control of a probed sub device"
98 " %d named %s", i, da->name);
99 ret = rte_eth_dev_owner_set(pid, &PRIV(dev)->my_owner);
100 if (ret < 0) {
101 INFO("sub_device %d owner set failed (%s), "
102 "will try again later", i, strerror(-ret));
103 continue;
104 } else if (strncmp(rte_eth_devices[pid].device->name,
105 da->name, strlen(da->name)) != 0) {
106 /*
107 * The device probably was removed and its port
108 * id was reallocated before ownership set.
109 */
110 rte_eth_dev_owner_unset(pid,
111 PRIV(dev)->my_owner.id);
112 INFO("sub_device %d was removed before taking"
113 " ownership, will try again later", i);
114 continue;
115 }
116 }
117 sdev->sdev_port_id = pid;
118 SUB_ID(sdev) = i;
119 sdev->fs_port_id = dev->data->port_id;
120 sdev->dev = ETH(sdev)->device;
121 sdev->state = DEV_PROBED;
122 }
123 return 0;
124 }
125
126 int
127 failsafe_eal_init(struct rte_eth_dev *dev)
128 {
129 int ret;
130
131 ret = fs_bus_init(dev);
132 if (ret)
133 return ret;
134 if (PRIV(dev)->state < DEV_PROBED)
135 PRIV(dev)->state = DEV_PROBED;
136 fs_switch_dev(dev, NULL);
137 return 0;
138 }
139
140 static int
141 fs_bus_uninit(struct rte_eth_dev *dev)
142 {
143 struct sub_device *sdev = NULL;
144 uint8_t i;
145 int sdev_ret;
146 int ret = 0;
147
148 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_PROBED) {
149 sdev_ret = rte_dev_remove(sdev->dev);
150 if (sdev_ret) {
151 ERROR("Failed to remove requested device %s (err: %d)",
152 sdev->dev->name, sdev_ret);
153 continue;
154 }
155 sdev->state = DEV_PROBED - 1;
156 }
157 return ret;
158 }
159
160 int
161 failsafe_eal_uninit(struct rte_eth_dev *dev)
162 {
163 int ret;
164
165 ret = fs_bus_uninit(dev);
166 PRIV(dev)->state = DEV_PROBED - 1;
167 return ret;
168 }