6e3f203e793ce694250246d77edaf70ac7a33c1f
[dpdk.git] / drivers / net / failsafe / failsafe_private.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2017 6WIND S.A.
3  * Copyright 2017 Mellanox Technologies, Ltd
4  */
5
6 #ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_
7 #define _RTE_ETH_FAILSAFE_PRIVATE_H_
8
9 #include <stdint.h>
10 #include <sys/queue.h>
11 #include <pthread.h>
12
13 #include <rte_atomic.h>
14 #include <rte_dev.h>
15 #include <rte_ethdev_driver.h>
16 #include <rte_devargs.h>
17 #include <rte_flow.h>
18 #include <rte_interrupts.h>
19
20 #define FAILSAFE_DRIVER_NAME "Fail-safe PMD"
21 #define FAILSAFE_OWNER_NAME "Fail-safe"
22
23 #define PMD_FAILSAFE_MAC_KVARG "mac"
24 #define PMD_FAILSAFE_HOTPLUG_POLL_KVARG "hotplug_poll"
25 #define PMD_FAILSAFE_PARAM_STRING       \
26         "dev(<ifc>),"                   \
27         "exec(<shell command>),"        \
28         "fd(<fd number>),"              \
29         "mac=mac_addr,"                 \
30         "hotplug_poll=u64"              \
31         ""
32
33 #define FAILSAFE_HOTPLUG_DEFAULT_TIMEOUT_MS 2000
34
35 #define FAILSAFE_MAX_ETHPORTS 2
36 #define FAILSAFE_MAX_ETHADDR 128
37
38 #define DEVARGS_MAXLEN 4096
39
40 enum rxp_service_state {
41         SS_NO_SERVICE = 0,
42         SS_REGISTERED,
43         SS_READY,
44         SS_RUNNING,
45 };
46
47 /* TYPES */
48
49 struct rx_proxy {
50         /* epoll file descriptor */
51         int efd;
52         /* event vector to be used by epoll */
53         struct rte_epoll_event *evec;
54         /* rte service id */
55         uint32_t sid;
56         /* service core id */
57         uint32_t scid;
58         enum rxp_service_state sstate;
59 };
60
61 struct rxq {
62         struct fs_priv *priv;
63         uint16_t qid;
64         /* next sub_device to poll */
65         struct sub_device *sdev;
66         unsigned int socket_id;
67         int event_fd;
68         unsigned int enable_events:1;
69         struct rte_eth_rxq_info info;
70         rte_atomic64_t refcnt[];
71 };
72
73 struct txq {
74         struct fs_priv *priv;
75         uint16_t qid;
76         unsigned int socket_id;
77         struct rte_eth_txq_info info;
78         rte_atomic64_t refcnt[];
79 };
80
81 struct rte_flow {
82         TAILQ_ENTRY(rte_flow) next;
83         /* sub_flows */
84         struct rte_flow *flows[FAILSAFE_MAX_ETHPORTS];
85         /* flow description for synchronization */
86         struct rte_flow_conv_rule rule;
87         uint8_t rule_data[];
88 };
89
90 enum dev_state {
91         DEV_UNDEFINED,
92         DEV_PARSED,
93         DEV_PROBED,
94         DEV_ACTIVE,
95         DEV_STARTED,
96 };
97
98 struct fs_stats {
99         struct rte_eth_stats stats;
100         uint64_t timestamp;
101 };
102
103 struct sub_device {
104         /* Exhaustive DPDK device description */
105         struct sub_device *next;
106         struct rte_devargs devargs;
107         struct rte_bus *bus;
108         struct rte_device *dev;
109         struct rte_eth_dev *edev;
110         uint8_t sid;
111         /* Device state machine */
112         enum dev_state state;
113         /* Last stats snapshot passed to user */
114         struct fs_stats stats_snapshot;
115         /* Some device are defined as a command line */
116         char *cmdline;
117         /* Others are retrieved through a file descriptor */
118         char *fd_str;
119         /* fail-safe device backreference */
120         struct rte_eth_dev *fs_dev;
121         /* flag calling for recollection */
122         volatile unsigned int remove:1;
123         /* flow isolation state */
124         int flow_isolated:1;
125         /* RMV callback registration state */
126         unsigned int rmv_callback:1;
127         /* LSC callback registration state */
128         unsigned int lsc_callback:1;
129 };
130
131 /*
132  * This is referenced by eth_dev->data->dev_private
133  * This is shared between processes.
134  */
135 struct fs_priv {
136         struct rte_eth_dev_data *data; /* backreference to shared data. */
137         /*
138          * Set of sub_devices.
139          * subs[0] is the preferred device
140          * any other is just another slave
141          */
142         struct sub_device *subs;
143         uint8_t subs_head; /* if head == tail, no subs */
144         uint8_t subs_tail; /* first invalid */
145         uint8_t subs_tx; /* current emitting device */
146         uint8_t current_probed;
147         /* flow mapping */
148         TAILQ_HEAD(sub_flows, rte_flow) flow_list;
149         /* current number of mac_addr slots allocated. */
150         uint32_t nb_mac_addr;
151         struct ether_addr mac_addrs[FAILSAFE_MAX_ETHADDR];
152         uint32_t mac_addr_pool[FAILSAFE_MAX_ETHADDR];
153         uint32_t nb_mcast_addr;
154         struct ether_addr *mcast_addrs;
155         /* current capabilities */
156         struct rte_eth_dev_info infos;
157         struct rte_eth_dev_owner my_owner; /* Unique owner. */
158         struct rte_intr_handle intr_handle; /* Port interrupt handle. */
159         /*
160          * Fail-safe state machine.
161          * This level will be tracking state of the EAL and eth
162          * layer at large as defined by the user application.
163          * It will then steer the sub_devices toward the same
164          * synchronized state.
165          */
166         enum dev_state state;
167         struct rte_eth_stats stats_accumulator;
168         /*
169          * Rx interrupts/events proxy.
170          * The PMD issues Rx events to the EAL on behalf of its subdevices,
171          * it does that by registering an event-fd for each of its queues with
172          * the EAL. A PMD service thread listens to all the Rx events from the
173          * subdevices, when an Rx event is issued by a subdevice it will be
174          * caught by this service with will trigger an Rx event in the
175          * appropriate failsafe Rx queue.
176          */
177         struct rx_proxy rxp;
178         pthread_mutex_t hotplug_mutex;
179         /* Hot-plug mutex is locked by the alarm mechanism. */
180         volatile unsigned int alarm_lock:1;
181         unsigned int pending_alarm:1; /* An alarm is pending */
182         /* flow isolation state */
183         int flow_isolated:1;
184 };
185
186 /* FAILSAFE_INTR */
187
188 int failsafe_rx_intr_install(struct rte_eth_dev *dev);
189 void failsafe_rx_intr_uninstall(struct rte_eth_dev *dev);
190 int failsafe_rx_intr_install_subdevice(struct sub_device *sdev);
191 void failsafe_rx_intr_uninstall_subdevice(struct sub_device *sdev);
192
193 /* MISC */
194
195 int failsafe_hotplug_alarm_install(struct rte_eth_dev *dev);
196 int failsafe_hotplug_alarm_cancel(struct rte_eth_dev *dev);
197
198 /* RX / TX */
199
200 void failsafe_set_burst_fn(struct rte_eth_dev *dev, int force_safe);
201
202 uint16_t failsafe_rx_burst(void *rxq,
203                 struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
204 uint16_t failsafe_tx_burst(void *txq,
205                 struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
206
207 uint16_t failsafe_rx_burst_fast(void *rxq,
208                 struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
209 uint16_t failsafe_tx_burst_fast(void *txq,
210                 struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
211
212 /* ARGS */
213
214 int failsafe_args_parse(struct rte_eth_dev *dev, const char *params);
215 void failsafe_args_free(struct rte_eth_dev *dev);
216 int failsafe_args_count_subdevice(struct rte_eth_dev *dev, const char *params);
217 int failsafe_args_parse_subs(struct rte_eth_dev *dev);
218
219 /* EAL */
220
221 int failsafe_eal_init(struct rte_eth_dev *dev);
222 int failsafe_eal_uninit(struct rte_eth_dev *dev);
223
224 /* ETH_DEV */
225
226 int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev);
227 void failsafe_eth_dev_unregister_callbacks(struct sub_device *sdev);
228 void failsafe_dev_remove(struct rte_eth_dev *dev);
229 void failsafe_stats_increment(struct rte_eth_stats *to,
230                                 struct rte_eth_stats *from);
231 int failsafe_eth_rmv_event_callback(uint16_t port_id,
232                                     enum rte_eth_event_type type,
233                                     void *arg, void *out);
234 int failsafe_eth_lsc_event_callback(uint16_t port_id,
235                                     enum rte_eth_event_type event,
236                                     void *cb_arg, void *out);
237 int failsafe_eth_new_event_callback(uint16_t port_id,
238                                     enum rte_eth_event_type event,
239                                     void *cb_arg, void *out);
240
241 /* GLOBALS */
242
243 extern const char pmd_failsafe_driver_name[];
244 extern const struct eth_dev_ops failsafe_ops;
245 extern const struct rte_flow_ops fs_flow_ops;
246 extern uint64_t failsafe_hotplug_poll;
247 extern int failsafe_mac_from_arg;
248
249 /* HELPERS */
250
251 /* dev: (struct rte_eth_dev *) fail-safe device */
252 #define PRIV(dev) \
253         ((struct fs_priv *)(dev)->data->dev_private)
254
255 /* sdev: (struct sub_device *) */
256 #define ETH(sdev) \
257         ((sdev)->edev)
258
259 /* sdev: (struct sub_device *) */
260 #define PORT_ID(sdev) \
261         (ETH(sdev)->data->port_id)
262
263 /* sdev: (struct sub_device *) */
264 #define SUB_ID(sdev) \
265         ((sdev)->sid)
266
267 /**
268  * Stateful iterator construct over fail-safe sub-devices:
269  * s:     (struct sub_device *), iterator
270  * i:     (uint8_t), increment
271  * dev:   (struct rte_eth_dev *), fail-safe ethdev
272  * state: (enum dev_state), minimum acceptable device state
273  */
274 #define FOREACH_SUBDEV_STATE(s, i, dev, state)          \
275         for (s = fs_find_next((dev), 0, state, &i);     \
276              s != NULL;                                 \
277              s = fs_find_next((dev), i + 1, state, &i))
278
279 /**
280  * Iterator construct over fail-safe sub-devices:
281  * s:   (struct sub_device *), iterator
282  * i:   (uint8_t), increment
283  * dev: (struct rte_eth_dev *), fail-safe ethdev
284  */
285 #define FOREACH_SUBDEV(s, i, dev)                       \
286         FOREACH_SUBDEV_STATE(s, i, dev, DEV_UNDEFINED)
287
288 /* dev: (struct rte_eth_dev *) fail-safe device */
289 #define PREFERRED_SUBDEV(dev) \
290         (&PRIV(dev)->subs[0])
291
292 /* dev: (struct rte_eth_dev *) fail-safe device */
293 #define TX_SUBDEV(dev)                                                    \
294         (PRIV(dev)->subs_tx >= PRIV(dev)->subs_tail                ? NULL \
295          : (PRIV(dev)->subs[PRIV(dev)->subs_tx].state < DEV_PROBED ? NULL \
296          : &PRIV(dev)->subs[PRIV(dev)->subs_tx]))
297
298 /**
299  * s:   (struct sub_device *)
300  * ops: (struct eth_dev_ops) member
301  */
302 #define SUBOPS(s, ops) \
303         (ETH(s)->dev_ops->ops)
304
305 /**
306  * Atomic guard
307  */
308
309 /**
310  * a: (rte_atomic64_t)
311  */
312 #define FS_ATOMIC_P(a) \
313         rte_atomic64_set(&(a), 1)
314
315 /**
316  * a: (rte_atomic64_t)
317  */
318 #define FS_ATOMIC_V(a) \
319         rte_atomic64_set(&(a), 0)
320
321 /**
322  * s: (struct sub_device *)
323  * i: uint16_t qid
324  */
325 #define FS_ATOMIC_RX(s, i) \
326         rte_atomic64_read( \
327          &((struct rxq *)((s)->fs_dev->data->rx_queues[i]))->refcnt[(s)->sid] \
328         )
329 /**
330  * s: (struct sub_device *)
331  * i: uint16_t qid
332  */
333 #define FS_ATOMIC_TX(s, i) \
334         rte_atomic64_read( \
335          &((struct txq *)((s)->fs_dev->data->tx_queues[i]))->refcnt[(s)->sid] \
336         )
337
338 #ifdef RTE_EXEC_ENV_FREEBSD
339 #define FS_THREADID_TYPE void*
340 #define FS_THREADID_FMT  "p"
341 #else
342 #define FS_THREADID_TYPE unsigned long
343 #define FS_THREADID_FMT  "lu"
344 #endif
345
346 extern int failsafe_logtype;
347
348 #define LOG__(l, m, ...) \
349         rte_log(RTE_LOG_ ## l, failsafe_logtype, \
350                 "net_failsafe: " m "%c", __VA_ARGS__)
351
352 #define LOG_(level, ...) LOG__(level, __VA_ARGS__, '\n')
353 #define DEBUG(...) LOG_(DEBUG, __VA_ARGS__)
354 #define INFO(...) LOG_(INFO, __VA_ARGS__)
355 #define WARN(...) LOG_(WARNING, __VA_ARGS__)
356 #define ERROR(...) LOG_(ERR, __VA_ARGS__)
357
358 /* inlined functions */
359
360 static inline struct sub_device *
361 fs_find_next(struct rte_eth_dev *dev,
362              uint8_t sid,
363              enum dev_state min_state,
364              uint8_t *sid_out)
365 {
366         struct sub_device *subs;
367         uint8_t tail;
368
369         subs = PRIV(dev)->subs;
370         tail = PRIV(dev)->subs_tail;
371         while (sid < tail) {
372                 if (subs[sid].state >= min_state)
373                         break;
374                 sid++;
375         }
376         *sid_out = sid;
377         if (sid >= tail)
378                 return NULL;
379         return &subs[sid];
380 }
381
382 /*
383  * Lock hot-plug mutex.
384  * is_alarm means that the caller is, for sure, the hot-plug alarm mechanism.
385  */
386 static inline int
387 fs_lock(struct rte_eth_dev *dev, unsigned int is_alarm)
388 {
389         int ret;
390
391         if (is_alarm) {
392                 ret = pthread_mutex_trylock(&PRIV(dev)->hotplug_mutex);
393                 if (ret) {
394                         DEBUG("Hot-plug mutex lock trying failed(%s), will try"
395                               " again later...", strerror(ret));
396                         return ret;
397                 }
398                 PRIV(dev)->alarm_lock = 1;
399         } else {
400                 ret = pthread_mutex_lock(&PRIV(dev)->hotplug_mutex);
401                 if (ret) {
402                         ERROR("Cannot lock mutex(%s)", strerror(ret));
403                         return ret;
404                 }
405         }
406         return ret;
407 }
408
409 /*
410  * Unlock hot-plug mutex.
411  * is_alarm means that the caller is, for sure, the hot-plug alarm mechanism.
412  */
413 static inline void
414 fs_unlock(struct rte_eth_dev *dev, unsigned int is_alarm)
415 {
416         int ret;
417
418         if (is_alarm) {
419                 RTE_ASSERT(PRIV(dev)->alarm_lock == 1);
420                 PRIV(dev)->alarm_lock = 0;
421         }
422         ret = pthread_mutex_unlock(&PRIV(dev)->hotplug_mutex);
423         if (ret)
424                 ERROR("Cannot unlock hot-plug mutex(%s)", strerror(ret));
425 }
426
427 /*
428  * Switch emitting device.
429  * If banned is set, banned must not be considered for
430  * the role of emitting device.
431  */
432 static inline void
433 fs_switch_dev(struct rte_eth_dev *dev,
434               struct sub_device *banned)
435 {
436         struct sub_device *txd;
437         enum dev_state req_state;
438
439         req_state = PRIV(dev)->state;
440         txd = TX_SUBDEV(dev);
441         if (PREFERRED_SUBDEV(dev)->state >= req_state &&
442             PREFERRED_SUBDEV(dev) != banned) {
443                 if (txd != PREFERRED_SUBDEV(dev) &&
444                     (txd == NULL ||
445                      (req_state == DEV_STARTED) ||
446                      (txd && txd->state < DEV_STARTED))) {
447                         DEBUG("Switching tx_dev to preferred sub_device");
448                         PRIV(dev)->subs_tx = 0;
449                 }
450         } else if ((txd && txd->state < req_state) ||
451                    txd == NULL ||
452                    txd == banned) {
453                 struct sub_device *sdev = NULL;
454                 uint8_t i;
455
456                 /* Using acceptable device */
457                 FOREACH_SUBDEV_STATE(sdev, i, dev, req_state) {
458                         if (sdev == banned)
459                                 continue;
460                         DEBUG("Switching tx_dev to sub_device %d",
461                               i);
462                         PRIV(dev)->subs_tx = i;
463                         break;
464                 }
465                 if (i >= PRIV(dev)->subs_tail || sdev == NULL) {
466                         DEBUG("No device ready, deactivating tx_dev");
467                         PRIV(dev)->subs_tx = PRIV(dev)->subs_tail;
468                 }
469         } else {
470                 return;
471         }
472         failsafe_set_burst_fn(dev, 0);
473         rte_wmb();
474 }
475
476 /*
477  * Adjust error value and rte_errno to the fail-safe actual error value.
478  */
479 static inline int
480 fs_err(struct sub_device *sdev, int err)
481 {
482         /* A device removal shouldn't be reported as an error. */
483         if (sdev->remove == 1 || err == -EIO)
484                 return rte_errno = 0;
485         return err;
486 }
487 #endif /* _RTE_ETH_FAILSAFE_PRIVATE_H_ */