X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Ffailsafe%2Ffailsafe_private.h;h=7754248ff827f7d81b510d403bdddb761699bb87;hb=ac6881ea6b6101d6de7b1e3900d47afaa08bcc2d;hp=82d969d889c5600d91dc6f36d5ef2ad005b48c58;hpb=b737a1ee57b6d7a868f71ab97894398fac61963b;p=dpdk.git diff --git a/drivers/net/failsafe/failsafe_private.h b/drivers/net/failsafe/failsafe_private.h index 82d969d889..7754248ff8 100644 --- a/drivers/net/failsafe/failsafe_private.h +++ b/drivers/net/failsafe/failsafe_private.h @@ -36,8 +36,9 @@ #include +#include #include -#include +#include #include #define FAILSAFE_DRIVER_NAME "Fail-safe PMD" @@ -47,6 +48,7 @@ #define PMD_FAILSAFE_PARAM_STRING \ "dev()," \ "exec()," \ + "fd()," \ "mac=mac_addr," \ "hotplug_poll=u64" \ "" @@ -56,15 +58,18 @@ #define FAILSAFE_MAX_ETHPORTS 2 #define FAILSAFE_MAX_ETHADDR 128 +#define DEVARGS_MAXLEN 4096 + /* TYPES */ struct rxq { struct fs_priv *priv; uint16_t qid; - /* id of last sub_device polled */ - uint8_t last_polled; + /* next sub_device to poll */ + struct sub_device *sdev; unsigned int socket_id; struct rte_eth_rxq_info info; + rte_atomic64_t refcnt[]; }; struct txq { @@ -72,6 +77,7 @@ struct txq { uint16_t qid; unsigned int socket_id; struct rte_eth_txq_info info; + rte_atomic64_t refcnt[]; }; struct rte_flow { @@ -90,8 +96,14 @@ enum dev_state { DEV_STARTED, }; +struct fs_stats { + struct rte_eth_stats stats; + uint64_t timestamp; +}; + struct sub_device { /* Exhaustive DPDK device description */ + struct sub_device *next; struct rte_devargs devargs; struct rte_bus *bus; struct rte_device *dev; @@ -99,8 +111,18 @@ struct sub_device { uint8_t sid; /* Device state machine */ enum dev_state state; + /* Last stats snapshot passed to user */ + struct fs_stats stats_snapshot; /* Some device are defined as a command line */ char *cmdline; + /* Others are retrieved through a file descriptor */ + char *fd_str; + /* fail-safe device backreference */ + struct rte_eth_dev *fs_dev; + /* flag calling for recollection */ + volatile unsigned int remove:1; + /* flow isolation state */ + int flow_isolated:1; }; struct fs_priv { @@ -131,7 +153,10 @@ struct fs_priv { * synchronized state. */ enum dev_state state; + struct rte_eth_stats stats_accumulator; unsigned int pending_alarm:1; /* An alarm is pending */ + /* flow isolation state */ + int flow_isolated:1; }; /* MISC */ @@ -141,11 +166,18 @@ int failsafe_hotplug_alarm_cancel(struct rte_eth_dev *dev); /* RX / TX */ +void set_burst_fn(struct rte_eth_dev *dev, int force_safe); + uint16_t failsafe_rx_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); uint16_t failsafe_tx_burst(void *txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); +uint16_t failsafe_rx_burst_fast(void *rxq, + struct rte_mbuf **rx_pkts, uint16_t nb_pkts); +uint16_t failsafe_tx_burst_fast(void *txq, + struct rte_mbuf **tx_pkts, uint16_t nb_pkts); + /* ARGS */ int failsafe_args_parse(struct rte_eth_dev *dev, const char *params); @@ -161,6 +193,15 @@ int failsafe_eal_uninit(struct rte_eth_dev *dev); /* ETH_DEV */ int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev); +void failsafe_dev_remove(struct rte_eth_dev *dev); +void failsafe_stats_increment(struct rte_eth_stats *to, + struct rte_eth_stats *from); +int failsafe_eth_rmv_event_callback(uint16_t port_id, + enum rte_eth_event_type type, + void *arg, void *out); +int failsafe_eth_lsc_event_callback(uint16_t port_id, + enum rte_eth_event_type event, + void *cb_arg, void *out); /* GLOBALS */ @@ -195,10 +236,10 @@ extern int mac_from_arg; * dev: (struct rte_eth_dev *), fail-safe ethdev * state: (enum dev_state), minimum acceptable device state */ -#define FOREACH_SUBDEV_STATE(s, i, dev, state) \ - for (i = fs_find_next((dev), 0, state); \ - i < PRIV(dev)->subs_tail && (s = &PRIV(dev)->subs[i]); \ - i = fs_find_next((dev), i + 1, state)) +#define FOREACH_SUBDEV_STATE(s, i, dev, state) \ + for (s = fs_find_next((dev), 0, state, &i); \ + s != NULL; \ + s = fs_find_next((dev), i + 1, state, &i)) /** * Iterator construct over fail-safe sub-devices: @@ -226,6 +267,39 @@ extern int mac_from_arg; #define SUBOPS(s, ops) \ (ETH(s)->dev_ops->ops) +/** + * Atomic guard + */ + +/** + * a: (rte_atomic64_t) + */ +#define FS_ATOMIC_P(a) \ + rte_atomic64_set(&(a), 1) + +/** + * a: (rte_atomic64_t) + */ +#define FS_ATOMIC_V(a) \ + rte_atomic64_set(&(a), 0) + +/** + * s: (struct sub_device *) + * i: uint16_t qid + */ +#define FS_ATOMIC_RX(s, i) \ + rte_atomic64_read( \ + &((struct rxq *)((s)->fs_dev->data->rx_queues[i]))->refcnt[(s)->sid] \ + ) +/** + * s: (struct sub_device *) + * i: uint16_t qid + */ +#define FS_ATOMIC_TX(s, i) \ + rte_atomic64_read( \ + &((struct txq *)((s)->fs_dev->data->tx_queues[i]))->refcnt[(s)->sid] \ + ) + #define LOG__(level, m, ...) \ RTE_LOG(level, PMD, "net_failsafe: " m "%c", __VA_ARGS__) #define LOG_(level, ...) LOG__(level, __VA_ARGS__, '\n') @@ -236,53 +310,86 @@ extern int mac_from_arg; /* inlined functions */ -static inline uint8_t -fs_find_next(struct rte_eth_dev *dev, uint8_t sid, - enum dev_state min_state) +static inline struct sub_device * +fs_find_next(struct rte_eth_dev *dev, + uint8_t sid, + enum dev_state min_state, + uint8_t *sid_out) { - while (sid < PRIV(dev)->subs_tail) { - if (PRIV(dev)->subs[sid].state >= min_state) + struct sub_device *subs; + uint8_t tail; + + subs = PRIV(dev)->subs; + tail = PRIV(dev)->subs_tail; + while (sid < tail) { + if (subs[sid].state >= min_state) break; sid++; } - if (sid >= PRIV(dev)->subs_tail) - return PRIV(dev)->subs_tail; - return sid; + *sid_out = sid; + if (sid >= tail) + return NULL; + return &subs[sid]; } +/* + * Switch emitting device. + * If banned is set, banned must not be considered for + * the role of emitting device. + */ static inline void -fs_switch_dev(struct rte_eth_dev *dev) +fs_switch_dev(struct rte_eth_dev *dev, + struct sub_device *banned) { + struct sub_device *txd; enum dev_state req_state; req_state = PRIV(dev)->state; - if (PREFERRED_SUBDEV(dev)->state >= req_state) { - if (TX_SUBDEV(dev) != PREFERRED_SUBDEV(dev) && - (TX_SUBDEV(dev) == NULL || + txd = TX_SUBDEV(dev); + if (PREFERRED_SUBDEV(dev)->state >= req_state && + PREFERRED_SUBDEV(dev) != banned) { + if (txd != PREFERRED_SUBDEV(dev) && + (txd == NULL || (req_state == DEV_STARTED) || - (TX_SUBDEV(dev) && TX_SUBDEV(dev)->state < DEV_STARTED))) { + (txd && txd->state < DEV_STARTED))) { DEBUG("Switching tx_dev to preferred sub_device"); PRIV(dev)->subs_tx = 0; } - } else if ((TX_SUBDEV(dev) && TX_SUBDEV(dev)->state < req_state) || - TX_SUBDEV(dev) == NULL) { - struct sub_device *sdev; + } else if ((txd && txd->state < req_state) || + txd == NULL || + txd == banned) { + struct sub_device *sdev = NULL; uint8_t i; /* Using acceptable device */ FOREACH_SUBDEV_STATE(sdev, i, dev, req_state) { + if (sdev == banned) + continue; DEBUG("Switching tx_dev to sub_device %d", i); PRIV(dev)->subs_tx = i; break; } - } else if (TX_SUBDEV(dev) && TX_SUBDEV(dev)->state < req_state) { - DEBUG("No device ready, deactivating tx_dev"); - PRIV(dev)->subs_tx = PRIV(dev)->subs_tail; + if (i >= PRIV(dev)->subs_tail || sdev == NULL) { + DEBUG("No device ready, deactivating tx_dev"); + PRIV(dev)->subs_tx = PRIV(dev)->subs_tail; + } } else { return; } + set_burst_fn(dev, 0); rte_wmb(); } +/* + * Adjust error value and rte_errno to the fail-safe actual error value. + */ +static inline int +fs_err(struct sub_device *sdev, int err) +{ + /* A device removal shouldn't be reported as an error. */ + if (sdev->remove == 1 || err == -EIO) + return rte_errno = 0; + return err; +} #endif /* _RTE_ETH_FAILSAFE_PRIVATE_H_ */