introduce fail-safe PMD
v3 cover introduce fail-safe PMD
This PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/
ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/
ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/
v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixes
v2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.
Gaetan Rivet (11):
ethdev: save VLAN filter setting
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMD
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support link status change event
net/failsafe: support flow API isolation mode
MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 186 +++++++ doc/guides/nics/features/failsafe.ini | 32 ++ doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 74 +++ drivers/net/failsafe/failsafe.c | 305 +++++++++++ drivers/net/failsafe/failsafe_args.c | 475 +++++++++++++++++ drivers/net/failsafe/failsafe_eal.c | 140 +++++ drivers/net/failsafe/failsafe_ether.c | 413 +++++++++++++++ drivers/net/failsafe/failsafe_flow.c | 245 +++++++++ drivers/net/failsafe/failsafe_ops.c | 869 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 377 ++++++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 204 ++++++++ lib/librte_ether/rte_ethdev.c | 38 +- lib/librte_ether/rte_ethdev.h | 24 +- mk/rte.app.mk | 1 + 18 files changed, 3381 insertions(+), 16 deletions(-) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ether.c create mode 100644 drivers/net/failsafe/failsafe_flow.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c
Signature · 1 line
2.1.4
PATCH v3 1/11 ethdev: save VLAN filter setting
Other configuration items (i.e. MAC addresses) are stored within rte_eth_dev_data, but not this one.
--- lib/librte_ether/rte_ethdev.c | 19 ++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +18 -1
@@ -1976,6 +1976,7 @@ int rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) { struct rte_eth_dev *dev; +int ret;RTE_ETH_VALID_PORTID_OR_ERR_RET (port_id, -ENODEV ); dev = &rte_eth_devices[port_id];
@@ -1991,7 +1992,23 @@ rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) }RTE_FUNC_PTR_OR_ERR_RET (*dev->dev_ops->vlan_filter_set, -ENOTSUP ); -return (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); + ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); +if (ret ==0 ) { +struct rte_vlan_filter_conf *vfc; +int vidx; +int vbit; + + vfc = &dev->data->vlan_filter_conf; + vidx = vlan_id /64 ; + vbit = vlan_id %64 ; + +if (on) + vfc->ids[vidx] |=UINT64_C (1 ) << vbit; +else + vfc->ids[vidx] &= ~(UINT64_C (1 ) << vbit); + } + +return ret; }int
lib/librte_ether/rte_ethdev.h +10 -0
@@ -374,6 +374,14 @@ enum rte_vlan_type { };/** +* A structure used to describe a vlan filter. +* If the bit corresponding to a VID is set, such VID is on. +*/ +struct rte_vlan_filter_conf { +uint64_t ids[64 ]; +}; + +/** * A structure used to configure the Receive Side Scaling (RSS) feature * of an Ethernet port. * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1738,6 +1746,8 @@ struct rte_eth_dev_data {enum rte_kernel_driver kdrv;/**< Kernel driver passthrough */ int numa_node;/**< NUMA node connection */ const char *drv_name;/**< Driver name */ +struct rte_vlan_filter_conf vlan_filter_conf; +/**< VLAN filter configuration. */ };/** Device supports hotplug detach */
Signature · 1 line
2.1.4
PATCH v3 2/11 ethdev: add deferred intermediate device state
In reply to Gaetan RivetThis device state means that the device is managed externally, by whichever party has set this state (PMD or application).
Note: this new device state is only an information. The related device structure and operators are still valid and can be used normally.
It is however made private by device management helpers within ethdev, making the device invisible to applications.
--- lib/librte_ether/rte_ethdev.c | 3 ++- lib/librte_ether/rte_ethdev.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +2 -1
@@ -288,7 +288,8 @@ int rte_eth_dev_is_valid_port(uint8_t port_id) {if (port_id >=RTE_MAX_ETHPORTS || - rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED ) + (rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED && + rte_eth_devices[port_id].state !=RTE_ETH_DEV_DEFERRED ))return 0 ;else return 1 ;
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1652,6 +1652,7 @@ struct rte_eth_rxtx_callback {enum rte_eth_dev_state {RTE_ETH_DEV_UNUSED =0 ,RTE_ETH_DEV_ATTACHED , +RTE_ETH_DEV_DEFERRED , };/**
Signature · 1 line
2.1.4
PATCH v3 3/11 ethdev: count devices consistently
In reply to Gaetan RivetMake the rte_eth_dev_count() return the number of available devices even after some are detached by the hotplug API or put in a deferred state.
--- lib/librte_ether/rte_ethdev.c | 16 +++++++++------- lib/librte_ether/rte_ethdev.h | 13 ++++++------- 2 files changed, 15 insertions(+), 14 deletions(-)
lib/librte_ether/rte_ethdev.c +9 -7
@@ -72,7 +72,6 @@ static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS ];static struct rte_eth_dev_data *rte_eth_dev_data;static uint8_t eth_dev_last_created_port; -static uint8_t nb_ports;/* spinlock for eth device callbacks */ static rte_spinlock_t rte_eth_dev_cb_lock =RTE_SPINLOCK_INITIALIZER ;
@@ -207,7 +206,6 @@ eth_dev_get(uint8_t port_id)TAILQ_INIT (&(eth_dev->link_intr_cbs)); eth_dev_last_created_port = port_id; - nb_ports++;return eth_dev; }
@@ -280,7 +278,6 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)return -EINVAL ; eth_dev->state =RTE_ETH_DEV_UNUSED ; - nb_ports--;return 0 ; }
@@ -305,7 +302,15 @@ rte_eth_dev_socket_id(uint8_t port_id)uint8_t rte_eth_dev_count (void ) { -return nb_ports; +uint8_t p; +uint8_t count; + + count =0 ; + +RTE_ETH_FOREACH_DEV (p) + count++; + +return count; }int
@@ -337,9 +342,6 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)return -EINVAL ; } -if (!nb_ports) -return -ENODEV ; - *port_id =RTE_MAX_ETHPORTS ; RTE_ETH_FOREACH_DEV(i) { if (!strncmp(name,
lib/librte_ether/rte_ethdev.h +6 -7
@@ -1788,13 +1788,12 @@ uint8_t rte_eth_find_next(uint8_t port_id);/** * Get the total number of Ethernet devices that have been successfully -* initialized by the [matching] Ethernet driver during the PCI probing phase. -* All devices whose port identifier is in the range -* [0, rte_eth_dev_count() - 1] can be operated on by network applications -* immediately after invoking rte_eal_init(). -* If the application unplugs a port using hotplug function, The enabled port -* numbers may be noncontiguous. In the case, the applications need to manage -* enabled port by using the ``RTE_ETH_FOREACH_DEV()`` macro. +* initialized by the matching Ethernet driver during the PCI probing phase +* and that are available for applications to use. These devices must be +* accessed by using the ``RTE_ETH_FOREACH_DEV()`` macro to deal with +* non-contiguous ranges of devices. +* These non-contiguous ranges can be created by calls to hotplug functions or +* by some PMDs. * * @return * - The total number of usable Ethernet devices.
Signature · 1 line
2.1.4
PATCH v3 4/11 net/failsafe: add fail-safe PMD
In reply to Gaetan RivetIntroduce the fail-safe poll mode driver initialization and enable its build infrastructure.
This PMD allows for applications to benefit from true hot-plugging support without having to implement it.
It intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back. It also allows defining a contingency to the removal of a device, by designating a fail-over device that will take on transmitting operations if the preferred device is removed.
Applications only see a fail-safe instance, without caring for underlying activity ensuring their continued operations.
--- MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 133 +++++++ doc/guides/nics/features/failsafe.ini | 24 ++ doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 72 ++++ drivers/net/failsafe/failsafe.c | 231 +++++++++++ drivers/net/failsafe/failsafe_args.c | 331 ++++++++++++++++ drivers/net/failsafe/failsafe_eal.c | 160 ++++++++ drivers/net/failsafe/failsafe_ops.c | 663 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 227 +++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 107 ++++++ mk/rte.app.mk | 1 + 14 files changed, 1963 insertions(+) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c
MAINTAINERS +5 -0
@@ -333,6 +333,11 @@ F: drivers/net/enic/ F: doc/guides/nics/enic.rst F: doc/guides/nics/features/enic.ini +Fail-safe PMD +M: Gaetan Rivet <[email protected]> +F: drivers/net/failsafe/ +F: doc/guides/nics/fail_safe.rst + Intel e1000 M: Wenzhuo Lu <[email protected]> F: drivers/net/e1000/
config/common_base +6 -0
@@ -425,6 +425,12 @@ CONFIG_RTE_LIBRTE_PMD_XENVIRT=n CONFIG_RTE_LIBRTE_PMD_NULL=y # +# Compile fail-safe PMD +# +CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y +CONFIG_RTE_LIBRTE_PMD_FAILSAFE_DEBUG=n + +# # Do prefetch of packet data within PMD driver receive function # CONFIG_RTE_PMD_PACKET_PREFETCH=y
doc/guides/nics/fail_safe.rst new file +133 -0
133 lines not on this page · raw message
doc/guides/nics/features/failsafe.ini new file +24 -0
@@ -0,0 +1,24 @@ +; +; Supported features of the 'fail-safe' poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Link status = Y +Queue start/stop = Y +MTU update = Y +Jumbo frame = Y +Promiscuous mode = Y +Allmulticast mode = Y +Unicast MAC filter = Y +Multicast MAC filter = Y +VLAN filter = Y +Packet type parsing = Y +Basic stats = Y +Stats per queue = Y +ARMv7 = Y +ARMv8 = Y +Power8 = Y +x86-32 = Y +x86-64 = Y +Usage doc = Y
doc/guides/nics/index.rst +1 -0
@@ -64,6 +64,7 @@ Network Interface Controller Drivers vhost vmxnet3 pcap_ring + fail_safe **Figures**
drivers/net/Makefile +2 -0
@@ -59,6 +59,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena DEPDIRS-ena = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic DEPDIRS-enic = $(core-libs) librte_hash +DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe +DEPDIRS-failsafe = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k DEPDIRS-fm10k = $(core-libs) librte_hash DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
drivers/net/failsafe/Makefile new file +72 -0
72 lines not on this page · raw message
drivers/net/failsafe/failsafe.c new file +231 -0
231 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c new file +331 -0
331 lines not on this page · raw message
drivers/net/failsafe/failsafe_eal.c new file +160 -0
160 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c new file +663 -0
663 lines not on this page · raw message
drivers/net/failsafe/failsafe_private.h new file +227 -0
227 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c new file +107 -0
107 lines not on this page · raw message
mk/rte.app.mk +1 -0
@@ -120,6 +120,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += -lrte_pmd_fm10k +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += -lrte_pmd_failsafe _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
Signature · 1 line
2.1.4
PATCH v3 5/11 net/failsafe: add plug-in support
In reply to Gaetan RivetPeriodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
--- doc/guides/nics/fail_safe.rst | 19 +++ drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 71 ++++++++++ drivers/net/failsafe/failsafe_args.c | 32 +++++ drivers/net/failsafe/failsafe_eal.c | 30 +---- drivers/net/failsafe/failsafe_ether.c | 228 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 25 ++-- drivers/net/failsafe/failsafe_private.h | 60 ++++++++- 8 files changed, 423 insertions(+), 43 deletions(-) create mode 100644 drivers/net/failsafe/failsafe_ether.c
doc/guides/nics/fail_safe.rst +19 -0
@@ -102,6 +102,11 @@ Fail-safe command line parameters address is generated, that will be subsequently applied to all sub-device once they are probed. +- **hotplug_poll** parameter [UINT64] (default **2000**) + + This parameter allows the user to configure the amount of time in milliseconds + between two slave upkeep round. + Usage example ~~~~~~~~~~~~~
@@ -131,3 +136,17 @@ Care must be taken, however, to respect the **ether** API concerning device access, and in particular, using the ``RTE_ETH_FOREACH_DEV`` macro to iterate over ethernet devices, instead of directly accessing them or by writing one's own device iterator. + +Plug-in feature +--------------- + +A sub-device can be defined without existing on the system when the fail-safe +PMD is initialized. Upon probing this device, the fail-safe PMD will detect its +absence and postpone its use. It will then register for a periodic check on any +missing sub-device. + +During this time, the fail-safe PMD can be used normally, configured and told to +emit and receive packets. It will store any applied configuration, and try to +apply it upon the probing of its missing sub-device. After this configuration +pass, the new sub-device will be synchronized with other sub-devices, i.e. be +started if the fail-safe PMD has been started by the user before.
drivers/net/failsafe/Makefile +1 -0
@@ -40,6 +40,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_args.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c # No exported include files
drivers/net/failsafe/failsafe.c +71 -0
83 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c +32 -0
@@ -45,9 +45,11 @@typedef int (parse_cb )(struct rte_eth_dev *dev,const char *params,uint8_t head); +uint64_t hotplug_poll;int mac_from_arg;const char *pmd_failsafe_init_parameters[] = { +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ,PMD_FAILSAFE_MAC_KVARG ,NULL , };
@@ -221,6 +223,24 @@ fs_remove_sub_devices_definition(char params[DEVARGS_MAXLEN]) }static int +fs_get_u64_arg(const char *key __rte_unused, +const char *value,void *out) +{ +uint64_t *u64 = out; +char *endptr =NULL ; + +if ((value ==NULL ) || (out ==NULL )) +return -EINVAL ; + errno =0 ; + *u64 =strtoull (value, &endptr,0 ); +if (errno !=0 ) +return -errno; +if (endptr == value) +return -1 ; +return 0 ; +} + +static int fs_get_mac_addr_arg(const char *key __rte_unused,const char *value,void *out) {
@@ -252,6 +272,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) ret =0 ; priv->subs_tx =FAILSAFE_MAX_ETHPORTS ;/* default parameters */ + hotplug_poll =FAILSAFE_HOTPLUG_DEFAULT_TIMEOUT_MS ; mac_from_arg =0 ; n =snprintf (mut_params,sizeof (mut_params),"%s" , params);if (n >=sizeof (mut_params)) {
@@ -274,6 +295,16 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) PMD_FAILSAFE_PARAM_STRING);return -1 ; } +/* PLUG_IN event poll timer */ + arg_count =rte_kvargs_count (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ); +if (arg_count ==1 ) { + ret =rte_kvargs_process (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG , + &fs_get_u64_arg, &hotplug_poll); +if (ret <0 ) + goto free_kvlist; + }/* MAC addr */ arg_count =rte_kvargs_count (kvlist,PMD_FAILSAFE_MAC_KVARG );
@@ -287,6 +318,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) mac_from_arg =1 ; } } +PRIV (dev)->state =DEV_PARSED ; free_kvlist:rte_kvargs_free (kvlist);return ret;
drivers/net/failsafe/failsafe_eal.c +4 -26
@@ -90,37 +90,14 @@ fs_bus_init(struct rte_eth_dev *dev)int failsafe_eal_init (struct rte_eth_dev *dev) { -struct sub_device *sdev; -uint8_t i;int ret; ret =fs_bus_init (dev);if (ret)return ret; -/* -* We only update TX_SUBDEV if we are not started. -* If a sub_device is emitting, we will switch the TX_SUBDEV to the -* preferred port only upon starting it, so that the switch is smoother. -*/ -if (PREFERRED_SUBDEV (dev)->state >=DEV_PROBED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev) && - (TX_SUBDEV (dev) ==NULL || - (TX_SUBDEV (dev) &&TX_SUBDEV (dev)->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 <DEV_PROBED ) || -TX_SUBDEV (dev) ==NULL ) { -/* Using first probed device */ - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_PROBED) { -DEBUG ("Switching tx_dev to sub_device %d" , - i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_PROBED ) +PRIV (dev)->state =DEV_PROBED ; +fs_switch_dev (dev);return 0 ; }
@@ -156,5 +133,6 @@ failsafe_eal_uninit(struct rte_eth_dev *dev) ret =fs_bus_uninit (dev);if (ret)return ret; +PRIV (dev)->state =DEV_PROBED -1 ;return 0 ; }
drivers/net/failsafe/failsafe_ether.c new file +228 -0
228 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +10 -15
@@ -89,6 +89,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } sdev->state =DEV_ACTIVE ; } +if (PRIV (dev)->state <DEV_ACTIVE ) +PRIV (dev)->state =DEV_ACTIVE ;return 0 ; }
@@ -108,21 +110,9 @@ fs_dev_start(struct rte_eth_dev *dev)return ret; sdev->state =DEV_STARTED ; } -if (PREFERRED_SUBDEV (dev)->state ==DEV_STARTED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev)) { -DEBUG ("Switching tx_dev to preferred sub_device" ); -PRIV (dev)->subs_tx =0 ; - } - }else { -if ((TX_SUBDEV (dev) &&TX_SUBDEV (dev)->state <DEV_STARTED ) || -TX_SUBDEV (dev) ==NULL ) { - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) { -DEBUG ("Switching tx_dev to sub_device %d" , i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_STARTED ) +PRIV (dev)->state =DEV_STARTED ; +fs_switch_dev (dev);return 0 ; }
@@ -132,6 +122,7 @@ fs_dev_stop(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +PRIV (dev)->state =DEV_STARTED -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) {rte_eth_dev_stop (PORT_ID (sdev)); sdev->state =DEV_STARTED -1 ;
@@ -183,6 +174,10 @@ fs_dev_close(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +failsafe_hotplug_alarm_cancel (dev); +if (PRIV (dev)->state ==DEV_STARTED ) + dev->dev_ops->dev_stop (dev); +PRIV (dev)->state =DEV_ACTIVE -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) {DEBUG ("Closing sub_device %d" , i);rte_eth_dev_close (PORT_ID (sdev));
drivers/net/failsafe/failsafe_private.h +58 -2
92 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v3 6/11 net/failsafe: add flexible device definition
In reply to Gaetan RivetAdd the "exec" device type.
The parameters given to this type of device will be executed in a shell. The output of this command is then used as a definition for a device.
That command can be re-interpreted if the related device is not plugged-in. It allows for a device definition to react to system changes (e.g. changing PCI bus for a given device).
--- doc/guides/nics/fail_safe.rst | 20 +++++++ drivers/net/failsafe/failsafe_args.c | 99 +++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ether.c | 7 +++ drivers/net/failsafe/failsafe_private.h | 4 ++ 4 files changed, 130 insertions(+)
doc/guides/nics/fail_safe.rst +20 -0
@@ -91,6 +91,19 @@ Fail-safe command line parameters additional sub-device parameters if need be. They will be passed on to the sub-device. +- **exec(<shell command>)** parameter + + This parameter allows the user to provide a command to the fail-safe PMD to + execute and define a sub-device. + It is done within a regular shell context. + The first line of its output is read by the fail-safe PMD and otherwise + interpreted as if passed by the regular **dev** parameter. + Any other line is discarded. + If the command fail or output an incorrect string, the sub-device is not + initialized. + All commas within the ``shell command`` are replaced by spaces before + executing the command. This helps using scripts to specify devices. + - **mac** parameter [MAC address] This parameter allows the user to set a default MAC address to the fail-safe
@@ -126,6 +139,13 @@ This section shows some example of using **testpmd** with a fail-safe PMD. --vdev='net_failsafe0,mac=de:ad:be:ef:01:02,dev(84:00.0),dev(net_ring0,nodeaction=r1:0:CREATE)' -- \ -i +#. Start testpmd using a flexible device definition + + .. code-block:: console + + $RTE_TARGET/build/app/testpmd -c 0xff -n 4 --no-pci \ + --vdev='net_failsafe0,exec(echo 84:00.0)' -- -i + Using the Fail-safe PMD from an application -------------------------------------------
drivers/net/failsafe/failsafe_args.c +99 -0
126 lines not on this page · raw message
drivers/net/failsafe/failsafe_ether.c +7 -0
@@ -188,6 +188,13 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)int ret;uint8_t i; +if (PRIV (dev)->state <DEV_PARSED ) +return 0 ; + + ret =failsafe_args_parse_subs (dev); +if (ret) +return ret; +if (PRIV (dev)->state <DEV_PROBED )return 0 ; ret =failsafe_eal_init (dev);
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -44,6 +44,7 @@#define PMD_FAILSAFE_PLUG_IN_POLL_KVARG "hotplug_poll"#define PMD_FAILSAFE_PARAM_STRING \ "dev(<ifc>)," \ + "exec(<shell command>)," \ "mac=mac_addr," \ "hotplug_poll=u64" \ ""
@@ -87,6 +88,8 @@ struct sub_device {struct rte_eth_dev *edev;/* Device state machine */ enum dev_state state; +/* Some device are defined as a command line */ +char *cmdline; };struct fs_priv {
@@ -135,6 +138,7 @@ uint16_t failsafe_tx_burst(void *txq,int failsafe_args_parse (struct rte_eth_dev *dev,const char *params);void failsafe_args_free (struct rte_eth_dev *dev);int failsafe_args_count_subdevice (struct rte_eth_dev *dev,const char *params); +int failsafe_args_parse_subs (struct rte_eth_dev *dev);/* EAL */
Signature · 1 line
2.1.4
PATCH v3 7/11 net/failsafe: support flow API
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_eal.c | 1 + drivers/net/failsafe/failsafe_ether.c | 70 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 216 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 29 +++++ drivers/net/failsafe/failsafe_private.h | 18 +++ 8 files changed, 337 insertions(+) create mode 100644 drivers/net/failsafe/failsafe_flow.c
doc/guides/nics/features/failsafe.ini +1 -0
@@ -13,6 +13,7 @@ Allmulticast mode = Y Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y +Flow API = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/Makefile +1 -0
@@ -41,6 +41,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_flow.c # No exported include files
drivers/net/failsafe/failsafe.c +1 -0
@@ -177,6 +177,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) dev->data->mac_addrs = &PRIV (dev)->mac_addrs[0 ]; dev->data->dev_link = eth_link;PRIV (dev)->nb_mac_addr =1 ; +TAILQ_INIT (&PRIV (dev)->flow_list); dev->rx_pkt_burst = (eth_rx_burst_t)&failsafe_rx_burst; dev->tx_pkt_burst = (eth_tx_burst_t)&failsafe_tx_burst;if (params ==NULL ) {
drivers/net/failsafe/failsafe_eal.c +1 -0
@@ -80,6 +80,7 @@ fs_bus_init(struct rte_eth_dev *dev)ERROR ("sub_device %d init went wrong" , i);return -ENODEV ; } +SUB_ID (sdev) = i; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
drivers/net/failsafe/failsafe_ether.c +70 -0
90 lines not on this page · raw message
drivers/net/failsafe/failsafe_flow.c new file +216 -0
216 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +29 -0
@@ -35,6 +35,7 @@#include <stdint.h> #include <rte_ethdev.h> #include <rte_malloc.h> +#include <rte_flow.h> #include "failsafe_private.h"
@@ -628,6 +629,33 @@ fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)rte_eth_dev_default_mac_addr_set (PORT_ID (sdev), mac_addr); } +static int +fs_filter_ctrl (struct rte_eth_dev *dev, +enum rte_filter_type type, +enum rte_filter_op op, +void *arg) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + +if (type ==RTE_ETH_FILTER_GENERIC && + op ==RTE_ETH_FILTER_GET ) { + *(const void **)arg = &fs_flow_ops; +return 0 ; + } + FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) { +DEBUG ("Calling rte_eth_dev_filter_ctrl on sub_device %d" , i); + ret =rte_eth_dev_filter_ctrl (PORT_ID (sdev), type, op, arg); +if (ret) { +ERROR ("Operation rte_eth_dev_filter_ctrl failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + } +return 0 ; +} +const struct eth_dev_ops failsafe_ops = { .dev_configure = fs_dev_configure, .dev_start = fs_dev_start,
@@ -655,4 +683,5 @@ const struct eth_dev_ops failsafe_ops = { .mac_addr_remove = fs_mac_addr_remove, .mac_addr_add = fs_mac_addr_add, .mac_addr_set = fs_mac_addr_set, + .filter_ctrl = fs_filter_ctrl, };
drivers/net/failsafe/failsafe_private.h +18 -0
@@ -34,6 +34,8 @@#ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_#define _RTE_ETH_FAILSAFE_PRIVATE_H_ +#include <sys/queue.h> +#include <rte_dev.h> #include <rte_ethdev.h> #include <rte_devargs.h>
@@ -72,6 +74,14 @@ struct txq {struct rte_eth_txq_info info; }; +struct rte_flow { +TAILQ_ENTRY (rte_flow) next; +/* sub_flows */ +struct rte_flow *flows[FAILSAFE_MAX_ETHPORTS ]; +/* flow description for synchronization */ +struct rte_flow_desc *fd; +}; +enum dev_state {DEV_UNDEFINED =0 ,DEV_PARSED ,
@@ -86,6 +96,7 @@ struct sub_device {struct rte_bus *bus;struct rte_device *dev;struct rte_eth_dev *edev; +uint8_t sid;/* Device state machine */ enum dev_state state;/* Some device are defined as a command line */
@@ -104,6 +115,8 @@ struct fs_priv {uint8_t subs_tail;/* first invalid */ uint8_t subs_tx;/* current emitting device */ uint8_t current_probed; +/* flow mapping */ + TAILQ_HEAD(sub_flows, rte_flow) flow_list;/* current number of mac_addr slots allocated. */ uint32_t nb_mac_addr;struct ether_addr mac_addrs[FAILSAFE_MAX_ETHADDR ];
@@ -153,6 +166,7 @@ int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev);extern const char pmd_failsafe_driver_name[];extern const struct eth_dev_ops failsafe_ops; +extern const struct rte_flow_ops fs_flow_ops;extern uint64_t hotplug_poll;extern int mac_from_arg;
@@ -170,6 +184,10 @@ extern int mac_from_arg;#define PORT_ID (sdev) \ (ETH(sdev)->data->port_id) +/* sdev: (struct sub_device *) */ +#define SUB_ID (sdev) \ + ((sdev)->sid) +/** * Stateful iterator construct over fail-safe sub-devices: * s: (struct sub_device *), iterator
Signature · 1 line
2.1.4
PATCH v3 8/11 net/failsafe: support offload capabilities
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 6 ++ drivers/net/failsafe/failsafe_ops.c | 131 +++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-)
doc/guides/nics/features/failsafe.ini +6 -0
@@ -14,6 +14,12 @@ Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y Flow API = Y +VLAN offload = Y +QinQ offload = Y +L3 checksum offload = Y +L4 checksum offload = Y +Inner L3 checksum = Y +Inner L4 checksum = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/failsafe_ops.c +129 -2
151 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v3 9/11 net/failsafe: add fast burst functions
In reply to Gaetan Rivet--- doc/guides/nics/fail_safe.rst | 14 ++++ drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_args.c | 13 +++ drivers/net/failsafe/failsafe_eal.c | 3 +- drivers/net/failsafe/failsafe_ether.c | 93 +++++++++++++++++++-- drivers/net/failsafe/failsafe_ops.c | 38 ++++++++- drivers/net/failsafe/failsafe_private.h | 81 +++++++++++++++++-- drivers/net/failsafe/failsafe_rxtx.c | 139 +++++++++++++++++++++++++++----- 8 files changed, 343 insertions(+), 39 deletions(-)
doc/guides/nics/fail_safe.rst +14 -0
@@ -51,6 +51,12 @@ The Fail-safe PMD only supports a limited set of features. If you plan to use a device underneath the Fail-safe PMD with a specific feature, this feature must be supported by the Fail-safe PMD to avoid throwing any error. +A notable exception is the device removal feature. The fail-safe PMD being a +virtual device, it cannot currently be removed in the sense of a specific bus +hotplug, like for PCI for example. It will however enable this feature for its +sub-device automatically, detecting those that are capable and register the +relevant callback for such event. + Check the feature matrix for the complete set of supported features. Compilation options
@@ -170,3 +176,11 @@ emit and receive packets. It will store any applied configuration, and try to apply it upon the probing of its missing sub-device. After this configuration pass, the new sub-device will be synchronized with other sub-devices, i.e. be started if the fail-safe PMD has been started by the user before. + +Plug-out feature +---------------- + +A sub-device supporting the device removal event can be removed from its bus at +any time. The fail-safe PMD will register a callback for such event and react +accordingly. It will try to safely stop, close and uninit the sub-device having +emitted this event, allowing it to free its eventual resources.
drivers/net/failsafe/failsafe.c +1 -0
@@ -132,6 +132,7 @@ fs_hotplug_alarm(void *arg)if (!PRIV (dev)->pending_alarm)return ;PRIV (dev)->pending_alarm =0 ; +failsafe_dev_remove (dev); FOREACH_SUBDEV(sdev, i, dev)if (sdev->state !=PRIV (dev)->state)break ;
drivers/net/failsafe/failsafe_args.c +13 -0
@@ -443,6 +443,17 @@ failsafe_args_count_subdevice(struct rte_eth_dev *dev, dev, params); } +static int +fs_parse_sub_device (struct sub_device *sdev) +{ +struct rte_devargs *da; +char devstr[DEVARGS_MAXLEN ] ="" ; + + da = &sdev->devargs; +snprintf (devstr,sizeof (devstr),"%s,%s" , da->name, da->args); +return fs_parse_device (sdev, devstr); +} +int failsafe_args_parse_subs (struct rte_eth_dev *dev) {
@@ -455,6 +466,8 @@ failsafe_args_parse_subs(struct rte_eth_dev *dev)continue ;if (sdev->cmdline) ret =fs_execute_cmd (sdev, sdev->cmdline); +else + ret =fs_parse_sub_device (sdev);if (ret ==0 ) sdev->state =DEV_PARSED ; }
drivers/net/failsafe/failsafe_eal.c +2 -1
@@ -81,6 +81,7 @@ fs_bus_init(struct rte_eth_dev *dev)return -ENODEV ; }SUB_ID (sdev) = i; + sdev->fs_dev = dev; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
@@ -98,7 +99,7 @@ failsafe_eal_init(struct rte_eth_dev *dev)return ret;if (PRIV (dev)->state <DEV_PROBED )PRIV (dev)->state =DEV_PROBED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
drivers/net/failsafe/failsafe_ether.c +87 -6
127 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +35 -3
@@ -33,6 +33,8 @@#include <assert.h> #include <stdint.h> + +#include <rte_atomic.h> #include <rte_ethdev.h> #include <rte_malloc.h> #include <rte_flow.h>
@@ -204,9 +206,21 @@ fs_dev_configure(struct rte_eth_dev *dev) } } FOREACH_SUBDEV(sdev, i, dev) { +int rmv_interrupt =0 ; +if (sdev->state !=DEV_PROBED )continue ; + + rmv_interrupt =ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_RMV ; +if (rmv_interrupt) { +DEBUG ("Enabling RMV interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.rmv =1 ; + }else { +DEBUG ("sub_device %d does not support RMV event" , i); + }DEBUG ("Configuring sub-device %d" , i); + sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev), dev->data->nb_rx_queues, dev->data->nb_tx_queues,
@@ -215,6 +229,16 @@ fs_dev_configure(struct rte_eth_dev *dev)ERROR ("Could not configure sub_device %d" , i);return ret; } +if (rmv_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_RMV , + failsafe_eth_rmv_event_callback, + sdev); +if (ret) +WARN ("Failed to register RMV callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.rmv =0 ; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
@@ -240,7 +264,7 @@ fs_dev_start(struct rte_eth_dev *dev) }if (PRIV (dev)->state <DEV_STARTED )PRIV (dev)->state =DEV_STARTED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
@@ -351,10 +375,14 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,fs_rx_queue_release (rxq); dev->data->rx_queues[rx_queue_id] =NULL ; } - rxq =rte_zmalloc (NULL ,sizeof (*rxq), + rxq =rte_zmalloc (NULL , +sizeof (*rxq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (rxq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&rxq->refcnt[i]); rxq->qid = rx_queue_id; rxq->socket_id = socket_id; rxq->info.mp = mb_pool;
@@ -414,10 +442,14 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,fs_tx_queue_release (txq); dev->data->tx_queues[tx_queue_id] =NULL ; } - txq =rte_zmalloc ("ethdev TX queue" ,sizeof (*txq), + txq =rte_zmalloc ("ethdev TX queue" , +sizeof (*txq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (txq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&txq->refcnt[i]); txq->qid = tx_queue_id; txq->socket_id = socket_id; txq->info.conf = *tx_conf;
drivers/net/failsafe/failsafe_private.h +73 -8
164 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c +118 -21
175 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v3 10/11 net/failsafe: support link status change event
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_ether.c | 15 +++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 23 +++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 3 +++ 5 files changed, 43 insertions(+)
doc/guides/nics/features/failsafe.ini +1 -0
@@ -5,6 +5,7 @@ ; [Features] Link status = Y +Link status event = Y Queue start/stop = Y MTU update = Y Jumbo frame = Y
drivers/net/failsafe/failsafe.c +1 -0
@@ -240,6 +240,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) mac->addr_bytes[0 ], mac->addr_bytes[1 ], mac->addr_bytes[2 ], mac->addr_bytes[3 ], mac->addr_bytes[4], mac->addr_bytes[5]); + dev->data->dev_flags |=RTE_ETH_DEV_INTR_LSC ;return 0 ; free_args:failsafe_args_free (dev);
drivers/net/failsafe/failsafe_ether.c +15 -0
@@ -384,3 +384,18 @@ failsafe_eth_rmv_event_callback(uint8_t port_id __rte_unused,*/ sdev->remove =1 ; } + +void +failsafe_eth_lsc_event_callback(uint8_t port_id __rte_unused, + enum rte_eth_event_type event __rte_unused, +void *cb_arg) +{ +struct rte_eth_dev *dev = cb_arg; +int ret; + + ret = dev->dev_ops->link_update (dev,0 ); +/* We must pass on the LSC event */ +if (ret) +_rte_eth_dev_callback_process (dev,RTE_ETH_EVENT_INTR_LSC , +NULL ); +}
drivers/net/failsafe/failsafe_ops.c +23 -0
@@ -207,6 +207,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } FOREACH_SUBDEV(sdev, i, dev) {int rmv_interrupt =0 ; +int lsc_interrupt =0 ; +int lsc_enabled;if (sdev->state !=DEV_PROBED )continue ;
@@ -219,6 +221,17 @@ fs_dev_configure(struct rte_eth_dev *dev) }else {DEBUG ("sub_device %d does not support RMV event" , i); } + lsc_enabled = dev->data->dev_conf.intr_conf.lsc; + lsc_interrupt = lsc_enabled && + (ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_LSC ); +if (lsc_interrupt) { +DEBUG ("Enabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =1 ; + }else if (lsc_enabled && !lsc_interrupt) { +DEBUG ("Disabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =0 ; + }DEBUG ("Configuring sub-device %d" , i); sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev),
@@ -239,6 +252,16 @@ fs_dev_configure(struct rte_eth_dev *dev) SUB_ID(sdev)); } dev->data->dev_conf.intr_conf.rmv =0 ; +if (lsc_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_LSC , + failsafe_eth_lsc_event_callback, + dev); +if (ret) +WARN ("Failed to register LSC callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.lsc = lsc_enabled; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
drivers/net/failsafe/failsafe_private.h +3 -0
@@ -180,6 +180,9 @@ void failsafe_dev_remove(struct rte_eth_dev *dev);void failsafe_eth_rmv_event_callback (uint8_t port_id,enum rte_eth_event_type type,void *arg); +void failsafe_eth_lsc_event_callback (uint8_t port_id, +enum rte_eth_event_type event, +void *cb_arg);/* GLOBALS */
Signature · 1 line
2.1.4
PATCH v3 11/11 net/failsafe: support flow API isolation mode
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_ether.c | 12 ++++++++++++ drivers/net/failsafe/failsafe_flow.c | 29 +++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 4 ++++ 3 files changed, 45 insertions(+)
drivers/net/failsafe/failsafe_ether.c +12 -0
@@ -218,6 +218,18 @@ fs_eth_dev_conf_apply(struct rte_eth_dev *dev,DEBUG ("VLAN filter already set" ); }/* rte_flow */ +if (!PRIV (dev)->flow_isolated) { +DEBUG ("Flow isolation already disabled" ); + }else { +DEBUG ("Enabling flow isolation" ); + ret =rte_flow_isolate (PORT_ID (sdev), +PRIV (dev)->flow_isolated, + &ferror); +if (ret) { +fs_flow_complain (&ferror); +return ret; + } + }if (TAILQ_EMPTY (&PRIV (dev)->flow_list)) {DEBUG ("rte_flow already set" ); }else {
drivers/net/failsafe/failsafe_flow.c +29 -0
@@ -207,10 +207,39 @@ fs_flow_query(struct rte_eth_dev *dev,return -1 ; } +static int +fs_flow_isolate (struct rte_eth_dev *dev, +int set, +struct rte_flow_error *error) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state <DEV_PROBED ) +continue ; +DEBUG ("Calling rte_flow_isolate on sub_device %d" , i); +if (PRIV (dev)->flow_isolated != sdev->flow_isolated) +WARN ("flow isolation mode of sub_device %d in incoherent state." , + i); + ret =rte_flow_isolate (PORT_ID (sdev), set, error); +if (ret) { +ERROR ("Operation rte_flow_isolate failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + sdev->flow_isolated = set; + } +PRIV (dev)->flow_isolated = set; +return 0 ; +} +const struct rte_flow_ops fs_flow_ops = { .validate = fs_flow_validate, .create = fs_flow_create, .destroy = fs_flow_destroy, .flush = fs_flow_flush, .query = fs_flow_query, + .isolate = fs_flow_isolate, };
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -109,6 +109,8 @@ struct sub_device {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 {
@@ -140,6 +142,8 @@ struct fs_priv {*/ enum dev_state state; unsigned int pending_alarm:1; /* An alarm is pending */ +/* flow isolation state */ + int flow_isolated:1; };/* MISC */
Signature · 1 line
2.1.4
v4 cover introduce fail-safe PMD
In reply to Gaetan RivetThis PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/
ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/
ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/
v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixes
v2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.
v3 --> v4:
- Split back commits
net/failsafe: add fast burst functions net/failsafe: support device removal
That were squashed by error during a rebase
- Fix segfault on port plugin
- Fix isolate mode support for MLX4 ports plugin
Gaetan Rivet (12):
ethdev: save VLAN filter setting
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMD
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support device removal
net/failsafe: support link status change event
net/failsafe: support flow API isolation mode
MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 186 +++++++ doc/guides/nics/features/failsafe.ini | 32 ++ doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 74 +++ drivers/net/failsafe/failsafe.c | 305 +++++++++++ drivers/net/failsafe/failsafe_args.c | 475 +++++++++++++++++ drivers/net/failsafe/failsafe_eal.c | 140 +++++ drivers/net/failsafe/failsafe_ether.c | 431 ++++++++++++++++ drivers/net/failsafe/failsafe_flow.c | 245 +++++++++ drivers/net/failsafe/failsafe_ops.c | 869 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 377 ++++++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 204 ++++++++ lib/librte_ether/rte_ethdev.c | 38 +- lib/librte_ether/rte_ethdev.h | 24 +- mk/rte.app.mk | 1 + 18 files changed, 3399 insertions(+), 16 deletions(-) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ether.c create mode 100644 drivers/net/failsafe/failsafe_flow.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c
Signature · 1 line
2.1.4
PATCH v4 1/12 ethdev: save VLAN filter setting
Other configuration items (i.e. MAC addresses) are stored within rte_eth_dev_data, but not this one.
--- lib/librte_ether/rte_ethdev.c | 19 ++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +18 -1
@@ -1976,6 +1976,7 @@ int rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) { struct rte_eth_dev *dev; +int ret;RTE_ETH_VALID_PORTID_OR_ERR_RET (port_id, -ENODEV ); dev = &rte_eth_devices[port_id];
@@ -1991,7 +1992,23 @@ rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) }RTE_FUNC_PTR_OR_ERR_RET (*dev->dev_ops->vlan_filter_set, -ENOTSUP ); -return (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); + ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); +if (ret ==0 ) { +struct rte_vlan_filter_conf *vfc; +int vidx; +int vbit; + + vfc = &dev->data->vlan_filter_conf; + vidx = vlan_id /64 ; + vbit = vlan_id %64 ; + +if (on) + vfc->ids[vidx] |=UINT64_C (1 ) << vbit; +else + vfc->ids[vidx] &= ~(UINT64_C (1 ) << vbit); + } + +return ret; }int
lib/librte_ether/rte_ethdev.h +10 -0
@@ -374,6 +374,14 @@ enum rte_vlan_type { };/** +* A structure used to describe a vlan filter. +* If the bit corresponding to a VID is set, such VID is on. +*/ +struct rte_vlan_filter_conf { +uint64_t ids[64 ]; +}; + +/** * A structure used to configure the Receive Side Scaling (RSS) feature * of an Ethernet port. * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1738,6 +1746,8 @@ struct rte_eth_dev_data {enum rte_kernel_driver kdrv;/**< Kernel driver passthrough */ int numa_node;/**< NUMA node connection */ const char *drv_name;/**< Driver name */ +struct rte_vlan_filter_conf vlan_filter_conf; +/**< VLAN filter configuration. */ };/** Device supports hotplug detach */
Signature · 1 line
2.1.4
PATCH v4 2/12 ethdev: add deferred intermediate device state
In reply to Gaetan RivetThis device state means that the device is managed externally, by whichever party has set this state (PMD or application).
Note: this new device state is only an information. The related device structure and operators are still valid and can be used normally.
It is however made private by device management helpers within ethdev, making the device invisible to applications.
--- lib/librte_ether/rte_ethdev.c | 3 ++- lib/librte_ether/rte_ethdev.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +2 -1
@@ -288,7 +288,8 @@ int rte_eth_dev_is_valid_port(uint8_t port_id) {if (port_id >=RTE_MAX_ETHPORTS || - rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED ) + (rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED && + rte_eth_devices[port_id].state !=RTE_ETH_DEV_DEFERRED ))return 0 ;else return 1 ;
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1652,6 +1652,7 @@ struct rte_eth_rxtx_callback {enum rte_eth_dev_state {RTE_ETH_DEV_UNUSED =0 ,RTE_ETH_DEV_ATTACHED , +RTE_ETH_DEV_DEFERRED , };/**
Signature · 1 line
2.1.4
PATCH v4 3/12 ethdev: count devices consistently
In reply to Gaetan RivetMake the rte_eth_dev_count() return the number of available devices even after some are detached by the hotplug API or put in a deferred state.
--- lib/librte_ether/rte_ethdev.c | 16 +++++++++------- lib/librte_ether/rte_ethdev.h | 13 ++++++------- 2 files changed, 15 insertions(+), 14 deletions(-)
lib/librte_ether/rte_ethdev.c +9 -7
@@ -72,7 +72,6 @@ static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS ];static struct rte_eth_dev_data *rte_eth_dev_data;static uint8_t eth_dev_last_created_port; -static uint8_t nb_ports;/* spinlock for eth device callbacks */ static rte_spinlock_t rte_eth_dev_cb_lock =RTE_SPINLOCK_INITIALIZER ;
@@ -207,7 +206,6 @@ eth_dev_get(uint8_t port_id)TAILQ_INIT (&(eth_dev->link_intr_cbs)); eth_dev_last_created_port = port_id; - nb_ports++;return eth_dev; }
@@ -280,7 +278,6 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)return -EINVAL ; eth_dev->state =RTE_ETH_DEV_UNUSED ; - nb_ports--;return 0 ; }
@@ -305,7 +302,15 @@ rte_eth_dev_socket_id(uint8_t port_id)uint8_t rte_eth_dev_count (void ) { -return nb_ports; +uint8_t p; +uint8_t count; + + count =0 ; + +RTE_ETH_FOREACH_DEV (p) + count++; + +return count; }int
@@ -337,9 +342,6 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)return -EINVAL ; } -if (!nb_ports) -return -ENODEV ; - *port_id =RTE_MAX_ETHPORTS ; RTE_ETH_FOREACH_DEV(i) { if (!strncmp(name,
lib/librte_ether/rte_ethdev.h +6 -7
@@ -1788,13 +1788,12 @@ uint8_t rte_eth_find_next(uint8_t port_id);/** * Get the total number of Ethernet devices that have been successfully -* initialized by the [matching] Ethernet driver during the PCI probing phase. -* All devices whose port identifier is in the range -* [0, rte_eth_dev_count() - 1] can be operated on by network applications -* immediately after invoking rte_eal_init(). -* If the application unplugs a port using hotplug function, The enabled port -* numbers may be noncontiguous. In the case, the applications need to manage -* enabled port by using the ``RTE_ETH_FOREACH_DEV()`` macro. +* initialized by the matching Ethernet driver during the PCI probing phase +* and that are available for applications to use. These devices must be +* accessed by using the ``RTE_ETH_FOREACH_DEV()`` macro to deal with +* non-contiguous ranges of devices. +* These non-contiguous ranges can be created by calls to hotplug functions or +* by some PMDs. * * @return * - The total number of usable Ethernet devices.
Signature · 1 line
2.1.4
PATCH v4 4/12 net/failsafe: add fail-safe PMD
In reply to Gaetan RivetIntroduce the fail-safe poll mode driver initialization and enable its build infrastructure.
This PMD allows for applications to benefit from true hot-plugging support without having to implement it.
It intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back. It also allows defining a contingency to the removal of a device, by designating a fail-over device that will take on transmitting operations if the preferred device is removed.
Applications only see a fail-safe instance, without caring for underlying activity ensuring their continued operations.
--- MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 133 +++++++ doc/guides/nics/features/failsafe.ini | 24 ++ doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 72 ++++ drivers/net/failsafe/failsafe.c | 231 +++++++++++ drivers/net/failsafe/failsafe_args.c | 331 ++++++++++++++++ drivers/net/failsafe/failsafe_eal.c | 160 ++++++++ drivers/net/failsafe/failsafe_ops.c | 663 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 227 +++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 107 ++++++ mk/rte.app.mk | 1 + 14 files changed, 1963 insertions(+) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c
MAINTAINERS +5 -0
@@ -333,6 +333,11 @@ F: drivers/net/enic/ F: doc/guides/nics/enic.rst F: doc/guides/nics/features/enic.ini +Fail-safe PMD +M: Gaetan Rivet <[email protected]> +F: drivers/net/failsafe/ +F: doc/guides/nics/fail_safe.rst + Intel e1000 M: Wenzhuo Lu <[email protected]> F: drivers/net/e1000/
config/common_base +6 -0
@@ -425,6 +425,12 @@ CONFIG_RTE_LIBRTE_PMD_XENVIRT=n CONFIG_RTE_LIBRTE_PMD_NULL=y # +# Compile fail-safe PMD +# +CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y +CONFIG_RTE_LIBRTE_PMD_FAILSAFE_DEBUG=n + +# # Do prefetch of packet data within PMD driver receive function # CONFIG_RTE_PMD_PACKET_PREFETCH=y
doc/guides/nics/fail_safe.rst new file +133 -0
133 lines not on this page · raw message
doc/guides/nics/features/failsafe.ini new file +24 -0
@@ -0,0 +1,24 @@ +; +; Supported features of the 'fail-safe' poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Link status = Y +Queue start/stop = Y +MTU update = Y +Jumbo frame = Y +Promiscuous mode = Y +Allmulticast mode = Y +Unicast MAC filter = Y +Multicast MAC filter = Y +VLAN filter = Y +Packet type parsing = Y +Basic stats = Y +Stats per queue = Y +ARMv7 = Y +ARMv8 = Y +Power8 = Y +x86-32 = Y +x86-64 = Y +Usage doc = Y
doc/guides/nics/index.rst +1 -0
@@ -64,6 +64,7 @@ Network Interface Controller Drivers vhost vmxnet3 pcap_ring + fail_safe **Figures**
drivers/net/Makefile +2 -0
@@ -59,6 +59,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena DEPDIRS-ena = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic DEPDIRS-enic = $(core-libs) librte_hash +DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe +DEPDIRS-failsafe = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k DEPDIRS-fm10k = $(core-libs) librte_hash DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
drivers/net/failsafe/Makefile new file +72 -0
72 lines not on this page · raw message
drivers/net/failsafe/failsafe.c new file +231 -0
231 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c new file +331 -0
331 lines not on this page · raw message
drivers/net/failsafe/failsafe_eal.c new file +160 -0
160 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c new file +663 -0
663 lines not on this page · raw message
drivers/net/failsafe/failsafe_private.h new file +227 -0
227 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c new file +107 -0
107 lines not on this page · raw message
mk/rte.app.mk +1 -0
@@ -120,6 +120,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += -lrte_pmd_fm10k +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += -lrte_pmd_failsafe _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
Signature · 1 line
2.1.4
Re: [PATCH v4 04/12] net/failsafe: add fail-safe PMD
doc/guides/nics/fail_safe.rst line 36
Quoted 7 lines · On Mon, 29 May 2017 15:42:16 +0200 Gaetan Rivet <[email protected]> wrote:
doc/guides/nics/fail_safe.rst new file +7
-0+Fail-safe poll mode driver library +================================== + +The Fail-safe poll mode driver library (**librte_pmd_failsafe**) is a virtual +device that allows using any device supporting hotplug (sudden device removal +and plugging on its bus), without modifying other components relying on such +device (application, other PMDs).
What about the case of Hyper-V where the components of the Fail Safe PMD may arrive later. An example would be a NFV server that starts on boot. The synthetic device will be present at boot, but the associated VF device may be plugged in later (by checking SR-IOV on host console) or removed (by unchecking).
There doesn't appear to be a way to manage slave devices that get added and removed through CLI management model.
doc/guides/nics/fail_safe.rst line 79
Quoted 11 lines
doc/guides/nics/fail_safe.rst new file +11
-0+Using the Fail-safe PMD from the EAL command line +------------------------------------------------- + +The Fail-safe PMD can be used like most other DPDK virtual devices, by passing a +``--vdev`` parameter to the EAL when starting the application. The device name +must start with the *net_failsafe* prefix, followed by numbers or letters. This +name must be unique for each device. Each fail-safe instance must have at least one +sub-device, up to ``RTE_MAX_ETHPORTS-1``. + +A sub-device can be any legal DPDK device, including possibly another fail-safe +instance.
Configuring fail-safe (or any other device) from command line is difficult in a real world application. The EAL command line is difficult API to manipulate programmatically. Why not have a real API?
Quoted 20 lines
drivers/net/failsafe/failsafe_ops.c new file +20
-0+static int +fs_link_update (struct rte_eth_dev *dev, +int wait_to_complete) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + + FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) { +DEBUG ("Calling link_update on sub_device %d" , i); + ret = (SUBOPS (sdev, link_update))(ETH (sdev), wait_to_complete); +if (ret && ret !=-1 ) { +ERROR ("Link update failed for sub_device %d with error %d" , + i, ret); +return ret; + } + } +if (TX_SUBDEV (dev)) { +struct rte_eth_link *l1; +struct rte_eth_link *l2;
drivers/net/failsafe/failsafe_ops.c line 406
Quoted 10 lines
drivers/net/failsafe/failsafe_ops.c new file +10
-0+ + l1 = &dev->data->dev_link; + l2 = Ð (TX_SUBDEV (dev))->data->dev_link; +if (memcmp (l1, l2,sizeof (*l1))) { + *l1 = *l2; +return 0 ; + } + } +return -1 ; +}
memcmp here is a potential problem since rte_eth_link maybe padded and have holes. Why compare anyway? if *l1 == *l2 the assignment would be a nop.
What if links are down?
drivers/net/failsafe/failsafe_ops.c line 412
Quoted 5 lines
drivers/net/failsafe/failsafe_ops.c new file +5
-0+static void +fs_stats_get (struct rte_eth_dev *dev, +struct rte_eth_stats *stats) +{ +memset (stats,0 ,sizeof (*stats));
memset here is unnecessary, already done by rte_eth_stats_get
Re: [PATCH v4 04/12] net/failsafe: add fail-safe PMD
Quoted 15 lines · Stephen Hemminger
doc/guides/nics/fail_safe.rst line 36
Quoted 7 lines · On Mon, 29 May 2017 15:42:16 +0200 Gaetan Rivet <[email protected]> wrote:
doc/guides/nics/fail_safe.rst new file +7
-0+Fail-safe poll mode driver library +================================== + +The Fail-safe poll mode driver library (**librte_pmd_failsafe**) is a virtual +device that allows using any device supporting hotplug (sudden device removal +and plugging on its bus), without modifying other components relying on such +device (application, other PMDs).What about the case of Hyper-V where the components of the Fail Safe PMD may arrive later. An example would be a NFV server that starts on boot. The synthetic device will be present at boot, but the associated VF device may be plugged in later (by checking SR-IOV on host console) or removed (by unchecking).
Quoted 5 lines
There doesn't appear to be a way to manage slave devices that get added and removed through CLI management model.
The VF and the synthetic path (SP) should both be declared as slaves to the fail-safe. The SP is probed while the process fails for the VF.
The fail-safe then continues as usual, getting his infos (MAC address, capabilities) from the SP. More on that later, as you have evocated the subject in another thread.
The fail-safe detects that not all his slaves are probed and enables its plugin poll, meaning that it will detect when the VF arrives.
As the VF appears later, there is no way to know which PCI address it will be at. Thus the need for the "exec" slave declaration, which allows complex logic for slave detection.
What is necessary is a common piece of info (it can be MAC address, a class Id, anything else) that allows a script to detect that the right device has been plugged in. As long as the NFV server allows determinism here, the user will be able to use its VF.
Quoted 7 lines
Quoted 7 lines
doc/guides/nics/fail_safe.rst new file +7
-0+Using the Fail-safe PMD from the EAL command line +------------------------------------------------- + +The Fail-safe PMD can be used like most other DPDK virtual devices, by passing a +``--vdev`` parameter to the EAL when starting the application. The device name +must start with the *net_failsafe* prefix, followed by numbers or letters. This +name must be unique for each device. Each fail-safe instance must have at least one
Quoted 9 lines
doc/guides/nics/fail_safe.rst line 79
Quoted 4 lines
doc/guides/nics/fail_safe.rst new file +4
-0+sub-device, up to ``RTE_MAX_ETHPORTS-1``. + +A sub-device can be any legal DPDK device, including possibly another fail-safe +instance.Configuring fail-safe (or any other device) from command line is difficult in a real world application. The EAL command line is difficult API to manipulate programmatically. Why not have a real API?
The real API is proposed through the standard DPDK layers. You can already create a virtual device on the fly with arbitrary parameters. You can thus create a fail-safe device with several slaves.
The requirement to be able to do this however is that the bus of the slave supports the plug / unplug API. This is the case for the virtual and PCI buses.
You can try it on testpmd, using a command such as
testpmd> port attach net_failsafe0,dev(net_ring0),dev(net_ring1)
Should create a fail-safe instance with two slaves.
Finally, in a recent patchset, I introduced an rte_devargs parsing helper that should ease the creation of devices in this way. It takes a "name,devargs" string and builds an rte_devargs, that can be used in any plug/unplug implementation worth its salt.
{
struct rte_devargs da;
rte_eal_devargs_parse("net_failsafe0,dev(net_ring0)", &da); da.bus->plug(&da);
}
And you are set.
Quoted 43 lines
Quoted 20 lines
drivers/net/failsafe/failsafe_ops.c new file +20
-0+static int +fs_link_update (struct rte_eth_dev *dev, +int wait_to_complete) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + + FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) { +DEBUG ("Calling link_update on sub_device %d" , i); + ret = (SUBOPS (sdev, link_update))(ETH (sdev), wait_to_complete); +if (ret && ret !=-1 ) { +ERROR ("Link update failed for sub_device %d with error %d" , + i, ret); +return ret; + } + } +if (TX_SUBDEV (dev)) { +struct rte_eth_link *l1; +struct rte_eth_link *l2;drivers/net/failsafe/failsafe_ops.c line 406
Quoted 10 lines
drivers/net/failsafe/failsafe_ops.c new file +10
-0+ + l1 = &dev->data->dev_link; + l2 = Ð (TX_SUBDEV (dev))->data->dev_link; +if (memcmp (l1, l2,sizeof (*l1))) { + *l1 = *l2; +return 0 ; + } + } +return -1 ; +}memcmp here is a potential problem since
rte_eth_linkmaybe padded and have holes. Why compare anyway? if *l1 == *l2 the assignment would be a nop.
What if links are down?drivers/net/failsafe/failsafe_ops.c line 412
Quoted 5 lines
drivers/net/failsafe/failsafe_ops.c new file +5
-0+static void +fs_stats_get (struct rte_eth_dev *dev, +struct rte_eth_stats *stats) +{ +memset (stats,0 ,sizeof (*stats));memset here is unnecessary, already done by
rte_eth_stats_get
Signature · 2 lines
Gaëtan Rivet 6WIND
Re: [PATCH v4 04/12] net/failsafe: add fail-safe PMD
Quoted 4 lines · On Thu, 1 Jun 2017 16:01:37 +0200 Gaëtan Rivet <[email protected]> wrote:
What is necessary is a common piece of info (it can be MAC address, a class Id, anything else) that allows a script to detect that the right device has been plugged in. As long as the NFV server allows determinism here, the user will be able to use its VF.
There is a serial number property (GUID) on vmbus that is what Windows uses to associate VF and SF device. It maybe visible over sysfs.
But it make senses to put that kind of system dependent matching rule in some other place (DPDK bus logic? or external daemon).
Re: [PATCH v4 04/12] net/failsafe: add fail-safe PMD
Quoted 8 lines · Stephen Hemminger
Quoted 4 lines · On Thu, 1 Jun 2017 16:01:37 +0200 Gaëtan Rivet <[email protected]> wrote:
What is necessary is a common piece of info (it can be MAC address, a class Id, anything else) that allows a script to detect that the right device has been plugged in. As long as the NFV server allows determinism here, the user will be able to use its VF.
Quoted 5 lines
There is a serial number property (GUID) on vmbus that is what Windows uses to associate VF and SF device. It maybe visible over sysfs.
But it make senses to put that kind of system dependent matching rule in some other place (DPDK bus logic? or external daemon).
I think it might make sense to have expanded matching feature in rte_buses. For example, being able to match devices using metadatas specific to a bus, while allowing wildcards-like behavior.
Such as expressing "Probe all devices having a vendor:device id pair in such ranges", and having an "INTR_ADD" event added to mirror the "INTR_RMV" already existing.
Other possible grammar elements for device matching could be thought up, not limited to NFV servers. Once the buses have somewhat stabilized in this release or the next.
But the exec stanza allows the fail-safe to have answers for this configuration and possibly many others, at least while the buses are not capable enough.
Signature · 2 lines
Gaëtan Rivet 6WIND
PATCH v4 5/12 net/failsafe: add plug-in support
In reply to Gaetan RivetPeriodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
--- doc/guides/nics/fail_safe.rst | 19 +++ drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 71 ++++++++++ drivers/net/failsafe/failsafe_args.c | 32 +++++ drivers/net/failsafe/failsafe_eal.c | 30 +---- drivers/net/failsafe/failsafe_ether.c | 228 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 25 ++-- drivers/net/failsafe/failsafe_private.h | 60 ++++++++- 8 files changed, 423 insertions(+), 43 deletions(-) create mode 100644 drivers/net/failsafe/failsafe_ether.c
doc/guides/nics/fail_safe.rst +19 -0
@@ -102,6 +102,11 @@ Fail-safe command line parameters address is generated, that will be subsequently applied to all sub-device once they are probed. +- **hotplug_poll** parameter [UINT64] (default **2000**) + + This parameter allows the user to configure the amount of time in milliseconds + between two slave upkeep round. + Usage example ~~~~~~~~~~~~~
@@ -131,3 +136,17 @@ Care must be taken, however, to respect the **ether** API concerning device access, and in particular, using the ``RTE_ETH_FOREACH_DEV`` macro to iterate over ethernet devices, instead of directly accessing them or by writing one's own device iterator. + +Plug-in feature +--------------- + +A sub-device can be defined without existing on the system when the fail-safe +PMD is initialized. Upon probing this device, the fail-safe PMD will detect its +absence and postpone its use. It will then register for a periodic check on any +missing sub-device. + +During this time, the fail-safe PMD can be used normally, configured and told to +emit and receive packets. It will store any applied configuration, and try to +apply it upon the probing of its missing sub-device. After this configuration +pass, the new sub-device will be synchronized with other sub-devices, i.e. be +started if the fail-safe PMD has been started by the user before.
drivers/net/failsafe/Makefile +1 -0
@@ -40,6 +40,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_args.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c # No exported include files
drivers/net/failsafe/failsafe.c +71 -0
83 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c +32 -0
@@ -45,9 +45,11 @@typedef int (parse_cb )(struct rte_eth_dev *dev,const char *params,uint8_t head); +uint64_t hotplug_poll;int mac_from_arg;const char *pmd_failsafe_init_parameters[] = { +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ,PMD_FAILSAFE_MAC_KVARG ,NULL , };
@@ -221,6 +223,24 @@ fs_remove_sub_devices_definition(char params[DEVARGS_MAXLEN]) }static int +fs_get_u64_arg(const char *key __rte_unused, +const char *value,void *out) +{ +uint64_t *u64 = out; +char *endptr =NULL ; + +if ((value ==NULL ) || (out ==NULL )) +return -EINVAL ; + errno =0 ; + *u64 =strtoull (value, &endptr,0 ); +if (errno !=0 ) +return -errno; +if (endptr == value) +return -1 ; +return 0 ; +} + +static int fs_get_mac_addr_arg(const char *key __rte_unused,const char *value,void *out) {
@@ -252,6 +272,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) ret =0 ; priv->subs_tx =FAILSAFE_MAX_ETHPORTS ;/* default parameters */ + hotplug_poll =FAILSAFE_HOTPLUG_DEFAULT_TIMEOUT_MS ; mac_from_arg =0 ; n =snprintf (mut_params,sizeof (mut_params),"%s" , params);if (n >=sizeof (mut_params)) {
@@ -274,6 +295,16 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) PMD_FAILSAFE_PARAM_STRING);return -1 ; } +/* PLUG_IN event poll timer */ + arg_count =rte_kvargs_count (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ); +if (arg_count ==1 ) { + ret =rte_kvargs_process (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG , + &fs_get_u64_arg, &hotplug_poll); +if (ret <0 ) + goto free_kvlist; + }/* MAC addr */ arg_count =rte_kvargs_count (kvlist,PMD_FAILSAFE_MAC_KVARG );
@@ -287,6 +318,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) mac_from_arg =1 ; } } +PRIV (dev)->state =DEV_PARSED ; free_kvlist:rte_kvargs_free (kvlist);return ret;
drivers/net/failsafe/failsafe_eal.c +4 -26
@@ -90,37 +90,14 @@ fs_bus_init(struct rte_eth_dev *dev)int failsafe_eal_init (struct rte_eth_dev *dev) { -struct sub_device *sdev; -uint8_t i;int ret; ret =fs_bus_init (dev);if (ret)return ret; -/* -* We only update TX_SUBDEV if we are not started. -* If a sub_device is emitting, we will switch the TX_SUBDEV to the -* preferred port only upon starting it, so that the switch is smoother. -*/ -if (PREFERRED_SUBDEV (dev)->state >=DEV_PROBED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev) && - (TX_SUBDEV (dev) ==NULL || - (TX_SUBDEV (dev) &&TX_SUBDEV (dev)->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 <DEV_PROBED ) || -TX_SUBDEV (dev) ==NULL ) { -/* Using first probed device */ - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_PROBED) { -DEBUG ("Switching tx_dev to sub_device %d" , - i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_PROBED ) +PRIV (dev)->state =DEV_PROBED ; +fs_switch_dev (dev);return 0 ; }
@@ -156,5 +133,6 @@ failsafe_eal_uninit(struct rte_eth_dev *dev) ret =fs_bus_uninit (dev);if (ret)return ret; +PRIV (dev)->state =DEV_PROBED -1 ;return 0 ; }
drivers/net/failsafe/failsafe_ether.c new file +228 -0
228 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +10 -15
@@ -89,6 +89,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } sdev->state =DEV_ACTIVE ; } +if (PRIV (dev)->state <DEV_ACTIVE ) +PRIV (dev)->state =DEV_ACTIVE ;return 0 ; }
@@ -108,21 +110,9 @@ fs_dev_start(struct rte_eth_dev *dev)return ret; sdev->state =DEV_STARTED ; } -if (PREFERRED_SUBDEV (dev)->state ==DEV_STARTED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev)) { -DEBUG ("Switching tx_dev to preferred sub_device" ); -PRIV (dev)->subs_tx =0 ; - } - }else { -if ((TX_SUBDEV (dev) &&TX_SUBDEV (dev)->state <DEV_STARTED ) || -TX_SUBDEV (dev) ==NULL ) { - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) { -DEBUG ("Switching tx_dev to sub_device %d" , i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_STARTED ) +PRIV (dev)->state =DEV_STARTED ; +fs_switch_dev (dev);return 0 ; }
@@ -132,6 +122,7 @@ fs_dev_stop(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +PRIV (dev)->state =DEV_STARTED -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) {rte_eth_dev_stop (PORT_ID (sdev)); sdev->state =DEV_STARTED -1 ;
@@ -183,6 +174,10 @@ fs_dev_close(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +failsafe_hotplug_alarm_cancel (dev); +if (PRIV (dev)->state ==DEV_STARTED ) + dev->dev_ops->dev_stop (dev); +PRIV (dev)->state =DEV_ACTIVE -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) {DEBUG ("Closing sub_device %d" , i);rte_eth_dev_close (PORT_ID (sdev));
drivers/net/failsafe/failsafe_private.h +58 -2
92 lines not on this page · raw message
Signature · 1 line
2.1.4
Re: [PATCH v4 05/12] net/failsafe: add plug-in support
Quoted 6 lines · On Mon, 29 May 2017 15:42:17 +0200 Gaetan Rivet <[email protected]> wrote:
Periodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
There are existing event models (udev and netlink) that could be used to do plug-in support without polling. Polling relies on application doing rte_alarms and many don't.
Re: [PATCH v4 05/12] net/failsafe: add plug-in support
Quoted 7 lines · Stephen Hemminger
Quoted 4 lines · On Mon, 29 May 2017 15:42:17 +0200 Gaetan Rivet <[email protected]> wrote:
Periodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.
Quoted 6 lines
Quoted 2 lines
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
There are existing event models (udev and netlink) that could be used to do plug-in support without polling. Polling relies on application doing
rte_alarmsand many don't.
Indeed. This possibility arose during development.
The main issue with it however is that it introduces an asynchronous design, which the DPDK and PMDs underneath are not well-suited to interact with. It goes against the grain in a way.
The polling is simple. It can work with all models of device and is independent of event models specific to any architecture.
It also allows to simplify the contexts in which probing and removal are done. Currently there is only one, the interrupt thread. This solves a few possible race conditions without having to resort to critical sections.
The only dependency is on another DPDK subsystem, rte_alarm. I used alarms here because rte_timers need regular rte_timer_manage() calls and there is little way to guarantee the frequency of the calls.
rte_alarms do not force any externalities on applications, thus allowing a seamless use of the fail-safe.
Signature · 2 lines
Gaëtan Rivet 6WIND
Re: [PATCH v4 05/12] net/failsafe: add plug-in support
Quoted 29 lines · On Thu, 1 Jun 2017 16:12:41 +0200 Gaëtan Rivet <[email protected]> wrote:
Quoted 7 lines · Stephen Hemminger
Quoted 4 lines · On Mon, 29 May 2017 15:42:17 +0200 Gaetan Rivet <[email protected]> wrote:
Periodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.Quoted 6 lines
Quoted 2 lines
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
There are existing event models (udev and netlink) that could be used to do plug-in support without polling. Polling relies on application doing
rte_alarmsand many don't.Indeed. This possibility arose during development.
The main issue with it however is that it introduces an asynchronous design, which the DPDK and PMDs underneath are not well-suited to interact with. It goes against the grain in a way.
The polling is simple. It can work with all models of device and is independent of event models specific to any architecture.
It also allows to simplify the contexts in which probing and removal are done. Currently there is only one, the interrupt thread. This solves a few possible race conditions without having to resort to critical sections.
Quoted 7 lines
The only dependency is on another DPDK subsystem,
rte_alarm. I used alarms here becauserte_timersneed regularrte_timer_manage()calls and there is little way to guarantee the frequency of the calls.
rte_alarmsdo not force any externalities on applications, thus allowing a seamless use of the fail-safe.
The issue with rte_alarm and also with LSC interrupt callbacks is that they don't run on a normal DPDK EAL application thread. These callbacks run on a DPDK internal pthread. I remember having to do some application hacks like having the callback generate an internal event on a pipe.
Re: [PATCH v4 05/12] net/failsafe: add plug-in support
Quoted 41 lines · Stephen Hemminger
Quoted 29 lines · On Thu, 1 Jun 2017 16:12:41 +0200 Gaëtan Rivet <[email protected]> wrote:
Quoted 7 lines · Stephen Hemminger
Quoted 4 lines · On Mon, 29 May 2017 15:42:17 +0200 Gaetan Rivet <[email protected]> wrote:
Periodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.Quoted 6 lines
Quoted 2 lines
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
There are existing event models (udev and netlink) that could be used to do plug-in support without polling. Polling relies on application doing
rte_alarmsand many don't.Indeed. This possibility arose during development.
The main issue with it however is that it introduces an asynchronous design, which the DPDK and PMDs underneath are not well-suited to interact with. It goes against the grain in a way.
The polling is simple. It can work with all models of device and is independent of event models specific to any architecture.
It also allows to simplify the contexts in which probing and removal are done. Currently there is only one, the interrupt thread. This solves a few possible race conditions without having to resort to critical sections.
Quoted 7 lines
The only dependency is on another DPDK subsystem,
rte_alarm. I used alarms here becauserte_timersneed regularrte_timer_manage()calls and there is little way to guarantee the frequency of the calls.
rte_alarmsdo not force any externalities on applications, thus allowing a seamless use of the fail-safe.
Quoted 5 lines
The issue with
rte_alarmand also with LSC interrupt callbacks is that they don't run on a normal DPDK EAL application thread. These callbacks run on a DPDK internal pthread. I remember having to do some application hacks like having the callback generate an internal event on a pipe.
On the other hand, not all applications would make use of those hacks, and adding those would impose architecture elements on users. While convenient, this goes somewhat against the tool-box ethos of DPDK.
In the end, I had to leverage the existing tools. Interrupts in DPDK are a known weak point, but they are at least working and not too heavy conceptually on applications (clean threading model, no need for signal masks, etc). Better implementation might crop up at some point, if those hurdles are too much and shared by many.
Signature · 2 lines
Gaëtan Rivet 6WIND
Re: [PATCH v4 05/12] net/failsafe: add plug-in support
Quoted 52 lines · On Mon, 5 Jun 2017 01:09:19 +0200 Gaëtan Rivet <[email protected]> wrote:
Quoted 41 lines · Stephen Hemminger
Quoted 29 lines · On Thu, 1 Jun 2017 16:12:41 +0200 Gaëtan Rivet <[email protected]> wrote:
Quoted 7 lines · Stephen Hemminger
Quoted 4 lines · On Mon, 29 May 2017 15:42:17 +0200 Gaetan Rivet <[email protected]> wrote:
Periodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.Quoted 6 lines
Quoted 2 lines
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
There are existing event models (udev and netlink) that could be used to do plug-in support without polling. Polling relies on application doing
rte_alarmsand many don't.Indeed. This possibility arose during development.
The main issue with it however is that it introduces an asynchronous design, which the DPDK and PMDs underneath are not well-suited to interact with. It goes against the grain in a way.
The polling is simple. It can work with all models of device and is independent of event models specific to any architecture.
It also allows to simplify the contexts in which probing and removal are done. Currently there is only one, the interrupt thread. This solves a few possible race conditions without having to resort to critical sections.
Quoted 7 lines
The only dependency is on another DPDK subsystem,
rte_alarm. I used alarms here becauserte_timersneed regularrte_timer_manage()calls and there is little way to guarantee the frequency of the calls.
rte_alarmsdo not force any externalities on applications, thus allowing a seamless use of the fail-safe.Quoted 5 lines
The issue with
rte_alarmand also with LSC interrupt callbacks is that they don't run on a normal DPDK EAL application thread. These callbacks run on a DPDK internal pthread. I remember having to do some application hacks like having the callback generate an internal event on a pipe.On the other hand, not all applications would make use of those hacks, and adding those would impose architecture elements on users. While convenient, this goes somewhat against the tool-box ethos of DPDK.
Quoted 6 lines
In the end, I had to leverage the existing tools. Interrupts in DPDK are a known weak point, but they are at least working and not too heavy conceptually on applications (clean threading model, no need for signal masks, etc). Better implementation might crop up at some point, if those hurdles are too much and shared by many.
The alarm solution is a good intermediate step. But eventually in the spirit of the DPDK there should be option to have an event driven model. Maybe the event library will help.
For me the litmus test is can the known open source heavy weight DPDK applications like VPP work?
PATCH v4 6/12 net/failsafe: add flexible device definition
In reply to Gaetan RivetAdd the "exec" device type.
The parameters given to this type of device will be executed in a shell. The output of this command is then used as a definition for a device.
That command can be re-interpreted if the related device is not plugged-in. It allows for a device definition to react to system changes (e.g. changing PCI bus for a given device).
--- doc/guides/nics/fail_safe.rst | 20 +++++++ drivers/net/failsafe/failsafe_args.c | 99 +++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ether.c | 7 +++ drivers/net/failsafe/failsafe_private.h | 4 ++ 4 files changed, 130 insertions(+)
doc/guides/nics/fail_safe.rst +20 -0
@@ -91,6 +91,19 @@ Fail-safe command line parameters additional sub-device parameters if need be. They will be passed on to the sub-device. +- **exec(<shell command>)** parameter + + This parameter allows the user to provide a command to the fail-safe PMD to + execute and define a sub-device. + It is done within a regular shell context. + The first line of its output is read by the fail-safe PMD and otherwise + interpreted as if passed by the regular **dev** parameter. + Any other line is discarded. + If the command fail or output an incorrect string, the sub-device is not + initialized. + All commas within the ``shell command`` are replaced by spaces before + executing the command. This helps using scripts to specify devices. + - **mac** parameter [MAC address] This parameter allows the user to set a default MAC address to the fail-safe
@@ -126,6 +139,13 @@ This section shows some example of using **testpmd** with a fail-safe PMD. --vdev='net_failsafe0,mac=de:ad:be:ef:01:02,dev(84:00.0),dev(net_ring0,nodeaction=r1:0:CREATE)' -- \ -i +#. Start testpmd using a flexible device definition + + .. code-block:: console + + $RTE_TARGET/build/app/testpmd -c 0xff -n 4 --no-pci \ + --vdev='net_failsafe0,exec(echo 84:00.0)' -- -i + Using the Fail-safe PMD from an application -------------------------------------------
drivers/net/failsafe/failsafe_args.c +99 -0
126 lines not on this page · raw message
drivers/net/failsafe/failsafe_ether.c +7 -0
@@ -188,6 +188,13 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)int ret;uint8_t i; +if (PRIV (dev)->state <DEV_PARSED ) +return 0 ; + + ret =failsafe_args_parse_subs (dev); +if (ret) +return ret; +if (PRIV (dev)->state <DEV_PROBED )return 0 ; ret =failsafe_eal_init (dev);
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -44,6 +44,7 @@#define PMD_FAILSAFE_PLUG_IN_POLL_KVARG "hotplug_poll"#define PMD_FAILSAFE_PARAM_STRING \ "dev(<ifc>)," \ + "exec(<shell command>)," \ "mac=mac_addr," \ "hotplug_poll=u64" \ ""
@@ -87,6 +88,8 @@ struct sub_device {struct rte_eth_dev *edev;/* Device state machine */ enum dev_state state; +/* Some device are defined as a command line */ +char *cmdline; };struct fs_priv {
@@ -135,6 +138,7 @@ uint16_t failsafe_tx_burst(void *txq,int failsafe_args_parse (struct rte_eth_dev *dev,const char *params);void failsafe_args_free (struct rte_eth_dev *dev);int failsafe_args_count_subdevice (struct rte_eth_dev *dev,const char *params); +int failsafe_args_parse_subs (struct rte_eth_dev *dev);/* EAL */
Signature · 1 line
2.1.4
Re: [PATCH v4 06/12] net/failsafe: add flexible device definition
Quoted 4 lines · On Mon, 29 May 2017 15:42:18 +0200 Gaetan Rivet <[email protected]> wrote:
+- **exec(<shell command>)** parameter
doc/guides/nics/fail_safe.rst +2
-0+ + This parameter allows the user to provide a command to the fail-safe PMD to
doc/guides/nics/fail_safe.rst Fail-safe command line parameters · line 106
Quoted 10 lines
doc/guides/nics/fail_safe.rst +10
-0+ execute and define a sub-device. + It is done within a regular shell context. + The first line of its output is read by the fail-safe PMD and otherwise + interpreted as if passed by the regular **dev** parameter. + Any other line is discarded. + If the command fail or output an incorrect string, the sub-device is not + initialized. + All commas within the ``shell command`` are replaced by spaces before + executing the command. This helps using scripts to specify devices. +
Exec from a DPDK application seems like possible security hole since most DPDK applications have to run as root.
Quoted 12 lines
static int
drivers/net/failsafe/failsafe_args.c +11
-0+fs_execute_cmd(struct sub_device *sdev, char *cmdline) +{ + FILE *fp; +/* store possible newline as well */ +char output[DEVARGS_MAXLEN +1 ]; +size_t len; +int old_err; +int ret; + +assert (cmdline !=NULL || sdev->cmdline !=NULL ); +if (sdev->cmdline ==NULL ) {
drivers/net/failsafe/failsafe_args.c fs_parse_device(struct sub_device *sdev, char *args) · line 131
Quoted 10 lines
drivers/net/failsafe/failsafe_args.c +10
-0+char *new_str; +size_t i; + + len =strlen (cmdline) +1 ; + new_str =rte_realloc (sdev->cmdline, len, +RTE_CACHE_LINE_SIZE ); +if (new_str ==NULL ) { +ERROR ("Command line allocation failed" ); +return -ENOMEM ; + }
Using rte_malloc for cmdline is way over optimizing. rte_malloc comes from huge page area which is limited. The only reason to use it is if the memory needs to be shared by primary/slave. Also rte_malloc has much less protection (memleak checkers, guards etc) compared to regular malloc.
Re: [PATCH v4 06/12] net/failsafe: add flexible device definition
Quoted 4 lines · Stephen Hemminger
Quoted 1 line · On Mon, 29 May 2017 15:42:18 +0200 Gaetan Rivet <[email protected]> wrote:
Quoted 18 lines
doc/guides/nics/fail_safe.rst Fail-safe command line parameters · line 106
Quoted 13 lines
+- **exec(<shell command>)** parameter
doc/guides/nics/fail_safe.rst +12
-0+ + This parameter allows the user to provide a command to the fail-safe PMD to + execute and define a sub-device. + It is done within a regular shell context. + The first line of its output is read by the fail-safe PMD and otherwise + interpreted as if passed by the regular **dev** parameter. + Any other line is discarded. + If the command fail or output an incorrect string, the sub-device is not + initialized. + All commas within the ``shell command`` are replaced by spaces before + executing the command. This helps using scripts to specify devices. +Exec from a DPDK application seems like possible security hole since most DPDK applications have to run as root.
Users will run scripts or other programs that will launch fail-safe instances. If a user launches a script over the fail-safe to configure it or under it to detect devices, security seems at the same level?
Quoted 18 lines
Quoted 18 lines
static int
drivers/net/failsafe/failsafe_args.c +17
-0+fs_execute_cmd(struct sub_device *sdev, char *cmdline) +{ + FILE *fp; +/* store possible newline as well */ +char output[DEVARGS_MAXLEN +1 ]; +size_t len; +int old_err; +int ret; + +assert (cmdline !=NULL || sdev->cmdline !=NULL ); +if (sdev->cmdline ==NULL ) { +char *new_str; +size_t i; + + len =strlen (cmdline) +1 ; + new_str =rte_realloc (sdev->cmdline, len, +RTE_CACHE_LINE_SIZE );
Quoted 9 lines
drivers/net/failsafe/failsafe_args.c fs_parse_device(struct sub_device *sdev, char *args) · line 131
Quoted 4 lines
drivers/net/failsafe/failsafe_args.c +4
-0+if (new_str ==NULL ) { +ERROR ("Command line allocation failed" ); +return -ENOMEM ; + }Using
rte_mallocfor cmdline is way over optimizing.rte_malloccomes from huge page area which is limited. The only reason to use it is if the memory needs to be shared by primary/slave. Alsorte_mallochas much less protection (memleak checkers, guards etc) compared to regular malloc.
I agree, it should be changed.
Signature · 2 lines
Gaëtan Rivet 6WIND
PATCH v4 7/12 net/failsafe: support flow API
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_eal.c | 1 + drivers/net/failsafe/failsafe_ether.c | 70 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 216 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 29 +++++ drivers/net/failsafe/failsafe_private.h | 18 +++ 8 files changed, 337 insertions(+) create mode 100644 drivers/net/failsafe/failsafe_flow.c
doc/guides/nics/features/failsafe.ini +1 -0
@@ -13,6 +13,7 @@ Allmulticast mode = Y Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y +Flow API = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/Makefile +1 -0
@@ -41,6 +41,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_flow.c # No exported include files
drivers/net/failsafe/failsafe.c +1 -0
@@ -177,6 +177,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) dev->data->mac_addrs = &PRIV (dev)->mac_addrs[0 ]; dev->data->dev_link = eth_link;PRIV (dev)->nb_mac_addr =1 ; +TAILQ_INIT (&PRIV (dev)->flow_list); dev->rx_pkt_burst = (eth_rx_burst_t)&failsafe_rx_burst; dev->tx_pkt_burst = (eth_tx_burst_t)&failsafe_tx_burst;if (params ==NULL ) {
drivers/net/failsafe/failsafe_eal.c +1 -0
@@ -80,6 +80,7 @@ fs_bus_init(struct rte_eth_dev *dev)ERROR ("sub_device %d init went wrong" , i);return -ENODEV ; } +SUB_ID (sdev) = i; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
drivers/net/failsafe/failsafe_ether.c +70 -0
90 lines not on this page · raw message
drivers/net/failsafe/failsafe_flow.c new file +216 -0
216 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +29 -0
@@ -35,6 +35,7 @@#include <stdint.h> #include <rte_ethdev.h> #include <rte_malloc.h> +#include <rte_flow.h> #include "failsafe_private.h"
@@ -628,6 +629,33 @@ fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)rte_eth_dev_default_mac_addr_set (PORT_ID (sdev), mac_addr); } +static int +fs_filter_ctrl (struct rte_eth_dev *dev, +enum rte_filter_type type, +enum rte_filter_op op, +void *arg) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + +if (type ==RTE_ETH_FILTER_GENERIC && + op ==RTE_ETH_FILTER_GET ) { + *(const void **)arg = &fs_flow_ops; +return 0 ; + } + FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) { +DEBUG ("Calling rte_eth_dev_filter_ctrl on sub_device %d" , i); + ret =rte_eth_dev_filter_ctrl (PORT_ID (sdev), type, op, arg); +if (ret) { +ERROR ("Operation rte_eth_dev_filter_ctrl failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + } +return 0 ; +} +const struct eth_dev_ops failsafe_ops = { .dev_configure = fs_dev_configure, .dev_start = fs_dev_start,
@@ -655,4 +683,5 @@ const struct eth_dev_ops failsafe_ops = { .mac_addr_remove = fs_mac_addr_remove, .mac_addr_add = fs_mac_addr_add, .mac_addr_set = fs_mac_addr_set, + .filter_ctrl = fs_filter_ctrl, };
drivers/net/failsafe/failsafe_private.h +18 -0
@@ -34,6 +34,8 @@#ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_#define _RTE_ETH_FAILSAFE_PRIVATE_H_ +#include <sys/queue.h> +#include <rte_dev.h> #include <rte_ethdev.h> #include <rte_devargs.h>
@@ -72,6 +74,14 @@ struct txq {struct rte_eth_txq_info info; }; +struct rte_flow { +TAILQ_ENTRY (rte_flow) next; +/* sub_flows */ +struct rte_flow *flows[FAILSAFE_MAX_ETHPORTS ]; +/* flow description for synchronization */ +struct rte_flow_desc *fd; +}; +enum dev_state {DEV_UNDEFINED =0 ,DEV_PARSED ,
@@ -86,6 +96,7 @@ struct sub_device {struct rte_bus *bus;struct rte_device *dev;struct rte_eth_dev *edev; +uint8_t sid;/* Device state machine */ enum dev_state state;/* Some device are defined as a command line */
@@ -104,6 +115,8 @@ struct fs_priv {uint8_t subs_tail;/* first invalid */ uint8_t subs_tx;/* current emitting device */ uint8_t current_probed; +/* flow mapping */ + TAILQ_HEAD(sub_flows, rte_flow) flow_list;/* current number of mac_addr slots allocated. */ uint32_t nb_mac_addr;struct ether_addr mac_addrs[FAILSAFE_MAX_ETHADDR ];
@@ -153,6 +166,7 @@ int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev);extern const char pmd_failsafe_driver_name[];extern const struct eth_dev_ops failsafe_ops; +extern const struct rte_flow_ops fs_flow_ops;extern uint64_t hotplug_poll;extern int mac_from_arg;
@@ -170,6 +184,10 @@ extern int mac_from_arg;#define PORT_ID (sdev) \ (ETH(sdev)->data->port_id) +/* sdev: (struct sub_device *) */ +#define SUB_ID (sdev) \ + ((sdev)->sid) +/** * Stateful iterator construct over fail-safe sub-devices: * s: (struct sub_device *), iterator
Signature · 1 line
2.1.4
Re: [PATCH v4 07/12] net/failsafe: support flow API
Quoted 13 lines · On Mon, 29 May 2017 15:42:19 +0200 Gaetan Rivet <[email protected]> wrote:
Signed-off-by Gaetan Rivet <[email protected]>Acked-by Olga Shern <[email protected]>--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_eal.c | 1 + drivers/net/failsafe/failsafe_ether.c | 70 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 216 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 29 +++++ drivers/net/failsafe/failsafe_private.h | 18 +++ 8 files changed, 337 insertions(+) create mode 100644 drivers/net/failsafe/failsafe_flow.c
How does this interact with typical case of VF and dumb virtual device? The VF has flow API but dumb virtual device does not.
How does this work with late binding plugin? If VF arrives later is the flow table reprogrammed to the VF?
Re: [PATCH v4 07/12] net/failsafe: support flow API
Quoted 17 lines · Stephen Hemminger
Quoted 13 lines · On Mon, 29 May 2017 15:42:19 +0200 Gaetan Rivet <[email protected]> wrote:
Signed-off-by Gaetan Rivet <[email protected]>Acked-by Olga Shern <[email protected]>--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_eal.c | 1 + drivers/net/failsafe/failsafe_ether.c | 70 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 216 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 29 +++++ drivers/net/failsafe/failsafe_private.h | 18 +++ 8 files changed, 337 insertions(+) create mode 100644 drivers/net/failsafe/failsafe_flow.c
Quoted 3 lines
How does this interact with typical case of VF and dumb virtual device? The VF has flow API but dumb virtual device does not.
The fail-safe requires capabilities to be the same on all its slave. If a capability must be supported on the VF, then is should be as well on the synthetic path.
But the TAP PMD that can be used to capture traffic from a synthetic path supports rte_flow in the same capacity as other NICs.
Quoted 2 lines
How does this work with late binding plugin? If VF arrives later is the flow table reprogrammed to the VF?
The fail-safe stores an internal representation of rte_flows. These are replayed in the same order upon plugin, so the flow table is reprogrammed in the same way to the VF.
Signature · 2 lines
Gaëtan Rivet 6WIND
Re: [PATCH v4 07/12] net/failsafe: support flow API
Quoted 29 lines · On Thu, 1 Jun 2017 16:28:13 +0200 Gaëtan Rivet <[email protected]> wrote:
Quoted 17 lines · Stephen Hemminger
Quoted 13 lines · On Mon, 29 May 2017 15:42:19 +0200 Gaetan Rivet <[email protected]> wrote:
Signed-off-by Gaetan Rivet <[email protected]>Acked-by Olga Shern <[email protected]>--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_eal.c | 1 + drivers/net/failsafe/failsafe_ether.c | 70 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 216 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 29 +++++ drivers/net/failsafe/failsafe_private.h | 18 +++ 8 files changed, 337 insertions(+) create mode 100644 drivers/net/failsafe/failsafe_flow.cQuoted 3 lines
How does this interact with typical case of VF and dumb virtual device? The VF has flow API but dumb virtual device does not.
The fail-safe requires capabilities to be the same on all its slave. If a capability must be supported on the VF, then is should be as well on the synthetic path.
But the TAP PMD that can be used to capture traffic from a synthetic path supports
rte_flowin the same capacity as other NICs.
Quoted 7 lines
Quoted 2 lines
How does this work with late binding plugin? If VF arrives later is the flow table reprogrammed to the VF?
The fail-safe stores an internal representation of
rte_flows. These are replayed in the same order upon plugin, so the flow table is reprogrammed in the same way to the VF.
The synthetic path can't do flow direction in netvsc (and via tap). Therefore this whole flow direction part is uninteresting for the use case of Hyper-V/Azure.
PATCH v4 8/12 net/failsafe: support offload capabilities
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 6 ++ drivers/net/failsafe/failsafe_ops.c | 131 +++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-)
doc/guides/nics/features/failsafe.ini +6 -0
@@ -14,6 +14,12 @@ Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y Flow API = Y +VLAN offload = Y +QinQ offload = Y +L3 checksum offload = Y +L4 checksum offload = Y +Inner L3 checksum = Y +Inner L4 checksum = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/failsafe_ops.c +129 -2
151 lines not on this page · raw message
Signature · 1 line
2.1.4
Re: [PATCH v4 08/12] net/failsafe: support offload capabilities
Quoted 6 lines · On Mon, 29 May 2017 15:42:20 +0200 Gaetan Rivet <[email protected]> wrote:
Signed-off-by Gaetan Rivet <[email protected]>Acked-by Olga Shern <[email protected]>--- doc/guides/nics/features/failsafe.ini | 6 ++ drivers/net/failsafe/failsafe_ops.c | 131 +++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-)
Once again what about case of dumb synthetic NIC combined with SR-IOV VF? The VF has offloads the virtual NIC does not.
What about late plugin. how do you program the offloads of the later arriving VF device.
Re: [PATCH v4 08/12] net/failsafe: support offload capabilities
Quoted 10 lines · Stephen Hemminger
Quoted 6 lines · On Mon, 29 May 2017 15:42:20 +0200 Gaetan Rivet <[email protected]> wrote:
Signed-off-by Gaetan Rivet <[email protected]>Acked-by Olga Shern <[email protected]>--- doc/guides/nics/features/failsafe.ini | 6 ++ drivers/net/failsafe/failsafe_ops.c | 131 +++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-)
Quoted 3 lines
Once again what about case of dumb synthetic NIC combined with SR-IOV VF? The VF has offloads the virtual NIC does not.
The rules for capabilities are a little complicated.
In the case both VF and the virtual NIC are present at launch, then the logical AND is done both their capabilities sets.
If one has additional capabilities that the user is requesting, and the fail-safe recognize them (currently, all RX offloads, as TX offloads were not yet expressed by flags), and this capability is not supported by one slave, then this offload is disabled in the configuration.
Quoted 2 lines
What about late plugin. how do you program the offloads of the later arriving VF device.
If the VF is not present at launch, then the fail-safe reads only the set of capabilities from the fallback device. It does not have to do any AND-ing of the flags.
The consequence is that upon plugin of the VF, the latter has to respect the current running configuration. Probing will actually fail if some capability is not supported (depending on PMDs), and the running configuration is not updated as it is considered "live".
There are only two solutions to this, either:
* Complicate a lot the fail-safe design and the rules applied in the decision made on NIC configuration. The user then has bad surprises upon seeing that his performance have been degraded for arcane reasons.
* Emulate in software the offloads and try to advertize as many as possible. This is done for example in the TAP PMD for some flags, allowing those offloads to be used with hardware NICs.
The user then has a clear view of the available offloads by comparing both sets of capabilities.
Signature · 2 lines
Gaëtan Rivet 6WIND
Re: [PATCH v4 08/12] net/failsafe: support offload capabilities
L;w
Quoted 61 lines
-----Original Message-----
From: dev [mailto:[email protected]] On Behalf Of Gaëtan Rivet
Sent: Thursday, June 01, 2017 5:38 PM
To: Stephen Hemminger <[email protected]>
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v4 08/12] net/failsafe: support offload capabilitiesQuoted 8 lines · Stephen Hemminger
Quoted 5 lines · On Mon, 29 May 2017 15:42:20 +0200 Gaetan Rivet <[email protected]> wrote:
Signed-off-by Gaetan Rivet <[email protected]>Acked-by Olga Shern <[email protected]>--- doc/guides/nics/features/failsafe.ini | 6 ++ drivers/net/failsafe/failsafe_ops.c | 131+++++++++++++++++++++++++++++++++-
Quoted 3 lines
Quoted 1 line
2 files changed, 135 insertions(+), 2 deletions(-)Once again what about case of dumb synthetic NIC combined with SR-IOV
VF?
Quoted 2 lines
The VF has offloads the virtual NIC does not.
The rules for capabilities are a little complicated.
In the case both VF and the virtual NIC are present at launch, then the logical AND is done both their capabilities sets.
If one has additional capabilities that the user is requesting, and the fail-safe recognize them (currently, all RX offloads, as TX offloads were not yet expressed by flags), and this capability is not supported by one slave, then this offload is disabled in the configuration.Quoted 2 lines
What about late plugin. how do you program the offloads of the later arriving VF device.
If the VF is not present at launch, then the fail-safe reads only the set of capabilities from the fallback device. It does not have to do any AND-ing of the flags.
The consequence is that upon plugin of the VF, the latter has to respect the current running configuration. Probing will actually fail if some capability is not supported (depending on PMDs), and the running configuration is not updated as it is considered "live".
There are only two solutions to this, either:
* Complicate a lot the fail-safe design and the rules applied in the decision made on NIC configuration. The user then has bad surprises upon seeing that his performance have been degraded for arcane reasons.
* Emulate in software the offloads and try to advertize as many as possible. This is done for example in the TAP PMD for some flags, allowing those offloads to be used with hardware NICs.
The user then has a clear view of the available offloads by comparing both sets of capabilities.--
Gaëtan Rivet
6WIND
PATCH v4 9/12 net/failsafe: add fast burst functions
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_private.h | 8 +++ drivers/net/failsafe/failsafe_rxtx.c | 124 ++++++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 20 deletions(-)
drivers/net/failsafe/failsafe_private.h +8 -0
@@ -141,11 +141,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);
@@ -299,6 +306,7 @@ fs_switch_dev(struct rte_eth_dev *dev) }else {return ; } +set_burst_fn (dev,0 );rte_wmb (); }
drivers/net/failsafe/failsafe_rxtx.c +104 -20
154 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v4 10/12 net/failsafe: support device removal
In reply to Gaetan RivetListen to INTR_RMV events issued by slaves.
Add atomic flags on slave queues to detect use of slave bursts function. If a removal is detected, set the recollection flag on this slave.
During a slave upkeep round, if its recollection flag is set and its burst functions are not in use by any thread, remove that slave.
--- doc/guides/nics/fail_safe.rst | 14 +++++ drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_args.c | 13 +++++ drivers/net/failsafe/failsafe_eal.c | 3 +- drivers/net/failsafe/failsafe_ether.c | 93 ++++++++++++++++++++++++++++++--- drivers/net/failsafe/failsafe_ops.c | 38 ++++++++++++-- drivers/net/failsafe/failsafe_private.h | 73 +++++++++++++++++++++++--- drivers/net/failsafe/failsafe_rxtx.c | 17 +++++- 8 files changed, 232 insertions(+), 20 deletions(-)
doc/guides/nics/fail_safe.rst +14 -0
@@ -51,6 +51,12 @@ The Fail-safe PMD only supports a limited set of features. If you plan to use a device underneath the Fail-safe PMD with a specific feature, this feature must be supported by the Fail-safe PMD to avoid throwing any error. +A notable exception is the device removal feature. The fail-safe PMD being a +virtual device, it cannot currently be removed in the sense of a specific bus +hotplug, like for PCI for example. It will however enable this feature for its +sub-device automatically, detecting those that are capable and register the +relevant callback for such event. + Check the feature matrix for the complete set of supported features. Compilation options
@@ -170,3 +176,11 @@ emit and receive packets. It will store any applied configuration, and try to apply it upon the probing of its missing sub-device. After this configuration pass, the new sub-device will be synchronized with other sub-devices, i.e. be started if the fail-safe PMD has been started by the user before. + +Plug-out feature +---------------- + +A sub-device supporting the device removal event can be removed from its bus at +any time. The fail-safe PMD will register a callback for such event and react +accordingly. It will try to safely stop, close and uninit the sub-device having +emitted this event, allowing it to free its eventual resources.
drivers/net/failsafe/failsafe.c +1 -0
@@ -132,6 +132,7 @@ fs_hotplug_alarm(void *arg)if (!PRIV (dev)->pending_alarm)return ;PRIV (dev)->pending_alarm =0 ; +failsafe_dev_remove (dev); FOREACH_SUBDEV(sdev, i, dev)if (sdev->state !=PRIV (dev)->state)break ;
drivers/net/failsafe/failsafe_args.c +13 -0
@@ -443,6 +443,17 @@ failsafe_args_count_subdevice(struct rte_eth_dev *dev, dev, params); } +static int +fs_parse_sub_device (struct sub_device *sdev) +{ +struct rte_devargs *da; +char devstr[DEVARGS_MAXLEN ] ="" ; + + da = &sdev->devargs; +snprintf (devstr,sizeof (devstr),"%s,%s" , da->name, da->args); +return fs_parse_device (sdev, devstr); +} +int failsafe_args_parse_subs (struct rte_eth_dev *dev) {
@@ -455,6 +466,8 @@ failsafe_args_parse_subs(struct rte_eth_dev *dev)continue ;if (sdev->cmdline) ret =fs_execute_cmd (sdev, sdev->cmdline); +else + ret =fs_parse_sub_device (sdev);if (ret ==0 ) sdev->state =DEV_PARSED ; }
drivers/net/failsafe/failsafe_eal.c +2 -1
@@ -81,6 +81,7 @@ fs_bus_init(struct rte_eth_dev *dev)return -ENODEV ; }SUB_ID (sdev) = i; + sdev->fs_dev = dev; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
@@ -98,7 +99,7 @@ failsafe_eal_init(struct rte_eth_dev *dev)return ret;if (PRIV (dev)->state <DEV_PROBED )PRIV (dev)->state =DEV_PROBED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
drivers/net/failsafe/failsafe_ether.c +87 -6
127 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +35 -3
@@ -33,6 +33,8 @@#include <assert.h> #include <stdint.h> + +#include <rte_atomic.h> #include <rte_ethdev.h> #include <rte_malloc.h> #include <rte_flow.h>
@@ -204,9 +206,21 @@ fs_dev_configure(struct rte_eth_dev *dev) } } FOREACH_SUBDEV(sdev, i, dev) { +int rmv_interrupt =0 ; +if (sdev->state !=DEV_PROBED )continue ; + + rmv_interrupt =ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_RMV ; +if (rmv_interrupt) { +DEBUG ("Enabling RMV interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.rmv =1 ; + }else { +DEBUG ("sub_device %d does not support RMV event" , i); + }DEBUG ("Configuring sub-device %d" , i); + sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev), dev->data->nb_rx_queues, dev->data->nb_tx_queues,
@@ -215,6 +229,16 @@ fs_dev_configure(struct rte_eth_dev *dev)ERROR ("Could not configure sub_device %d" , i);return ret; } +if (rmv_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_RMV , + failsafe_eth_rmv_event_callback, + sdev); +if (ret) +WARN ("Failed to register RMV callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.rmv =0 ; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
@@ -240,7 +264,7 @@ fs_dev_start(struct rte_eth_dev *dev) }if (PRIV (dev)->state <DEV_STARTED )PRIV (dev)->state =DEV_STARTED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
@@ -351,10 +375,14 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,fs_rx_queue_release (rxq); dev->data->rx_queues[rx_queue_id] =NULL ; } - rxq =rte_zmalloc (NULL ,sizeof (*rxq), + rxq =rte_zmalloc (NULL , +sizeof (*rxq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (rxq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&rxq->refcnt[i]); rxq->qid = rx_queue_id; rxq->socket_id = socket_id; rxq->info.mp = mb_pool;
@@ -414,10 +442,14 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,fs_tx_queue_release (txq); dev->data->tx_queues[tx_queue_id] =NULL ; } - txq =rte_zmalloc ("ethdev TX queue" ,sizeof (*txq), + txq =rte_zmalloc ("ethdev TX queue" , +sizeof (*txq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (txq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&txq->refcnt[i]); txq->qid = tx_queue_id; txq->socket_id = socket_id; txq->info.conf = *tx_conf;
drivers/net/failsafe/failsafe_private.h +65 -8
140 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c +15 -2
@@ -33,6 +33,7 @@#include <assert.h> +#include <rte_atomic.h> #include <rte_mbuf.h> #include <rte_ethdev.h>
@@ -113,8 +114,10 @@ failsafe_rx_burst(void *queue,if (unlikely (fs_rx_unsafe (sdev)))continue ; sub_rxq =ETH (sdev)->data->rx_queues[rxq->qid]; +FS_ATOMIC_P (rxq->refcnt[sdev->sid]); nb_rx =ETH (sdev)->rx_pkt_burst (sub_rxq, rx_pkts, nb_pkts); +FS_ATOMIC_V (rxq->refcnt[sdev->sid]);if (nb_rx) { rxq->last_polled = i;return nb_rx;
@@ -147,8 +150,10 @@ failsafe_rx_burst_fast(void *queue, sdev = &priv->subs[i];assert (!fs_rx_unsafe (sdev)); sub_rxq =ETH (sdev)->data->rx_queues[rxq->qid]; +FS_ATOMIC_P (rxq->refcnt[sdev->sid]); nb_rx =ETH (sdev)->rx_pkt_burst (sub_rxq, rx_pkts, nb_pkts); +FS_ATOMIC_V (rxq->refcnt[sdev->sid]);if (nb_rx) { rxq->last_polled = i;return nb_rx;
@@ -165,13 +170,17 @@ failsafe_tx_burst(void *queue,struct sub_device *sdev;struct txq *txq;void *sub_txq; +uint16_t nb_tx; txq = queue; sdev =TX_SUBDEV (txq->priv->dev);if (unlikely (fs_tx_unsafe (sdev)))return 0 ; sub_txq =ETH (sdev)->data->tx_queues[txq->qid]; -return ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_P (txq->refcnt[sdev->sid]); + nb_tx =ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_V (txq->refcnt[sdev->sid]); +return nb_tx; }uint16_t
@@ -182,10 +191,14 @@ failsafe_tx_burst_fast(void *queue,struct sub_device *sdev;struct txq *txq;void *sub_txq; +uint16_t nb_tx; txq = queue; sdev =TX_SUBDEV (txq->priv->dev);assert (!fs_tx_unsafe (sdev)); sub_txq =ETH (sdev)->data->tx_queues[txq->qid]; -return ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_P (txq->refcnt[sdev->sid]); + nb_tx =ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_V (txq->refcnt[sdev->sid]); +return nb_tx; }
Signature · 1 line
2.1.4
PATCH v4 11/12 net/failsafe: support link status change event
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_ether.c | 15 +++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 23 +++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 3 +++ 5 files changed, 43 insertions(+)
doc/guides/nics/features/failsafe.ini +1 -0
@@ -5,6 +5,7 @@ ; [Features] Link status = Y +Link status event = Y Queue start/stop = Y MTU update = Y Jumbo frame = Y
drivers/net/failsafe/failsafe.c +1 -0
@@ -240,6 +240,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) mac->addr_bytes[0 ], mac->addr_bytes[1 ], mac->addr_bytes[2 ], mac->addr_bytes[3 ], mac->addr_bytes[4], mac->addr_bytes[5]); + dev->data->dev_flags |=RTE_ETH_DEV_INTR_LSC ;return 0 ; free_args:failsafe_args_free (dev);
drivers/net/failsafe/failsafe_ether.c +15 -0
@@ -384,3 +384,18 @@ failsafe_eth_rmv_event_callback(uint8_t port_id __rte_unused,*/ sdev->remove =1 ; } + +void +failsafe_eth_lsc_event_callback(uint8_t port_id __rte_unused, + enum rte_eth_event_type event __rte_unused, +void *cb_arg) +{ +struct rte_eth_dev *dev = cb_arg; +int ret; + + ret = dev->dev_ops->link_update (dev,0 ); +/* We must pass on the LSC event */ +if (ret) +_rte_eth_dev_callback_process (dev,RTE_ETH_EVENT_INTR_LSC , +NULL ); +}
drivers/net/failsafe/failsafe_ops.c +23 -0
@@ -207,6 +207,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } FOREACH_SUBDEV(sdev, i, dev) {int rmv_interrupt =0 ; +int lsc_interrupt =0 ; +int lsc_enabled;if (sdev->state !=DEV_PROBED )continue ;
@@ -219,6 +221,17 @@ fs_dev_configure(struct rte_eth_dev *dev) }else {DEBUG ("sub_device %d does not support RMV event" , i); } + lsc_enabled = dev->data->dev_conf.intr_conf.lsc; + lsc_interrupt = lsc_enabled && + (ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_LSC ); +if (lsc_interrupt) { +DEBUG ("Enabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =1 ; + }else if (lsc_enabled && !lsc_interrupt) { +DEBUG ("Disabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =0 ; + }DEBUG ("Configuring sub-device %d" , i); sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev),
@@ -239,6 +252,16 @@ fs_dev_configure(struct rte_eth_dev *dev) SUB_ID(sdev)); } dev->data->dev_conf.intr_conf.rmv =0 ; +if (lsc_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_LSC , + failsafe_eth_lsc_event_callback, + dev); +if (ret) +WARN ("Failed to register LSC callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.lsc = lsc_enabled; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
drivers/net/failsafe/failsafe_private.h +3 -0
@@ -180,6 +180,9 @@ void failsafe_dev_remove(struct rte_eth_dev *dev);void failsafe_eth_rmv_event_callback (uint8_t port_id,enum rte_eth_event_type type,void *arg); +void failsafe_eth_lsc_event_callback (uint8_t port_id, +enum rte_eth_event_type event, +void *cb_arg);/* GLOBALS */
Signature · 1 line
2.1.4
PATCH v4 12/12 net/failsafe: support flow API isolation mode
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_ether.c | 34 +++++++++++++++++++++++++++++++-- drivers/net/failsafe/failsafe_flow.c | 29 ++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 4 ++++ 3 files changed, 65 insertions(+), 2 deletions(-)
drivers/net/failsafe/failsafe_ether.c +32 -2
@@ -74,6 +74,28 @@ fs_flow_complain(struct rte_flow_error *error) }static int +eth_dev_flow_isolate_set (struct rte_eth_dev *dev, +struct sub_device *sdev) +{ +struct rte_flow_error ferror; +int ret; + +if (!PRIV (dev)->flow_isolated) { +DEBUG ("Flow isolation already disabled" ); + }else { +DEBUG ("Enabling flow isolation" ); + ret =rte_flow_isolate (PORT_ID (sdev), +PRIV (dev)->flow_isolated, + &ferror); +if (ret) { +fs_flow_complain (&ferror); +return ret; + } + } +return 0 ; +} + +static int fs_eth_dev_conf_apply (struct rte_eth_dev *dev,struct sub_device *sdev) {
@@ -331,9 +353,17 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)if (PRIV (dev)->state <DEV_ACTIVE )return 0 ; inactive =0 ; - FOREACH_SUBDEV(sdev, i, dev) -if (sdev->state ==DEV_PROBED ) + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state ==DEV_PROBED ) { inactive |=UINT32_C (1 ) << i; + ret =eth_dev_flow_isolate_set (dev, sdev); +if (ret) { +ERROR ("Could not apply configuration to sub_device %d" , + i); + goto err_remove; + } + } + } ret = dev->dev_ops->dev_configure (dev);if (ret) goto err_remove;
drivers/net/failsafe/failsafe_flow.c +29 -0
@@ -207,10 +207,39 @@ fs_flow_query(struct rte_eth_dev *dev,return -1 ; } +static int +fs_flow_isolate (struct rte_eth_dev *dev, +int set, +struct rte_flow_error *error) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state <DEV_PROBED ) +continue ; +DEBUG ("Calling rte_flow_isolate on sub_device %d" , i); +if (PRIV (dev)->flow_isolated != sdev->flow_isolated) +WARN ("flow isolation mode of sub_device %d in incoherent state." , + i); + ret =rte_flow_isolate (PORT_ID (sdev), set, error); +if (ret) { +ERROR ("Operation rte_flow_isolate failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + sdev->flow_isolated = set; + } +PRIV (dev)->flow_isolated = set; +return 0 ; +} +const struct rte_flow_ops fs_flow_ops = { .validate = fs_flow_validate, .create = fs_flow_create, .destroy = fs_flow_destroy, .flush = fs_flow_flush, .query = fs_flow_query, + .isolate = fs_flow_isolate, };
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -109,6 +109,8 @@ struct sub_device {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 {
@@ -140,6 +142,8 @@ struct fs_priv {*/ enum dev_state state; unsigned int pending_alarm:1; /* An alarm is pending */ +/* flow isolation state */ + int flow_isolated:1; };/* MISC */
Signature · 1 line
2.1.4
Quoted 64 lines · Gaetan Rivet
This PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixesv2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.v3 --> v4:
- Split back commits
net/failsafe: add fast burst functions net/failsafe: support device removal
That were squashed by error during a rebase
- Fix segfault on port plugin
- Fix isolate mode support for MLX4 ports plugin
Quoted 13 lines
Gaetan Rivet (12):
ethdev: save VLAN filter setting
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMD
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support device removal
net/failsafe: support link status change event
net/failsafe: support flow API isolation mode
Bruce, Neil,
Any comment on to the latest version of the PMD?
Thomas,
Should this discussed in the tech-board, again for this release?
Thanks,
ferruh
Quoted 1 line · On Mon, 29 May 2017 15:03:40 +0100 Ferruh Yigit <[email protected]> wrote:
Should this discussed in the tech-board, again for this release?
The primary discussion area should be the mailing list not the tech board. Comments in public please.
Quoted 100 lines · On Mon, 29 May 2017 15:42:12 +0200 Gaetan Rivet <[email protected]> wrote:
This PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixesv2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.v3 --> v4:
- Split back commits
net/failsafe: add fast burst functions net/failsafe: support device removal
That were squashed by error during a rebase
- Fix segfault on port plugin
- Fix isolate mode support for MLX4 ports pluginGaetan Rivet (12):
ethdev: save VLAN filter setting
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMD
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support device removal
net/failsafe: support link status change event
net/failsafe: support flow API isolation modeMAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 186 +++++++ doc/guides/nics/features/failsafe.ini | 32 ++ doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 74 +++ drivers/net/failsafe/failsafe.c | 305 +++++++++++ drivers/net/failsafe/failsafe_args.c | 475 +++++++++++++++++ drivers/net/failsafe/failsafe_eal.c | 140 +++++ drivers/net/failsafe/failsafe_ether.c | 431 ++++++++++++++++ drivers/net/failsafe/failsafe_flow.c | 245 +++++++++ drivers/net/failsafe/failsafe_ops.c | 869 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 377 ++++++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 204 ++++++++ lib/librte_ether/rte_ethdev.c | 38 +- lib/librte_ether/rte_ethdev.h | 24 +- mk/rte.app.mk | 1 + 18 files changed, 3399 insertions(+), 16 deletions(-) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile
Quoted 9 lines
create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ether.c create mode 100644 drivers/net/failsafe/failsafe_flow.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c
Discussed in tech-board meeting and accepted for inclusion in 17.08 release. Longer term this driver would benefit from better hot plug support
v5 cover introduce fail-safe PMD
In reply to Gaetan RivetThis PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/
ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/
ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/
v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixes
v2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.
v3 --> v4:
- Split back commits
net/failsafe: add fast burst functions net/failsafe: support device removal
That were squashed by error during a rebase
- Fix segfault on port plugin
- Fix isolate mode support for MLX4 ports plugin
v4 --> v5:
- Follow new plug / unplug API.
Gaetan Rivet (12):
ethdev: save VLAN filter setting
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMD
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support device removal
net/failsafe: support link status change event
net/failsafe: support flow API isolation mode
MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 186 +++++++ doc/guides/nics/features/failsafe.ini | 32 ++ doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 74 +++ drivers/net/failsafe/failsafe.c | 305 +++++++++++ drivers/net/failsafe/failsafe_args.c | 475 +++++++++++++++++ drivers/net/failsafe/failsafe_eal.c | 143 ++++++ drivers/net/failsafe/failsafe_ether.c | 430 ++++++++++++++++ drivers/net/failsafe/failsafe_flow.c | 245 +++++++++ drivers/net/failsafe/failsafe_ops.c | 869 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 376 ++++++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 204 ++++++++ lib/librte_ether/rte_ethdev.c | 38 +- lib/librte_ether/rte_ethdev.h | 24 +- mk/rte.app.mk | 1 + 18 files changed, 3400 insertions(+), 16 deletions(-) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ether.c create mode 100644 drivers/net/failsafe/failsafe_flow.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c
Signature · 1 line
2.1.4
PATCH v5 1/12 ethdev: save VLAN filter setting
Other configuration items (i.e. MAC addresses) are stored within rte_eth_dev_data, but not this one.
--- lib/librte_ether/rte_ethdev.c | 19 ++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +18 -1
@@ -1963,6 +1963,7 @@ int rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) { struct rte_eth_dev *dev; +int ret;RTE_ETH_VALID_PORTID_OR_ERR_RET (port_id, -ENODEV ); dev = &rte_eth_devices[port_id];
@@ -1978,7 +1979,23 @@ rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) }RTE_FUNC_PTR_OR_ERR_RET (*dev->dev_ops->vlan_filter_set, -ENOTSUP ); -return (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); + ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); +if (ret ==0 ) { +struct rte_vlan_filter_conf *vfc; +int vidx; +int vbit; + + vfc = &dev->data->vlan_filter_conf; + vidx = vlan_id /64 ; + vbit = vlan_id %64 ; + +if (on) + vfc->ids[vidx] |=UINT64_C (1 ) << vbit; +else + vfc->ids[vidx] &= ~(UINT64_C (1 ) << vbit); + } + +return ret; }int
lib/librte_ether/rte_ethdev.h +10 -0
@@ -374,6 +374,14 @@ enum rte_vlan_type { };/** +* A structure used to describe a vlan filter. +* If the bit corresponding to a VID is set, such VID is on. +*/ +struct rte_vlan_filter_conf { +uint64_t ids[64 ]; +}; + +/** * A structure used to configure the Receive Side Scaling (RSS) feature * of an Ethernet port. * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1675,6 +1683,8 @@ struct rte_eth_dev_data {enum rte_kernel_driver kdrv;/**< Kernel driver passthrough */ int numa_node;/**< NUMA node connection */ const char *drv_name;/**< Driver name */ +struct rte_vlan_filter_conf vlan_filter_conf; +/**< VLAN filter configuration. */ };/** Device supports hotplug detach */
Signature · 1 line
2.1.4
PATCH v5 2/12 ethdev: add deferred intermediate device state
In reply to Gaetan RivetThis device state means that the device is managed externally, by whichever party has set this state (PMD or application).
Note: this new device state is only an information. The related device structure and operators are still valid and can be used normally.
It is however made private by device management helpers within ethdev, making the device invisible to applications.
--- lib/librte_ether/rte_ethdev.c | 3 ++- lib/librte_ether/rte_ethdev.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +2 -1
@@ -287,7 +287,8 @@ int rte_eth_dev_is_valid_port(uint8_t port_id) {if (port_id >=RTE_MAX_ETHPORTS || - rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED ) + (rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED && + rte_eth_devices[port_id].state !=RTE_ETH_DEV_DEFERRED ))return 0 ;else return 1 ;
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1589,6 +1589,7 @@ struct rte_eth_rxtx_callback {enum rte_eth_dev_state {RTE_ETH_DEV_UNUSED =0 ,RTE_ETH_DEV_ATTACHED , +RTE_ETH_DEV_DEFERRED , };/**
Signature · 1 line
2.1.4
PATCH v5 3/12 ethdev: count devices consistently
In reply to Gaetan RivetMake the rte_eth_dev_count() return the number of available devices even after some are detached by the hotplug API or put in a deferred state.
--- lib/librte_ether/rte_ethdev.c | 16 +++++++++------- lib/librte_ether/rte_ethdev.h | 13 ++++++------- 2 files changed, 15 insertions(+), 14 deletions(-)
lib/librte_ether/rte_ethdev.c +9 -7
@@ -71,7 +71,6 @@ static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS ];static struct rte_eth_dev_data *rte_eth_dev_data;static uint8_t eth_dev_last_created_port; -static uint8_t nb_ports;/* spinlock for eth device callbacks */ static rte_spinlock_t rte_eth_dev_cb_lock =RTE_SPINLOCK_INITIALIZER ;
@@ -206,7 +205,6 @@ eth_dev_get(uint8_t port_id)TAILQ_INIT (&(eth_dev->link_intr_cbs)); eth_dev_last_created_port = port_id; - nb_ports++;return eth_dev; }
@@ -279,7 +277,6 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)return -EINVAL ; eth_dev->state =RTE_ETH_DEV_UNUSED ; - nb_ports--;return 0 ; }
@@ -304,7 +301,15 @@ rte_eth_dev_socket_id(uint8_t port_id)uint8_t rte_eth_dev_count (void ) { -return nb_ports; +uint8_t p; +uint8_t count; + + count =0 ; + +RTE_ETH_FOREACH_DEV (p) + count++; + +return count; }int
@@ -336,9 +341,6 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)return -EINVAL ; } -if (!nb_ports) -return -ENODEV ; - *port_id =RTE_MAX_ETHPORTS ; RTE_ETH_FOREACH_DEV(i) { if (!strncmp(name,
lib/librte_ether/rte_ethdev.h +6 -7
@@ -1725,13 +1725,12 @@ uint8_t rte_eth_find_next(uint8_t port_id);/** * Get the total number of Ethernet devices that have been successfully -* initialized by the [matching] Ethernet driver during the PCI probing phase. -* All devices whose port identifier is in the range -* [0, rte_eth_dev_count() - 1] can be operated on by network applications -* immediately after invoking rte_eal_init(). -* If the application unplugs a port using hotplug function, The enabled port -* numbers may be noncontiguous. In the case, the applications need to manage -* enabled port by using the ``RTE_ETH_FOREACH_DEV()`` macro. +* initialized by the matching Ethernet driver during the PCI probing phase +* and that are available for applications to use. These devices must be +* accessed by using the ``RTE_ETH_FOREACH_DEV()`` macro to deal with +* non-contiguous ranges of devices. +* These non-contiguous ranges can be created by calls to hotplug functions or +* by some PMDs. * * @return * - The total number of usable Ethernet devices.
Signature · 1 line
2.1.4
PATCH v5 4/12 net/failsafe: add fail-safe PMD
In reply to Gaetan RivetIntroduce the fail-safe poll mode driver initialization and enable its build infrastructure.
This PMD allows for applications to benefit from true hot-plugging support without having to implement it.
It intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back. It also allows defining a contingency to the removal of a device, by designating a fail-over device that will take on transmitting operations if the preferred device is removed.
Applications only see a fail-safe instance, without caring for underlying activity ensuring their continued operations.
--- MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 133 +++++++ doc/guides/nics/features/failsafe.ini | 24 ++ doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 72 ++++ drivers/net/failsafe/failsafe.c | 231 +++++++++++ drivers/net/failsafe/failsafe_args.c | 331 ++++++++++++++++ drivers/net/failsafe/failsafe_eal.c | 163 ++++++++ drivers/net/failsafe/failsafe_ops.c | 663 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 227 +++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 107 ++++++ mk/rte.app.mk | 1 + 14 files changed, 1966 insertions(+) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c
MAINTAINERS +5 -0
@@ -333,6 +333,11 @@ F: drivers/net/enic/ F: doc/guides/nics/enic.rst F: doc/guides/nics/features/enic.ini +Fail-safe PMD +M: Gaetan Rivet <[email protected]> +F: drivers/net/failsafe/ +F: doc/guides/nics/fail_safe.rst + Intel e1000 M: Wenzhuo Lu <[email protected]> F: drivers/net/e1000/
config/common_base +6 -0
@@ -433,6 +433,12 @@ CONFIG_RTE_LIBRTE_PMD_XENVIRT=n CONFIG_RTE_LIBRTE_PMD_NULL=y # +# Compile fail-safe PMD +# +CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y +CONFIG_RTE_LIBRTE_PMD_FAILSAFE_DEBUG=n + +# # Do prefetch of packet data within PMD driver receive function # CONFIG_RTE_PMD_PACKET_PREFETCH=y
doc/guides/nics/fail_safe.rst new file +133 -0
133 lines not on this page · raw message
doc/guides/nics/features/failsafe.ini new file +24 -0
@@ -0,0 +1,24 @@ +; +; Supported features of the 'fail-safe' poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Link status = Y +Queue start/stop = Y +MTU update = Y +Jumbo frame = Y +Promiscuous mode = Y +Allmulticast mode = Y +Unicast MAC filter = Y +Multicast MAC filter = Y +VLAN filter = Y +Packet type parsing = Y +Basic stats = Y +Stats per queue = Y +ARMv7 = Y +ARMv8 = Y +Power8 = Y +x86-32 = Y +x86-64 = Y +Usage doc = Y
doc/guides/nics/index.rst +1 -0
@@ -64,6 +64,7 @@ Network Interface Controller Drivers vhost vmxnet3 pcap_ring + fail_safe **Figures**
drivers/net/Makefile +2 -0
@@ -59,6 +59,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena DEPDIRS-ena = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic DEPDIRS-enic = $(core-libs) librte_hash +DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe +DEPDIRS-failsafe = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k DEPDIRS-fm10k = $(core-libs) librte_hash DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
drivers/net/failsafe/Makefile new file +72 -0
72 lines not on this page · raw message
drivers/net/failsafe/failsafe.c new file +231 -0
231 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c new file +331 -0
331 lines not on this page · raw message
drivers/net/failsafe/failsafe_eal.c new file +163 -0
163 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c new file +663 -0
663 lines not on this page · raw message
drivers/net/failsafe/failsafe_private.h new file +227 -0
227 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c new file +107 -0
107 lines not on this page · raw message
mk/rte.app.mk +1 -0
@@ -122,6 +122,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += -lrte_pmd_fm10k +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += -lrte_pmd_failsafe _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
Signature · 1 line
2.1.4
Re: [PATCH v5 04/12] net/failsafe: add fail-safe PMD
You need this patch for shared library build:
drivers/net/failsafe/Makefile +4 -0
@@ -34,6 +34,10 @@ include $(RTE_SDK)/mk/rte.vars.mk # Library name LIB = librte_pmd_failsafe.a +EXPORT_MAP := rte_pmd_failsafe_version.map + +LIBABIVER := 1 + # Sources are stored in SRCS-y SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_args.c
drivers/net/failsafe/rte_pmd_failsafe_version.map new file +4 -0
@@ -0,0 +1,4 @@ +DPDK_17.08 { + + local: *; +};
PATCH v5 5/12 net/failsafe: add plug-in support
In reply to Gaetan RivetPeriodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
--- doc/guides/nics/fail_safe.rst | 19 +++ drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 71 ++++++++++ drivers/net/failsafe/failsafe_args.c | 32 +++++ drivers/net/failsafe/failsafe_eal.c | 30 +---- drivers/net/failsafe/failsafe_ether.c | 228 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 25 ++-- drivers/net/failsafe/failsafe_private.h | 60 ++++++++- 8 files changed, 423 insertions(+), 43 deletions(-) create mode 100644 drivers/net/failsafe/failsafe_ether.c
doc/guides/nics/fail_safe.rst +19 -0
@@ -102,6 +102,11 @@ Fail-safe command line parameters address is generated, that will be subsequently applied to all sub-device once they are probed. +- **hotplug_poll** parameter [UINT64] (default **2000**) + + This parameter allows the user to configure the amount of time in milliseconds + between two slave upkeep round. + Usage example ~~~~~~~~~~~~~
@@ -131,3 +136,17 @@ Care must be taken, however, to respect the **ether** API concerning device access, and in particular, using the ``RTE_ETH_FOREACH_DEV`` macro to iterate over ethernet devices, instead of directly accessing them or by writing one's own device iterator. + +Plug-in feature +--------------- + +A sub-device can be defined without existing on the system when the fail-safe +PMD is initialized. Upon probing this device, the fail-safe PMD will detect its +absence and postpone its use. It will then register for a periodic check on any +missing sub-device. + +During this time, the fail-safe PMD can be used normally, configured and told to +emit and receive packets. It will store any applied configuration, and try to +apply it upon the probing of its missing sub-device. After this configuration +pass, the new sub-device will be synchronized with other sub-devices, i.e. be +started if the fail-safe PMD has been started by the user before.
drivers/net/failsafe/Makefile +1 -0
@@ -40,6 +40,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_args.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c # No exported include files
drivers/net/failsafe/failsafe.c +71 -0
83 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c +32 -0
@@ -45,9 +45,11 @@typedef int (parse_cb )(struct rte_eth_dev *dev,const char *params,uint8_t head); +uint64_t hotplug_poll;int mac_from_arg;const char *pmd_failsafe_init_parameters[] = { +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ,PMD_FAILSAFE_MAC_KVARG ,NULL , };
@@ -221,6 +223,24 @@ fs_remove_sub_devices_definition(char params[DEVARGS_MAXLEN]) }static int +fs_get_u64_arg(const char *key __rte_unused, +const char *value,void *out) +{ +uint64_t *u64 = out; +char *endptr =NULL ; + +if ((value ==NULL ) || (out ==NULL )) +return -EINVAL ; + errno =0 ; + *u64 =strtoull (value, &endptr,0 ); +if (errno !=0 ) +return -errno; +if (endptr == value) +return -1 ; +return 0 ; +} + +static int fs_get_mac_addr_arg(const char *key __rte_unused,const char *value,void *out) {
@@ -252,6 +272,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) ret =0 ; priv->subs_tx =FAILSAFE_MAX_ETHPORTS ;/* default parameters */ + hotplug_poll =FAILSAFE_HOTPLUG_DEFAULT_TIMEOUT_MS ; mac_from_arg =0 ; n =snprintf (mut_params,sizeof (mut_params),"%s" , params);if (n >=sizeof (mut_params)) {
@@ -274,6 +295,16 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) PMD_FAILSAFE_PARAM_STRING);return -1 ; } +/* PLUG_IN event poll timer */ + arg_count =rte_kvargs_count (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ); +if (arg_count ==1 ) { + ret =rte_kvargs_process (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG , + &fs_get_u64_arg, &hotplug_poll); +if (ret <0 ) + goto free_kvlist; + }/* MAC addr */ arg_count =rte_kvargs_count (kvlist,PMD_FAILSAFE_MAC_KVARG );
@@ -287,6 +318,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) mac_from_arg =1 ; } } +PRIV (dev)->state =DEV_PARSED ; free_kvlist:rte_kvargs_free (kvlist);return ret;
drivers/net/failsafe/failsafe_eal.c +4 -26
@@ -91,37 +91,14 @@ fs_bus_init(struct rte_eth_dev *dev)int failsafe_eal_init (struct rte_eth_dev *dev) { -struct sub_device *sdev; -uint8_t i;int ret; ret =fs_bus_init (dev);if (ret)return ret; -/* -* We only update TX_SUBDEV if we are not started. -* If a sub_device is emitting, we will switch the TX_SUBDEV to the -* preferred port only upon starting it, so that the switch is smoother. -*/ -if (PREFERRED_SUBDEV (dev)->state >=DEV_PROBED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev) && - (TX_SUBDEV (dev) ==NULL || - (TX_SUBDEV (dev) &&TX_SUBDEV (dev)->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 <DEV_PROBED ) || -TX_SUBDEV (dev) ==NULL ) { -/* Using first probed device */ - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_PROBED) { -DEBUG ("Switching tx_dev to sub_device %d" , - i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_PROBED ) +PRIV (dev)->state =DEV_PROBED ; +fs_switch_dev (dev);return 0 ; }
@@ -159,5 +136,6 @@ failsafe_eal_uninit(struct rte_eth_dev *dev) ret =fs_bus_uninit (dev);if (ret)return ret; +PRIV (dev)->state =DEV_PROBED -1 ;return 0 ; }
drivers/net/failsafe/failsafe_ether.c new file +228 -0
228 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +10 -15
@@ -89,6 +89,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } sdev->state =DEV_ACTIVE ; } +if (PRIV (dev)->state <DEV_ACTIVE ) +PRIV (dev)->state =DEV_ACTIVE ;return 0 ; }
@@ -108,21 +110,9 @@ fs_dev_start(struct rte_eth_dev *dev)return ret; sdev->state =DEV_STARTED ; } -if (PREFERRED_SUBDEV (dev)->state ==DEV_STARTED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev)) { -DEBUG ("Switching tx_dev to preferred sub_device" ); -PRIV (dev)->subs_tx =0 ; - } - }else { -if ((TX_SUBDEV (dev) &&TX_SUBDEV (dev)->state <DEV_STARTED ) || -TX_SUBDEV (dev) ==NULL ) { - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) { -DEBUG ("Switching tx_dev to sub_device %d" , i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_STARTED ) +PRIV (dev)->state =DEV_STARTED ; +fs_switch_dev (dev);return 0 ; }
@@ -132,6 +122,7 @@ fs_dev_stop(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +PRIV (dev)->state =DEV_STARTED -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) {rte_eth_dev_stop (PORT_ID (sdev)); sdev->state =DEV_STARTED -1 ;
@@ -183,6 +174,10 @@ fs_dev_close(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +failsafe_hotplug_alarm_cancel (dev); +if (PRIV (dev)->state ==DEV_STARTED ) + dev->dev_ops->dev_stop (dev); +PRIV (dev)->state =DEV_ACTIVE -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) {DEBUG ("Closing sub_device %d" , i);rte_eth_dev_close (PORT_ID (sdev));
drivers/net/failsafe/failsafe_private.h +58 -2
92 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v5 6/12 net/failsafe: add flexible device definition
In reply to Gaetan RivetAdd the "exec" device type.
The parameters given to this type of device will be executed in a shell. The output of this command is then used as a definition for a device.
That command can be re-interpreted if the related device is not plugged-in. It allows for a device definition to react to system changes (e.g. changing PCI bus for a given device).
--- doc/guides/nics/fail_safe.rst | 20 +++++++ drivers/net/failsafe/failsafe_args.c | 99 +++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ether.c | 7 +++ drivers/net/failsafe/failsafe_private.h | 4 ++ 4 files changed, 130 insertions(+)
doc/guides/nics/fail_safe.rst +20 -0
@@ -91,6 +91,19 @@ Fail-safe command line parameters additional sub-device parameters if need be. They will be passed on to the sub-device. +- **exec(<shell command>)** parameter + + This parameter allows the user to provide a command to the fail-safe PMD to + execute and define a sub-device. + It is done within a regular shell context. + The first line of its output is read by the fail-safe PMD and otherwise + interpreted as if passed by the regular **dev** parameter. + Any other line is discarded. + If the command fail or output an incorrect string, the sub-device is not + initialized. + All commas within the ``shell command`` are replaced by spaces before + executing the command. This helps using scripts to specify devices. + - **mac** parameter [MAC address] This parameter allows the user to set a default MAC address to the fail-safe
@@ -126,6 +139,13 @@ This section shows some example of using **testpmd** with a fail-safe PMD. --vdev='net_failsafe0,mac=de:ad:be:ef:01:02,dev(84:00.0),dev(net_ring0,nodeaction=r1:0:CREATE)' -- \ -i +#. Start testpmd using a flexible device definition + + .. code-block:: console + + $RTE_TARGET/build/app/testpmd -c 0xff -n 4 --no-pci \ + --vdev='net_failsafe0,exec(echo 84:00.0)' -- -i + Using the Fail-safe PMD from an application -------------------------------------------
drivers/net/failsafe/failsafe_args.c +99 -0
126 lines not on this page · raw message
drivers/net/failsafe/failsafe_ether.c +7 -0
@@ -188,6 +188,13 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)int ret;uint8_t i; +if (PRIV (dev)->state <DEV_PARSED ) +return 0 ; + + ret =failsafe_args_parse_subs (dev); +if (ret) +return ret; +if (PRIV (dev)->state <DEV_PROBED )return 0 ; ret =failsafe_eal_init (dev);
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -44,6 +44,7 @@#define PMD_FAILSAFE_PLUG_IN_POLL_KVARG "hotplug_poll"#define PMD_FAILSAFE_PARAM_STRING \ "dev(<ifc>)," \ + "exec(<shell command>)," \ "mac=mac_addr," \ "hotplug_poll=u64" \ ""
@@ -87,6 +88,8 @@ struct sub_device {struct rte_eth_dev *edev;/* Device state machine */ enum dev_state state; +/* Some device are defined as a command line */ +char *cmdline; };struct fs_priv {
@@ -135,6 +138,7 @@ uint16_t failsafe_tx_burst(void *txq,int failsafe_args_parse (struct rte_eth_dev *dev,const char *params);void failsafe_args_free (struct rte_eth_dev *dev);int failsafe_args_count_subdevice (struct rte_eth_dev *dev,const char *params); +int failsafe_args_parse_subs (struct rte_eth_dev *dev);/* EAL */
Signature · 1 line
2.1.4
PATCH v5 7/12 net/failsafe: support flow API
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_eal.c | 1 + drivers/net/failsafe/failsafe_ether.c | 70 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 216 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 29 +++++ drivers/net/failsafe/failsafe_private.h | 18 +++ 8 files changed, 337 insertions(+) create mode 100644 drivers/net/failsafe/failsafe_flow.c
doc/guides/nics/features/failsafe.ini +1 -0
@@ -13,6 +13,7 @@ Allmulticast mode = Y Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y +Flow API = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/Makefile +1 -0
@@ -41,6 +41,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_flow.c # No exported include files
drivers/net/failsafe/failsafe.c +1 -0
@@ -177,6 +177,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) dev->data->mac_addrs = &PRIV (dev)->mac_addrs[0 ]; dev->data->dev_link = eth_link;PRIV (dev)->nb_mac_addr =1 ; +TAILQ_INIT (&PRIV (dev)->flow_list); dev->rx_pkt_burst = (eth_rx_burst_t)&failsafe_rx_burst; dev->tx_pkt_burst = (eth_tx_burst_t)&failsafe_tx_burst;if (params ==NULL ) {
drivers/net/failsafe/failsafe_eal.c +1 -0
@@ -81,6 +81,7 @@ fs_bus_init(struct rte_eth_dev *dev)ERROR ("sub_device %d init went wrong" , i);return -ENODEV ; } +SUB_ID (sdev) = i; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
drivers/net/failsafe/failsafe_ether.c +70 -0
90 lines not on this page · raw message
drivers/net/failsafe/failsafe_flow.c new file +216 -0
216 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +29 -0
@@ -35,6 +35,7 @@#include <stdint.h> #include <rte_ethdev.h> #include <rte_malloc.h> +#include <rte_flow.h> #include "failsafe_private.h"
@@ -628,6 +629,33 @@ fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)rte_eth_dev_default_mac_addr_set (PORT_ID (sdev), mac_addr); } +static int +fs_filter_ctrl (struct rte_eth_dev *dev, +enum rte_filter_type type, +enum rte_filter_op op, +void *arg) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + +if (type ==RTE_ETH_FILTER_GENERIC && + op ==RTE_ETH_FILTER_GET ) { + *(const void **)arg = &fs_flow_ops; +return 0 ; + } + FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) { +DEBUG ("Calling rte_eth_dev_filter_ctrl on sub_device %d" , i); + ret =rte_eth_dev_filter_ctrl (PORT_ID (sdev), type, op, arg); +if (ret) { +ERROR ("Operation rte_eth_dev_filter_ctrl failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + } +return 0 ; +} +const struct eth_dev_ops failsafe_ops = { .dev_configure = fs_dev_configure, .dev_start = fs_dev_start,
@@ -655,4 +683,5 @@ const struct eth_dev_ops failsafe_ops = { .mac_addr_remove = fs_mac_addr_remove, .mac_addr_add = fs_mac_addr_add, .mac_addr_set = fs_mac_addr_set, + .filter_ctrl = fs_filter_ctrl, };
drivers/net/failsafe/failsafe_private.h +18 -0
@@ -34,6 +34,8 @@#ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_#define _RTE_ETH_FAILSAFE_PRIVATE_H_ +#include <sys/queue.h> +#include <rte_dev.h> #include <rte_ethdev.h> #include <rte_devargs.h>
@@ -72,6 +74,14 @@ struct txq {struct rte_eth_txq_info info; }; +struct rte_flow { +TAILQ_ENTRY (rte_flow) next; +/* sub_flows */ +struct rte_flow *flows[FAILSAFE_MAX_ETHPORTS ]; +/* flow description for synchronization */ +struct rte_flow_desc *fd; +}; +enum dev_state {DEV_UNDEFINED =0 ,DEV_PARSED ,
@@ -86,6 +96,7 @@ struct sub_device {struct rte_bus *bus;struct rte_device *dev;struct rte_eth_dev *edev; +uint8_t sid;/* Device state machine */ enum dev_state state;/* Some device are defined as a command line */
@@ -104,6 +115,8 @@ struct fs_priv {uint8_t subs_tail;/* first invalid */ uint8_t subs_tx;/* current emitting device */ uint8_t current_probed; +/* flow mapping */ + TAILQ_HEAD(sub_flows, rte_flow) flow_list;/* current number of mac_addr slots allocated. */ uint32_t nb_mac_addr;struct ether_addr mac_addrs[FAILSAFE_MAX_ETHADDR ];
@@ -153,6 +166,7 @@ int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev);extern const char pmd_failsafe_driver_name[];extern const struct eth_dev_ops failsafe_ops; +extern const struct rte_flow_ops fs_flow_ops;extern uint64_t hotplug_poll;extern int mac_from_arg;
@@ -170,6 +184,10 @@ extern int mac_from_arg;#define PORT_ID (sdev) \ (ETH(sdev)->data->port_id) +/* sdev: (struct sub_device *) */ +#define SUB_ID (sdev) \ + ((sdev)->sid) +/** * Stateful iterator construct over fail-safe sub-devices: * s: (struct sub_device *), iterator
Signature · 1 line
2.1.4
PATCH v5 8/12 net/failsafe: support offload capabilities
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 6 ++ drivers/net/failsafe/failsafe_ops.c | 131 +++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-)
doc/guides/nics/features/failsafe.ini +6 -0
@@ -14,6 +14,12 @@ Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y Flow API = Y +VLAN offload = Y +QinQ offload = Y +L3 checksum offload = Y +L4 checksum offload = Y +Inner L3 checksum = Y +Inner L4 checksum = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/failsafe_ops.c +129 -2
151 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v5 9/12 net/failsafe: add fast burst functions
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_private.h | 8 +++ drivers/net/failsafe/failsafe_rxtx.c | 124 ++++++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 20 deletions(-)
drivers/net/failsafe/failsafe_private.h +8 -0
@@ -141,11 +141,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);
@@ -299,6 +306,7 @@ fs_switch_dev(struct rte_eth_dev *dev) }else {return ; } +set_burst_fn (dev,0 );rte_wmb (); }
drivers/net/failsafe/failsafe_rxtx.c +104 -20
154 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v5 10/12 net/failsafe: support device removal
In reply to Gaetan RivetListen to INTR_RMV events issued by slaves.
Add atomic flags on slave queues to detect use of slave bursts function. If a removal is detected, set the recollection flag on this slave.
During a slave upkeep round, if its recollection flag is set and its burst functions are not in use by any thread, remove that slave.
--- doc/guides/nics/fail_safe.rst | 14 +++++ drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_args.c | 13 +++++ drivers/net/failsafe/failsafe_eal.c | 3 +- drivers/net/failsafe/failsafe_ether.c | 92 ++++++++++++++++++++++++++++++--- drivers/net/failsafe/failsafe_ops.c | 38 ++++++++++++-- drivers/net/failsafe/failsafe_private.h | 72 +++++++++++++++++++++++--- drivers/net/failsafe/failsafe_rxtx.c | 17 +++++- 8 files changed, 230 insertions(+), 20 deletions(-)
doc/guides/nics/fail_safe.rst +14 -0
@@ -51,6 +51,12 @@ The Fail-safe PMD only supports a limited set of features. If you plan to use a device underneath the Fail-safe PMD with a specific feature, this feature must be supported by the Fail-safe PMD to avoid throwing any error. +A notable exception is the device removal feature. The fail-safe PMD being a +virtual device, it cannot currently be removed in the sense of a specific bus +hotplug, like for PCI for example. It will however enable this feature for its +sub-device automatically, detecting those that are capable and register the +relevant callback for such event. + Check the feature matrix for the complete set of supported features. Compilation options
@@ -170,3 +176,11 @@ emit and receive packets. It will store any applied configuration, and try to apply it upon the probing of its missing sub-device. After this configuration pass, the new sub-device will be synchronized with other sub-devices, i.e. be started if the fail-safe PMD has been started by the user before. + +Plug-out feature +---------------- + +A sub-device supporting the device removal event can be removed from its bus at +any time. The fail-safe PMD will register a callback for such event and react +accordingly. It will try to safely stop, close and uninit the sub-device having +emitted this event, allowing it to free its eventual resources.
drivers/net/failsafe/failsafe.c +1 -0
@@ -132,6 +132,7 @@ fs_hotplug_alarm(void *arg)if (!PRIV (dev)->pending_alarm)return ;PRIV (dev)->pending_alarm =0 ; +failsafe_dev_remove (dev); FOREACH_SUBDEV(sdev, i, dev)if (sdev->state !=PRIV (dev)->state)break ;
drivers/net/failsafe/failsafe_args.c +13 -0
@@ -443,6 +443,17 @@ failsafe_args_count_subdevice(struct rte_eth_dev *dev, dev, params); } +static int +fs_parse_sub_device (struct sub_device *sdev) +{ +struct rte_devargs *da; +char devstr[DEVARGS_MAXLEN ] ="" ; + + da = &sdev->devargs; +snprintf (devstr,sizeof (devstr),"%s,%s" , da->name, da->args); +return fs_parse_device (sdev, devstr); +} +int failsafe_args_parse_subs (struct rte_eth_dev *dev) {
@@ -455,6 +466,8 @@ failsafe_args_parse_subs(struct rte_eth_dev *dev)continue ;if (sdev->cmdline) ret =fs_execute_cmd (sdev, sdev->cmdline); +else + ret =fs_parse_sub_device (sdev);if (ret ==0 ) sdev->state =DEV_PARSED ; }
drivers/net/failsafe/failsafe_eal.c +2 -1
@@ -82,6 +82,7 @@ fs_bus_init(struct rte_eth_dev *dev)return -ENODEV ; }SUB_ID (sdev) = i; + sdev->fs_dev = dev; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
@@ -99,7 +100,7 @@ failsafe_eal_init(struct rte_eth_dev *dev)return ret;if (PRIV (dev)->state <DEV_PROBED )PRIV (dev)->state =DEV_PROBED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
drivers/net/failsafe/failsafe_ether.c +86 -6
126 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +35 -3
@@ -33,6 +33,8 @@#include <assert.h> #include <stdint.h> + +#include <rte_atomic.h> #include <rte_ethdev.h> #include <rte_malloc.h> #include <rte_flow.h>
@@ -204,9 +206,21 @@ fs_dev_configure(struct rte_eth_dev *dev) } } FOREACH_SUBDEV(sdev, i, dev) { +int rmv_interrupt =0 ; +if (sdev->state !=DEV_PROBED )continue ; + + rmv_interrupt =ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_RMV ; +if (rmv_interrupt) { +DEBUG ("Enabling RMV interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.rmv =1 ; + }else { +DEBUG ("sub_device %d does not support RMV event" , i); + }DEBUG ("Configuring sub-device %d" , i); + sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev), dev->data->nb_rx_queues, dev->data->nb_tx_queues,
@@ -215,6 +229,16 @@ fs_dev_configure(struct rte_eth_dev *dev)ERROR ("Could not configure sub_device %d" , i);return ret; } +if (rmv_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_RMV , + failsafe_eth_rmv_event_callback, + sdev); +if (ret) +WARN ("Failed to register RMV callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.rmv =0 ; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
@@ -240,7 +264,7 @@ fs_dev_start(struct rte_eth_dev *dev) }if (PRIV (dev)->state <DEV_STARTED )PRIV (dev)->state =DEV_STARTED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
@@ -351,10 +375,14 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,fs_rx_queue_release (rxq); dev->data->rx_queues[rx_queue_id] =NULL ; } - rxq =rte_zmalloc (NULL ,sizeof (*rxq), + rxq =rte_zmalloc (NULL , +sizeof (*rxq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (rxq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&rxq->refcnt[i]); rxq->qid = rx_queue_id; rxq->socket_id = socket_id; rxq->info.mp = mb_pool;
@@ -414,10 +442,14 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,fs_tx_queue_release (txq); dev->data->tx_queues[tx_queue_id] =NULL ; } - txq =rte_zmalloc ("ethdev TX queue" ,sizeof (*txq), + txq =rte_zmalloc ("ethdev TX queue" , +sizeof (*txq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (txq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&txq->refcnt[i]); txq->qid = tx_queue_id; txq->socket_id = socket_id; txq->info.conf = *tx_conf;
drivers/net/failsafe/failsafe_private.h +64 -8
133 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c +15 -2
@@ -33,6 +33,7 @@#include <assert.h> +#include <rte_atomic.h> #include <rte_mbuf.h> #include <rte_ethdev.h>
@@ -113,8 +114,10 @@ failsafe_rx_burst(void *queue,if (unlikely (fs_rx_unsafe (sdev)))continue ; sub_rxq =ETH (sdev)->data->rx_queues[rxq->qid]; +FS_ATOMIC_P (rxq->refcnt[sdev->sid]); nb_rx =ETH (sdev)->rx_pkt_burst (sub_rxq, rx_pkts, nb_pkts); +FS_ATOMIC_V (rxq->refcnt[sdev->sid]);if (nb_rx) { rxq->last_polled = i;return nb_rx;
@@ -147,8 +150,10 @@ failsafe_rx_burst_fast(void *queue, sdev = &priv->subs[i];assert (!fs_rx_unsafe (sdev)); sub_rxq =ETH (sdev)->data->rx_queues[rxq->qid]; +FS_ATOMIC_P (rxq->refcnt[sdev->sid]); nb_rx =ETH (sdev)->rx_pkt_burst (sub_rxq, rx_pkts, nb_pkts); +FS_ATOMIC_V (rxq->refcnt[sdev->sid]);if (nb_rx) { rxq->last_polled = i;return nb_rx;
@@ -165,13 +170,17 @@ failsafe_tx_burst(void *queue,struct sub_device *sdev;struct txq *txq;void *sub_txq; +uint16_t nb_tx; txq = queue; sdev =TX_SUBDEV (txq->priv->dev);if (unlikely (fs_tx_unsafe (sdev)))return 0 ; sub_txq =ETH (sdev)->data->tx_queues[txq->qid]; -return ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_P (txq->refcnt[sdev->sid]); + nb_tx =ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_V (txq->refcnt[sdev->sid]); +return nb_tx; }uint16_t
@@ -182,10 +191,14 @@ failsafe_tx_burst_fast(void *queue,struct sub_device *sdev;struct txq *txq;void *sub_txq; +uint16_t nb_tx; txq = queue; sdev =TX_SUBDEV (txq->priv->dev);assert (!fs_tx_unsafe (sdev)); sub_txq =ETH (sdev)->data->tx_queues[txq->qid]; -return ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_P (txq->refcnt[sdev->sid]); + nb_tx =ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_V (txq->refcnt[sdev->sid]); +return nb_tx; }
Signature · 1 line
2.1.4
Re: [PATCH v5 10/12] net/failsafe: support device removal
This patch needs to be rebased with this change:
drivers/net/failsafe/failsafe_ether.c +1 -1
@@ -399,7 +399,7 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)void failsafe_eth_rmv_event_callback(uint8_t port_id __rte_unused, enum rte_eth_event_type event __rte_unused, -void *cb_arg) + void *cb_arg, void *ret __rte_unused) {struct sub_device *sdev = cb_arg;
drivers/net/failsafe/failsafe_private.h +1 -1
@@ -182,7 +182,7 @@ int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev);void failsafe_dev_remove (struct rte_eth_dev *dev);void failsafe_eth_rmv_event_callback (uint8_t port_id,enum rte_eth_event_type type, -void *arg); +void *arg,void *ret);
PATCH v5 11/12 net/failsafe: support link status change event
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_ether.c | 15 +++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 23 +++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 3 +++ 5 files changed, 43 insertions(+)
doc/guides/nics/features/failsafe.ini +1 -0
@@ -5,6 +5,7 @@ ; [Features] Link status = Y +Link status event = Y Queue start/stop = Y MTU update = Y Jumbo frame = Y
drivers/net/failsafe/failsafe.c +1 -0
@@ -240,6 +240,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) mac->addr_bytes[0 ], mac->addr_bytes[1 ], mac->addr_bytes[2 ], mac->addr_bytes[3 ], mac->addr_bytes[4], mac->addr_bytes[5]); + dev->data->dev_flags |=RTE_ETH_DEV_INTR_LSC ;return 0 ; free_args:failsafe_args_free (dev);
drivers/net/failsafe/failsafe_ether.c +15 -0
@@ -383,3 +383,18 @@ failsafe_eth_rmv_event_callback(uint8_t port_id __rte_unused,*/ sdev->remove =1 ; } + +void +failsafe_eth_lsc_event_callback(uint8_t port_id __rte_unused, + enum rte_eth_event_type event __rte_unused, +void *cb_arg) +{ +struct rte_eth_dev *dev = cb_arg; +int ret; + + ret = dev->dev_ops->link_update (dev,0 ); +/* We must pass on the LSC event */ +if (ret) +_rte_eth_dev_callback_process (dev,RTE_ETH_EVENT_INTR_LSC , +NULL ); +}
drivers/net/failsafe/failsafe_ops.c +23 -0
@@ -207,6 +207,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } FOREACH_SUBDEV(sdev, i, dev) {int rmv_interrupt =0 ; +int lsc_interrupt =0 ; +int lsc_enabled;if (sdev->state !=DEV_PROBED )continue ;
@@ -219,6 +221,17 @@ fs_dev_configure(struct rte_eth_dev *dev) }else {DEBUG ("sub_device %d does not support RMV event" , i); } + lsc_enabled = dev->data->dev_conf.intr_conf.lsc; + lsc_interrupt = lsc_enabled && + (ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_LSC ); +if (lsc_interrupt) { +DEBUG ("Enabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =1 ; + }else if (lsc_enabled && !lsc_interrupt) { +DEBUG ("Disabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =0 ; + }DEBUG ("Configuring sub-device %d" , i); sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev),
@@ -239,6 +252,16 @@ fs_dev_configure(struct rte_eth_dev *dev) SUB_ID(sdev)); } dev->data->dev_conf.intr_conf.rmv =0 ; +if (lsc_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_LSC , + failsafe_eth_lsc_event_callback, + dev); +if (ret) +WARN ("Failed to register LSC callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.lsc = lsc_enabled; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
drivers/net/failsafe/failsafe_private.h +3 -0
@@ -179,6 +179,9 @@ void failsafe_dev_remove(struct rte_eth_dev *dev);void failsafe_eth_rmv_event_callback (uint8_t port_id,enum rte_eth_event_type type,void *arg); +void failsafe_eth_lsc_event_callback (uint8_t port_id, +enum rte_eth_event_type event, +void *cb_arg);/* GLOBALS */
Signature · 1 line
2.1.4
Re: [PATCH v5 11/12] net/failsafe: support link status change event
This patch need to be rebased with this change:
drivers/net/failsafe/failsafe_ether.c +2 -2
@@ -417,7 +417,7 @@ failsafe_eth_rmv_event_callback(uint8_t port_id __rte_unused,void failsafe_eth_lsc_event_callback(uint8_t port_id __rte_unused, enum rte_eth_event_type event __rte_unused, -void *cb_arg) + void *cb_arg, void *ret __rte_unused) {struct rte_eth_dev *dev = cb_arg;int ret;
@@ -426,5 +426,5 @@ failsafe_eth_lsc_event_callback(uint8_t port_id __rte_unused,/* We must pass on the LSC event */ if (ret)_rte_eth_dev_callback_process (dev,RTE_ETH_EVENT_INTR_LSC , -NULL ); +NULL ,NULL ); }
--- a/drivers/net/failsafe/failsafe_private.h
+++ b/drivers/net/failsafe/failsafe_private.h
void failsafe_eth_lsc_event_callback(uint8_t port_id,
enum rte_eth_event_type event,
- void *cb_arg);
+ void *cb_arg, void *ret);
PATCH v5 12/12 net/failsafe: support flow API isolation mode
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_ether.c | 34 +++++++++++++++++++++++++++++++-- drivers/net/failsafe/failsafe_flow.c | 29 ++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 4 ++++ 3 files changed, 65 insertions(+), 2 deletions(-)
drivers/net/failsafe/failsafe_ether.c +32 -2
@@ -74,6 +74,28 @@ fs_flow_complain(struct rte_flow_error *error) }static int +eth_dev_flow_isolate_set (struct rte_eth_dev *dev, +struct sub_device *sdev) +{ +struct rte_flow_error ferror; +int ret; + +if (!PRIV (dev)->flow_isolated) { +DEBUG ("Flow isolation already disabled" ); + }else { +DEBUG ("Enabling flow isolation" ); + ret =rte_flow_isolate (PORT_ID (sdev), +PRIV (dev)->flow_isolated, + &ferror); +if (ret) { +fs_flow_complain (&ferror); +return ret; + } + } +return 0 ; +} + +static int fs_eth_dev_conf_apply (struct rte_eth_dev *dev,struct sub_device *sdev) {
@@ -331,9 +353,17 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)if (PRIV (dev)->state <DEV_ACTIVE )return 0 ; inactive =0 ; - FOREACH_SUBDEV(sdev, i, dev) -if (sdev->state ==DEV_PROBED ) + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state ==DEV_PROBED ) { inactive |=UINT32_C (1 ) << i; + ret =eth_dev_flow_isolate_set (dev, sdev); +if (ret) { +ERROR ("Could not apply configuration to sub_device %d" , + i); + goto err_remove; + } + } + } ret = dev->dev_ops->dev_configure (dev);if (ret) goto err_remove;
drivers/net/failsafe/failsafe_flow.c +29 -0
@@ -207,10 +207,39 @@ fs_flow_query(struct rte_eth_dev *dev,return -1 ; } +static int +fs_flow_isolate (struct rte_eth_dev *dev, +int set, +struct rte_flow_error *error) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state <DEV_PROBED ) +continue ; +DEBUG ("Calling rte_flow_isolate on sub_device %d" , i); +if (PRIV (dev)->flow_isolated != sdev->flow_isolated) +WARN ("flow isolation mode of sub_device %d in incoherent state." , + i); + ret =rte_flow_isolate (PORT_ID (sdev), set, error); +if (ret) { +ERROR ("Operation rte_flow_isolate failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + sdev->flow_isolated = set; + } +PRIV (dev)->flow_isolated = set; +return 0 ; +} +const struct rte_flow_ops fs_flow_ops = { .validate = fs_flow_validate, .create = fs_flow_create, .destroy = fs_flow_destroy, .flush = fs_flow_flush, .query = fs_flow_query, + .isolate = fs_flow_isolate, };
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -108,6 +108,8 @@ struct sub_device {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 {
@@ -139,6 +141,8 @@ struct fs_priv {*/ enum dev_state state; unsigned int pending_alarm:1; /* An alarm is pending */ +/* flow isolation state */ + int flow_isolated:1; };/* MISC */
Signature · 1 line
2.1.4
Quoted 11 lines · Gaetan Rivet
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/
Hi Gaetan,
Above dependencies are not enough to apply the PMD, it seems above ones also has dependencies to other patchsets, specially eal one that I am not able trace its dependencies from mails.
Since most of the eal patches are also from you, can you please list dependency tree to apply the PMD?
Thanks,
ferruh
Quoted 19 lines · Ferruh Yigit
Quoted 11 lines · Gaetan Rivet
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/Hi Gaetan,
Above dependencies are not enough to apply the PMD, it seems above ones also has dependencies to other patchsets, specially eal one that I am not able trace its dependencies from mails.
Quoted 6 lines
Since most of the eal patches are also from you, can you please list dependency tree to apply the PMD?
Thanks,
ferruh
Hi Ferruh,
here is the full list of patchsets that I have currently in my tree, in order, up until the fail-safe PMD:
---
[0] ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
[1] ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
[2] Remove PCI and VDEV dependency from eventdev library
http://dpdk.org/ml/archives/dev/2017-June/067402.html
[3] Remove cryptodev driver
http://dpdk.org/ml/archives/dev/2017-May/066382.html
[4] bus: attach / detach API
http://dpdk.org/ml/archives/dev/2017-June/067474.html
[5] pci: implement find_device bus operation
http://dpdk.org/ml/archives/dev/2017-June/067485.html
[6] rte_bus parse API
http://dpdk.org/ml/archives/dev/2017-June/067486.html
[7] Generic devargs parsing
http://dpdk.org/ml/archives/dev/2017-June/067496.html
[8] eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-June/067516.html
[9] bus/pci: remove PCI bus from EAL
http://dpdk.org/ml/archives/dev/2017-June/067520.html
[10] introduce fail-safe PMD
http://dpdk.org/ml/archives/dev/2017-June/067533.html
---
[2] has a slight compilation issue that I fixed with
https://github.com/grivet/dpdk/commit/1af1272bd3129e90ae7c4ab005e85d5f8a2f95fe
However Jerin has not yet answered to this issue (see:
http://dpdk.org/ml/archives/dev/2017-June/067412.html )
The failsafe PMD only depends on 0, 1, 4, 5, 6, 7, 8. All others are left there for consistency.
Signature · 2 lines
Gaëtan Rivet 6WIND
Quoted 69 lines · Gaëtan Rivet
Quoted 19 lines · Ferruh Yigit
Quoted 11 lines · Gaetan Rivet
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/Hi Gaetan,
Above dependencies are not enough to apply the PMD, it seems above ones also has dependencies to other patchsets, specially eal one that I am not able trace its dependencies from mails.
Quoted 6 lines
Since most of the eal patches are also from you, can you please list dependency tree to apply the PMD?
Thanks,
ferruhHi Ferruh,
here is the full list of patchsets that I have currently in my tree, in order, up until the fail-safe PMD:
---
[0] ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html[1] ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html[2] Remove PCI and VDEV dependency from eventdev library
http://dpdk.org/ml/archives/dev/2017-June/067402.html[3] Remove cryptodev driver
http://dpdk.org/ml/archives/dev/2017-May/066382.html[4] bus: attach / detach API
http://dpdk.org/ml/archives/dev/2017-June/067474.html[5] pci: implement
find_devicebus operation
http://dpdk.org/ml/archives/dev/2017-June/067485.html[6]
rte_busparse API
http://dpdk.org/ml/archives/dev/2017-June/067486.html[7] Generic devargs parsing
http://dpdk.org/ml/archives/dev/2017-June/067496.html[8] eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-June/067516.html[9] bus/pci: remove PCI bus from EAL
http://dpdk.org/ml/archives/dev/2017-June/067520.html[10] introduce fail-safe PMD
http://dpdk.org/ml/archives/dev/2017-June/067533.html---
Quoted 7 lines
[2] has a slight compilation issue that I fixed with
https://github.com/grivet/dpdk/commit/1af1272bd3129e90ae7c4ab005e85d5f8a2f95fe
However Jerin has not yet answered to this issue (see:
http://dpdk.org/ml/archives/dev/2017-June/067412.html )The failsafe PMD only depends on 0, 1, 4, 5, 6, 7, 8. All others are left there for consistency.
Thanks Gaetan,
I did able to apply the patchset, I think it is good idea to wait for PMD until things settle down in dependent patches side.
btw,getting build error [1], CFLAGS += -D_DEFAULT_SOURCE may help.
[1]/usr/include/features.h:148:3: error: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" [-Werror=cpp]
# warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
Quoted 75 lines · Ferruh Yigit
Quoted 74 lines · Gaëtan Rivet
Quoted 19 lines · Ferruh Yigit
Quoted 11 lines · Gaetan Rivet
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/Hi Gaetan,
Above dependencies are not enough to apply the PMD, it seems above ones also has dependencies to other patchsets, specially eal one that I am not able trace its dependencies from mails.
Quoted 6 lines
Since most of the eal patches are also from you, can you please list dependency tree to apply the PMD?
Thanks,
ferruhHi Ferruh,
here is the full list of patchsets that I have currently in my tree, in order, up until the fail-safe PMD:
---
[0] ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html[1] ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html[2] Remove PCI and VDEV dependency from eventdev library
http://dpdk.org/ml/archives/dev/2017-June/067402.html[3] Remove cryptodev driver
http://dpdk.org/ml/archives/dev/2017-May/066382.html[4] bus: attach / detach API
http://dpdk.org/ml/archives/dev/2017-June/067474.html[5] pci: implement
find_devicebus operation
http://dpdk.org/ml/archives/dev/2017-June/067485.html[6]
rte_busparse API
http://dpdk.org/ml/archives/dev/2017-June/067486.html[7] Generic devargs parsing
http://dpdk.org/ml/archives/dev/2017-June/067496.html[8] eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-June/067516.html[9] bus/pci: remove PCI bus from EAL
http://dpdk.org/ml/archives/dev/2017-June/067520.html[10] introduce fail-safe PMD
http://dpdk.org/ml/archives/dev/2017-June/067533.html---
[2] has a slight compilation issue that I fixed with
https://github.com/grivet/dpdk/commit/1af1272bd3129e90ae7c4ab005e85d5f8a2f95fe
However Jerin has not yet answered to this issue (see:
http://dpdk.org/ml/archives/dev/2017-June/067412.html )
Quoted 7 lines
Quoted 2 lines
The failsafe PMD only depends on 0, 1, 4, 5, 6, 7, 8. All others are left there for consistency.
Thanks Gaetan,
I did able to apply the patchset, I think it is good idea to wait for PMD until things settle down in dependent patches side.
btw, first three patches of the failsafe patchset are more generic ethdev layer patches. I think they shouldn't be merged as part of PMD patchset.
What do you think separating them into separate patchset (or perhaps individual patches, since they looks independent from eachother)?
Thanks,
ferruh
Quoted 10 lines
btw,getting build error [1], CFLAGS += -D_DEFAULT_SOURCE may help.
[1]
/usr/include/features.h:148:3: error: #warning "_BSD_SOURCEand_SVID_SOURCEare deprecated, use_DEFAULT_SOURCE" [-Werror=cpp]# warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
Quoted 76 lines · Ferruh Yigit
Quoted 75 lines · Ferruh Yigit
Quoted 74 lines · Gaëtan Rivet
Quoted 19 lines · Ferruh Yigit
Quoted 11 lines · Gaetan Rivet
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/Hi Gaetan,
Above dependencies are not enough to apply the PMD, it seems above ones also has dependencies to other patchsets, specially eal one that I am not able trace its dependencies from mails.
Quoted 6 lines
Since most of the eal patches are also from you, can you please list dependency tree to apply the PMD?
Thanks,
ferruhHi Ferruh,
here is the full list of patchsets that I have currently in my tree, in order, up until the fail-safe PMD:
---
[0] ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html[1] ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html[2] Remove PCI and VDEV dependency from eventdev library
http://dpdk.org/ml/archives/dev/2017-June/067402.html[3] Remove cryptodev driver
http://dpdk.org/ml/archives/dev/2017-May/066382.html[4] bus: attach / detach API
http://dpdk.org/ml/archives/dev/2017-June/067474.html[5] pci: implement
find_devicebus operation
http://dpdk.org/ml/archives/dev/2017-June/067485.html[6]
rte_busparse API
http://dpdk.org/ml/archives/dev/2017-June/067486.html[7] Generic devargs parsing
http://dpdk.org/ml/archives/dev/2017-June/067496.html[8] eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-June/067516.html[9] bus/pci: remove PCI bus from EAL
http://dpdk.org/ml/archives/dev/2017-June/067520.html[10] introduce fail-safe PMD
http://dpdk.org/ml/archives/dev/2017-June/067533.html---
[2] has a slight compilation issue that I fixed with
https://github.com/grivet/dpdk/commit/1af1272bd3129e90ae7c4ab005e85d5f8a2f95fe
However Jerin has not yet answered to this issue (see:
http://dpdk.org/ml/archives/dev/2017-June/067412.html )
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
The failsafe PMD only depends on 0, 1, 4, 5, 6, 7, 8. All others are left there for consistency.
Thanks Gaetan,
I did able to apply the patchset, I think it is good idea to wait for PMD until things settle down in dependent patches side.
Sure, it won't compile without it anyway.
Quoted 7 lines
btw, first three patches of the failsafe patchset are more generic ethdev layer patches. I think they shouldn't be merged as part of PMD patchset.
What do you think separating them into separate patchset (or perhaps individual patches, since they looks independent from eachother)?
Why not, but I am juggling (read: struggling) with a few patchsets already. I will wait for the dust to settle and look into it.
Quoted 14 lines
Thanks,
ferruhQuoted 10 lines
btw,getting build error [1], CFLAGS += -D_DEFAULT_SOURCE may help.
[1]
/usr/include/features.h:148:3: error: #warning "_BSD_SOURCEand_SVID_SOURCEare deprecated, use_DEFAULT_SOURCE" [-Werror=cpp]# warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
Signature · 2 lines
Gaëtan Rivet 6WIND
v6 cover introduce fail-safe PMD
In reply to Gaetan RivetThis PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/
ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/
ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/
v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixes
v2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.
v3 --> v4:
- Split back commits
net/failsafe: add fast burst functions net/failsafe: support device removal
That were squashed by error during a rebase
- Fix segfault on port plugin
- Fix isolate mode support for MLX4 ports plugin
v4 --> v5:
- Follow new plug / unplug API.
v5 --> v6:
- Follow new hotplug API.
- Improve usability of hotplug API.
- Fix rte_dev hotplug API implementation.
- Introduce rte_eal_devargs_rmv API as EXPERIMENTAL.
- Use it to clean up resources on hotplug_remove.
- Fix hotplug implementation and support un pci bus. The scan was not idempotent, nor clean. Neither were the device fields.
- Implement plug operation for vdev bus.
This is needed for hotplug support and to make the EAL independent from vdev-specific API.
- Remove useless parameters from plug / unplug API.
This patchset is fairly big and complex. The hotplug API has been rushed and has never been tested outside of the special case of vdev bus.
These evolutions are proposed alongside this PMD as only this PMD allows to test this API at the moment, and without those evolutions this PMD cannot be used.
Gaetan Rivet (22):
eal: return device handle upon plugin
eal: fix hotplug add
devargs: introduce removal function
eal: release devargs on device removal
pci: use given name as generic name
pci: fix generic driver pointer on probe error
pci: fix hotplug operations
vdev: add dev to vdev macro
vdev: implement plug operation
bus: remove useless plug parameter
ethdev: save VLAN filter setting
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMD
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support device removal
net/failsafe: support link status change event
net/failsafe: support flow API isolation mode
MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 186 +++++ doc/guides/nics/features/failsafe.ini | 32 + doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 78 ++ drivers/net/failsafe/failsafe.c | 305 ++++++++ drivers/net/failsafe/failsafe_args.c | 475 ++++++++++++ drivers/net/failsafe/failsafe_eal.c | 134 ++++ drivers/net/failsafe/failsafe_ether.c | 437 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 245 ++++++ drivers/net/failsafe/failsafe_ops.c | 869 ++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 376 ++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 204 +++++ drivers/net/failsafe/rte_pmd_failsafe_version.map | 4 + lib/librte_eal/bsdapp/eal/eal_pci.c | 4 +- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_dev.c | 83 ++- lib/librte_eal/common/eal_common_devargs.c | 18 + lib/librte_eal/common/eal_common_pci.c | 49 +- lib/librte_eal/common/eal_common_vdev.c | 12 +- lib/librte_eal/common/eal_private.h | 5 + lib/librte_eal/common/include/rte_bus.h | 6 +- lib/librte_eal/common/include/rte_dev.h | 10 +- lib/librte_eal/common/include/rte_devargs.h | 18 + lib/librte_eal/common/include/rte_vdev.h | 7 + lib/librte_eal/linuxapp/eal/eal_pci.c | 4 +- lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + lib/librte_ether/rte_ethdev.c | 38 +- lib/librte_ether/rte_ethdev.h | 24 +- mk/rte.app.mk | 1 + 32 files changed, 3568 insertions(+), 72 deletions(-) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ether.c create mode 100644 drivers/net/failsafe/failsafe_flow.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c create mode 100644 drivers/net/failsafe/rte_pmd_failsafe_version.map
Signature · 1 line
2.1.4
PATCH v6 1/22 eal: return device handle upon plugin
--- lib/librte_eal/common/eal_common_dev.c | 40 +++++++++++++++++++++++---------- lib/librte_eal/common/include/rte_dev.h | 10 +++++---- 2 files changed, 34 insertions(+), 16 deletions(-)
lib/librte_eal/common/eal_common_dev.c +28 -12
@@ -42,6 +42,7 @@#include <rte_devargs.h> #include <rte_debug.h> #include <rte_devargs.h> +#include <rte_errno.h> #include <rte_log.h> #include "eal_private.h"
@@ -67,6 +68,7 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)int rte_eal_dev_attach (const char *name,const char *devargs) { +struct rte_device *dev;int ret;if (name ==NULL || devargs ==NULL ) {
@@ -74,9 +76,9 @@ int rte_eal_dev_attach(const char *name, const char *devargs)return -EINVAL ; } - ret =rte_eal_hotplug_add ("pci" , name, devargs); -if (ret && ret != -EINVAL ) -return ret; + dev =rte_eal_hotplug_add ("pci" , name, devargs); +if (dev ==NULL && rte_errno !=EINVAL ) +return -rte_errno;/* * If we haven't found a bus device the user meant to "hotplug" a
@@ -118,7 +120,8 @@ int rte_eal_dev_detach(struct rte_device *dev)return ret; } -int rte_eal_hotplug_add (const char *busname,const char *devname, +struct rte_device * +rte_eal_hotplug_add (const char *busname,const char *devname,const char *devargs) {struct rte_bus *bus;
@@ -128,31 +131,39 @@ int rte_eal_hotplug_add(const char *busname, const char *devname, bus =rte_bus_find_by_name (busname);if (bus ==NULL ) {RTE_LOG (ERR ,EAL ,"Cannot find bus (%s)\n" , busname); -return -ENOENT ; + rte_errno =ENOENT ; +return NULL ; }if (bus->plug ==NULL ) {RTE_LOG (ERR ,EAL ,"Function plug not supported by bus (%s)\n" , bus->name); -return -ENOTSUP ; + rte_errno =ENOTSUP ; +return NULL ; } ret = bus->scan (); -if (ret) -return ret; +if (ret) { + rte_errno = -ret; +return NULL ; + } dev = bus->find_device (NULL , cmp_detached_dev_name, devname);if (dev ==NULL ) {RTE_LOG (ERR ,EAL ,"Cannot find unplugged device (%s)\n" , devname); -return -EINVAL ; + rte_errno =EINVAL ; +return NULL ; } ret = bus->plug (dev, devargs); -if (ret) +if (ret) {RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , dev->name); -return ret; + rte_errno = -ret; +return NULL ; + } +return dev; }int rte_eal_hotplug_remove (const char *busname,const char *devname)
@@ -164,24 +175,29 @@ int rte_eal_hotplug_remove(const char *busname, const char *devname) bus =rte_bus_find_by_name (busname);if (bus ==NULL ) {RTE_LOG (ERR ,EAL ,"Cannot find bus (%s)\n" , busname); + rte_errno =ENOENT ;return -ENOENT ; }if (bus->unplug ==NULL ) {RTE_LOG (ERR ,EAL ,"Function unplug not supported by bus (%s)\n" , bus->name); + rte_errno =ENOTSUP ;return -ENOTSUP ; } dev = bus->find_device (NULL , cmp_dev_name, devname);if (dev ==NULL ) {RTE_LOG (ERR ,EAL ,"Cannot find plugged device (%s)\n" , devname); + rte_errno =EINVAL ;return -EINVAL ; } ret = bus->unplug (dev); -if (ret) +if (ret) {RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , dev->name); + rte_errno = -ret; + }return ret; }
lib/librte_eal/common/include/rte_dev.h +6 -4
@@ -218,10 +218,12 @@ int rte_eal_dev_detach(struct rte_device *dev);* @param devargs * Device arguments to be passed to the driver. * @return -* 0 on success, negative on error. +* The pointer to the plugged rte_device on success. +* NULL on error. rte_errno is then set. */ -int rte_eal_hotplug_add (const char *busname,const char *devname, -const char *devargs); +struct rte_device *rte_eal_hotplug_add (const char *busname, +const char *devname, +const char *devargs);/** * @warning
@@ -234,7 +236,7 @@ int rte_eal_hotplug_add(const char *busname, const char *devname,* @param devname * The device name being removed. * @return -* 0 on success, negative on error. +* 0 on success, negative on error. rte_errno is then set. */ int rte_eal_hotplug_remove (const char *busname,const char *devname);
Signature · 1 line
2.1.4
PATCH v6 2/22 eal: fix hotplug add
In reply to Gaetan RivetNew device should be represented by an rte_devarg prior to being plugged.
--- lib/librte_eal/common/eal_common_dev.c | 43 +++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-)
lib/librte_eal/common/eal_common_dev.c +40 -3
@@ -120,12 +120,32 @@ int rte_eal_dev_detach(struct rte_device *dev)return ret; } +static char * +full_dev_name (const char *bus,const char *dev,const char *args) +{ +char *name; +size_t len; + + len =strlen (bus) +1 + +strlen (dev) +1 + +strlen (args) +1 ; + name =calloc (1 , len); +if (name ==NULL ) { +RTE_LOG (ERR ,EAL ,"Could not allocate full device name\n" ); +return NULL ; + } +snprintf (name, len,"%s:%s,%s" , bus, dev, + args ? args :"" ); +return name; +} +struct rte_device *rte_eal_hotplug_add (const char *busname,const char *devname,const char *devargs) {struct rte_bus *bus;struct rte_device *dev; +char *name;int ret; bus =rte_bus_find_by_name (busname);
@@ -142,10 +162,22 @@ rte_eal_hotplug_add(const char *busname, const char *devname,return NULL ; } + name =full_dev_name (busname, devname, devargs); +if (name ==NULL ) { + rte_errno =ENOMEM ; +return NULL ; + } + + ret =rte_eal_devargs_add (RTE_DEVTYPE_WHITELISTED , name); +if (ret) { + rte_errno =EINVAL ; + goto err_name; + } + ret = bus->scan ();if (ret) { rte_errno = -ret; -return NULL ; + goto err_name; } dev = bus->find_device (NULL , cmp_detached_dev_name, devname);
@@ -153,7 +185,7 @@ rte_eal_hotplug_add(const char *busname, const char *devname,RTE_LOG (ERR ,EAL ,"Cannot find unplugged device (%s)\n" , devname); rte_errno =EINVAL ; -return NULL ; + goto err_name; } ret = bus->plug (dev, devargs);
@@ -161,9 +193,14 @@ rte_eal_hotplug_add(const char *busname, const char *devname,RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , dev->name); rte_errno = -ret; -return NULL ; + goto err_name; } +free (name);return dev; + +err_name: +free (name); +return NULL ; }int rte_eal_hotplug_remove (const char *busname,const char *devname)
Signature · 1 line
2.1.4
PATCH v6 3/22 devargs: introduce removal function
In reply to Gaetan RivetHotplug support introduces the possibility of removing devices from the system. Allocated resources must be freed.
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_devargs.c | 18 ++++++++++++++++++ lib/librte_eal/common/include/rte_devargs.h | 18 ++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 38 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -207,6 +207,7 @@ EXPERIMENTAL { global: rte_eal_devargs_parse; + rte_eal_devargs_rmv; rte_eal_hotplug_add; rte_eal_hotplug_remove;
lib/librte_eal/common/eal_common_devargs.c +18 -0
@@ -41,6 +41,7 @@#include <string.h> #include <rte_devargs.h> +#include <rte_tailq.h> #include "eal_private.h" /** Global list of user devices */
@@ -185,6 +186,23 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)return -1 ; } +int +rte_eal_devargs_rmv (const char *busname,const char *devname) +{ +struct rte_devargs *d; +void *tmp; + + TAILQ_FOREACH_SAFE(d, &devargs_list, next, tmp) { +if (strcmp (d->bus->name, busname) ==0 && +strcmp (d->name, devname) ==0 ) { +TAILQ_REMOVE (&devargs_list, d, next); +free (d->args); +free (d); + } + } +return 1 ; +} +/* count the number of devices of a specified type */ unsigned int rte_eal_devargs_type_count (enum rte_devtype devtype)
lib/librte_eal/common/include/rte_devargs.h +18 -0
@@ -163,6 +163,24 @@ rte_eal_devargs_parse(const char *dev,int rte_eal_devargs_add (enum rte_devtype devtype,const char *devargs_str);/** +* Remove a device from the user device list. +* Its resources are freed. +* If the devargs cannot be found, nothing happens. +* +* @param busname +* bus name of the devargs to remove. +* +* @param devname +* device name of the devargs to remove. +* +* @return +* 0 on success. +* <0 on error. +* >0 if the devargs was not within the user device list. +*/ +int rte_eal_devargs_rmv (const char *busname,const char *devname); + +/** * Count the number of user devices of a specified type * * @param devtype
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -212,6 +212,7 @@ EXPERIMENTAL { global: rte_eal_devargs_parse; + rte_eal_devargs_rmv; rte_eal_hotplug_add; rte_eal_hotplug_remove;
Signature · 1 line
2.1.4
PATCH v6 4/22 eal: release devargs on device removal
In reply to Gaetan RivetRelease resources allocated for devargs when the device is being removed.
--- lib/librte_eal/common/eal_common_dev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
lib/librte_eal/common/eal_common_dev.c +7 -3
@@ -177,7 +177,7 @@ rte_eal_hotplug_add(const char *busname, const char *devname, ret = bus->scan ();if (ret) { rte_errno = -ret; - goto err_name; + goto err_devarg; } dev = bus->find_device (NULL , cmp_detached_dev_name, devname);
@@ -185,7 +185,7 @@ rte_eal_hotplug_add(const char *busname, const char *devname,RTE_LOG (ERR ,EAL ,"Cannot find unplugged device (%s)\n" , devname); rte_errno =EINVAL ; - goto err_name; + goto err_devarg; } ret = bus->plug (dev, devargs);
@@ -193,11 +193,13 @@ rte_eal_hotplug_add(const char *busname, const char *devname,RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , dev->name); rte_errno = -ret; - goto err_name; + goto err_devarg; }free (name);return dev; +err_devarg: +rte_eal_devargs_rmv (busname, devname); err_name:free (name);return NULL ;
@@ -230,6 +232,8 @@ int rte_eal_hotplug_remove(const char *busname, const char *devname)return -EINVAL ; } +rte_eal_devargs_rmv (busname, devname); + dev->devargs =NULL ; ret = bus->unplug (dev);if (ret) { RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",
Signature · 1 line
2.1.4
PATCH v6 5/22 pci: use given name as generic name
In reply to Gaetan RivetThe PCI device is referenced by other DPDK systems by the name of its parameter, not by the system name.
--- lib/librte_eal/bsdapp/eal/eal_pci.c | 4 ++-- lib/librte_eal/common/eal_common_pci.c | 21 ++++++++++++++++----- lib/librte_eal/common/eal_private.h | 5 +++++ lib/librte_eal/linuxapp/eal/eal_pci.c | 4 ++-- 4 files changed, 25 insertions(+), 9 deletions(-)
lib/librte_eal/bsdapp/eal/eal_pci.c +2 -2
@@ -282,8 +282,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)/* FreeBSD has no NUMA support (yet) */ dev->device.numa_node =0 ; -rte_pci_device_name (&dev->addr, dev->name,sizeof (dev->name)); - dev->device.name = dev->name; +pci_name_set (dev);/* FreeBSD has only one pass through driver */ dev->kdrv =RTE_KDRV_NIC_UIO ;
@@ -334,6 +333,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf) }else {/* already registered */ dev2->kdrv = dev->kdrv; dev2->max_vfs = dev->max_vfs; +pci_name_set (dev2);memmove (dev2->mem_resource, dev->mem_resource,sizeof (dev->mem_resource));
lib/librte_eal/common/eal_common_pci.c +16 -5
@@ -88,6 +88,21 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)return NULL ; } +void +pci_name_set (struct rte_pci_device *dev) +{ +struct rte_devargs *devargs; + +rte_pci_device_name (&dev->addr, + dev->name,sizeof (dev->name)); + devargs =pci_devargs_lookup (dev); + dev->device.devargs = devargs; +if (devargs !=NULL ) + dev->device.name = dev->device.devargs->name; +else + dev->device.name = dev->name; +} +/* map a particular resource from a file */ void * pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
@@ -396,11 +411,7 @@ rte_pci_probe(void)FOREACH_DEVICE_ON_PCIBUS (dev) { probed++; -/* set devargs in PCI structure */ - devargs =pci_devargs_lookup (dev); -if (devargs !=NULL ) - dev->device.devargs = devargs; - + devargs = dev->device.devargs;/* probe all or only whitelisted devices */ if (probe_all) ret =pci_probe_all_drivers (dev);
lib/librte_eal/common/eal_private.h +5 -0
@@ -113,6 +113,11 @@ struct rte_pci_driver;struct rte_pci_device ;/** +* Find the name of a PCI device. +*/ +void pci_name_set (struct rte_pci_device *dev); + +/** * Add a PCI device to the PCI Bus (append to PCI Device list). This function * also updates the bus references of the PCI Device (and the generic device * object embedded within.
lib/librte_eal/linuxapp/eal/eal_pci.c +2 -2
@@ -324,8 +324,7 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) dev->device.numa_node =0 ; } -rte_pci_device_name (addr, dev->name,sizeof (dev->name)); - dev->device.name = dev->name; +pci_name_set (dev);/* parse resources */ snprintf (filename,sizeof (filename),"%s/resource" , dirname);
@@ -373,6 +372,7 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) }else {/* already registered */ dev2->kdrv = dev->kdrv; dev2->max_vfs = dev->max_vfs; +pci_name_set (dev2);memmove (dev2->mem_resource, dev->mem_resource,sizeof (dev->mem_resource));free (dev);
Signature · 1 line
2.1.4
PATCH v6 6/22 pci: fix generic driver pointer on probe error
In reply to Gaetan RivetThe field is set but never resetted on error.
--- lib/librte_eal/common/eal_common_pci.c | 1 + 1 file changed, 1 insertion(+)
lib/librte_eal/common/eal_common_pci.c +1 -0
@@ -237,6 +237,7 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr, ret = dr->probe (dr, dev);if (ret) { dev->driver =NULL ; + dev->device.driver =NULL ; if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&/* Don't unmap if device is unsupported and * driver needs mapped resources.
Signature · 1 line
2.1.4
PATCH v6 7/22 pci: fix hotplug operations
In reply to Gaetan RivetThe device handle is already known and does not have to be infered from the PCI address.
Additionally, rte_memcpy.h was erroneously included.
--- lib/librte_eal/common/eal_common_pci.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-)
lib/librte_eal/common/eal_common_pci.c +6 -19
@@ -47,7 +47,6 @@#include <rte_pci.h> #include <rte_per_lcore.h> #include <rte_memory.h> -#include <rte_memcpy.h> #include <rte_memzone.h> #include <rte_eal.h> #include <rte_string_fns.h>
@@ -538,32 +537,20 @@ pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,static int pci_plug(struct rte_device *dev, const char *devargs __rte_unused) { -struct rte_pci_device *pdev; -struct rte_pci_addr *addr; - - addr = &RTE_DEV_TO_PCI (dev)->addr; - -/* Find the current device holding this address in the bus. */ -FOREACH_DEVICE_ON_PCIBUS (pdev) { -if (rte_eal_compare_pci_addr (&pdev->addr, addr) ==0 ) -return rte_pci_probe_one (addr); - } - - rte_errno =ENODEV ; -return -1 ; +return pci_probe_all_drivers (RTE_DEV_TO_PCI (dev)); }static int pci_unplug (struct rte_device *dev) {struct rte_pci_device *pdev; +int ret; pdev =RTE_DEV_TO_PCI (dev); -if (rte_pci_detach (&pdev->addr) !=0 ) { - rte_errno =ENODEV ; -return -1 ; - } -return 0 ; + ret =rte_pci_detach_dev (pdev); +rte_pci_remove_device (pdev); +free (pdev); +return ret; }struct rte_pci_bus rte_pci_bus = {
Signature · 1 line
2.1.4
PATCH v6 8/22 vdev: add dev to vdev macro
In reply to Gaetan Rivet--- lib/librte_eal/common/include/rte_vdev.h | 7 +++++++ 1 file changed, 7 insertions(+)
lib/librte_eal/common/include/rte_vdev.h +7 -0
@@ -46,6 +46,13 @@ struct rte_vdev_device {struct rte_device device;/**< Inherit core device */ }; +/** +* @internal +* Helper macro for drivers that need to convert to struct rte_vdev_device. +*/ +#define RTE_DEV_TO_VDEV (ptr) \ + container_of(ptr, struct rte_vdev_device, device) +static inline const char *rte_vdev_device_name (const struct rte_vdev_device *dev) {
Signature · 1 line
2.1.4
PATCH v6 9/22 vdev: implement plug operation
In reply to Gaetan Rivet--- lib/librte_eal/common/eal_common_vdev.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
lib/librte_eal/common/eal_common_vdev.c +7 -5
@@ -356,12 +356,14 @@ vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, }static int +vdev_plug(struct rte_device *dev, const char *args __rte_unused) +{ +return vdev_probe_all_drivers (RTE_DEV_TO_VDEV (dev)); +} + +static int vdev_unplug (struct rte_device *dev) { -/* -* The virtual bus doesn't support 'unattached' devices so this is -* actually equal to hotplugging removal of it. -*/ return rte_vdev_uninit (dev->name); }
@@ -369,7 +371,7 @@ static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, .find_device = vdev_find_device, - /* .plug = NULL, see comment on vdev_unplug */ + .plug = vdev_plug, .unplug = vdev_unplug, .parse = vdev_parse, };
Signature · 1 line
2.1.4
PATCH v6 10/22 bus: remove useless plug parameter
In reply to Gaetan RivetThe prior scan should link the relevant rte_devargs to the newly allocated rte_device. As such, it is useless to pass device arguments to the plug callback.
--- lib/librte_eal/common/eal_common_dev.c | 2 +- lib/librte_eal/common/eal_common_pci.c | 2 +- lib/librte_eal/common/eal_common_vdev.c | 2 +- lib/librte_eal/common/include/rte_bus.h | 6 +----- 4 files changed, 4 insertions(+), 8 deletions(-)
lib/librte_eal/common/eal_common_dev.c +1 -1
@@ -188,7 +188,7 @@ rte_eal_hotplug_add(const char *busname, const char *devname, goto err_devarg; } - ret = bus->plug (dev, devargs); + ret = bus->plug (dev);if (ret) {RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , dev->name);
lib/librte_eal/common/eal_common_pci.c +1 -1
@@ -535,7 +535,7 @@ pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, }static int -pci_plug(struct rte_device *dev, const char *devargs __rte_unused) +pci_plug (struct rte_device *dev) {return pci_probe_all_drivers (RTE_DEV_TO_PCI (dev)); }
lib/librte_eal/common/eal_common_vdev.c +1 -1
@@ -356,7 +356,7 @@ vdev_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, }static int -vdev_plug(struct rte_device *dev, const char *args __rte_unused) +vdev_plug (struct rte_device *dev) {return vdev_probe_all_drivers (RTE_DEV_TO_VDEV (dev)); }
lib/librte_eal/common/include/rte_bus.h +1 -5
@@ -114,15 +114,11 @@ typedef struct rte_device ** @param dev * Device pointer that was returned by a previous call to find_device. * -* @param devargs -* Device declaration. -* * @return * 0 on success. * !0 on error. */ -typedef int (*rte_bus_plug_t )(struct rte_device *dev, -const char *devargs); +typedef int (*rte_bus_plug_t )(struct rte_device *dev);/** * Implementation specific remove function which is responsible for unlinking
Signature · 1 line
2.1.4
PATCH v6 11/23 ethdev: add flow API rule copy function
In reply to Gaetan RivetThis allows PMDs and applications to save flow rules in their generic format for later processing. This is useful when rules cannot be applied immediately, such as when the device is not properly initialized.
--- lib/librte_ether/rte_ether_version.map | 1 + lib/librte_ether/rte_flow.c | 227 +++++++++++++++++++++++++++++++++ lib/librte_ether/rte_flow.h | 40 ++++++ 3 files changed, 268 insertions(+)
lib/librte_ether/rte_ether_version.map +1 -0
@@ -152,6 +152,7 @@ DPDK_17.08 { global: _rte_eth_dev_callback_process; + rte_flow_copy; rte_flow_isolate; } DPDK_17.05;
lib/librte_ether/rte_flow.c +227 -0
244 lines not on this page · raw message
lib/librte_ether/rte_flow.h +40 -0
@@ -1266,6 +1266,46 @@ rte_flow_query(uint8_t port_id,int rte_flow_isolate (uint8_t port_id,int set,struct rte_flow_error *error); +/** +* Generic flow representation. +* +* This form is sufficient to describe an rte_flow independently from any +* PMD implementation and allows for replayability and identification. +*/ +struct rte_flow_desc { +size_t size;/**< Allocated space including data[]. */ +struct rte_flow_attr attr;/**< Attributes. */ +struct rte_flow_item *items;/**< Items. */ +struct rte_flow_action *actions;/**< Actions. */ +uint8_t data[];/**< Storage for items/actions. */ +}; + +/** +* Copy an rte_flow rule description. +* +* @param[in] fd +* Flow rule description. +* @param[in] len +* Total size of allocated data for the flow description. +* @param[in] attr +* Flow rule attributes. +* @param[in] items +* Pattern specification (list terminated by the END pattern item). +* @param[in] actions +* Associated actions (list terminated by the END action). +* +* @return +* If len is greater or equal to the size of the flow, the total size of the +* flow description and its data. +* If len is lower than the size of the flow, the number of bytes that would +* have been written to desc had it been sufficient. Nothing is written. +*/ +size_t +rte_flow_copy (struct rte_flow_desc *fd,size_t len, +const struct rte_flow_attr *attr, +const struct rte_flow_item *items, +const struct rte_flow_action *actions); + #ifdef __cplusplus }#endif
Signature · 1 line
2.1.4
PATCH v6 11/22 ethdev: save VLAN filter setting
In reply to Gaetan RivetOther configuration items (i.e. MAC addresses) are stored within rte_eth_dev_data, but not this one.
--- lib/librte_ether/rte_ethdev.c | 19 ++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +18 -1
@@ -1981,6 +1981,7 @@ int rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) { struct rte_eth_dev *dev; +int ret;RTE_ETH_VALID_PORTID_OR_ERR_RET (port_id, -ENODEV ); dev = &rte_eth_devices[port_id];
@@ -1996,7 +1997,23 @@ rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) }RTE_FUNC_PTR_OR_ERR_RET (*dev->dev_ops->vlan_filter_set, -ENOTSUP ); -return (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); + ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); +if (ret ==0 ) { +struct rte_vlan_filter_conf *vfc; +int vidx; +int vbit; + + vfc = &dev->data->vlan_filter_conf; + vidx = vlan_id /64 ; + vbit = vlan_id %64 ; + +if (on) + vfc->ids[vidx] |=UINT64_C (1 ) << vbit; +else + vfc->ids[vidx] &= ~(UINT64_C (1 ) << vbit); + } + +return ret; }int
lib/librte_ether/rte_ethdev.h +10 -0
@@ -374,6 +374,14 @@ enum rte_vlan_type { };/** +* A structure used to describe a vlan filter. +* If the bit corresponding to a VID is set, such VID is on. +*/ +struct rte_vlan_filter_conf { +uint64_t ids[64 ]; +}; + +/** * A structure used to configure the Receive Side Scaling (RSS) feature * of an Ethernet port. * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1674,6 +1682,8 @@ struct rte_eth_dev_data {uint32_t dev_flags;/**< Capabilities */ enum rte_kernel_driver kdrv;/**< Kernel driver passthrough */ int numa_node;/**< NUMA node connection */ +struct rte_vlan_filter_conf vlan_filter_conf; +/**< VLAN filter configuration. */ };/** Device supports hotplug detach */
Signature · 1 line
2.1.4
PATCH v6 12/22 ethdev: add deferred intermediate device state
In reply to Gaetan RivetThis device state means that the device is managed externally, by whichever party has set this state (PMD or application).
Note: this new device state is only an information. The related device structure and operators are still valid and can be used normally.
It is however made private by device management helpers within ethdev, making the device invisible to applications.
--- lib/librte_ether/rte_ethdev.c | 3 ++- lib/librte_ether/rte_ethdev.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +2 -1
@@ -291,7 +291,8 @@ int rte_eth_dev_is_valid_port(uint8_t port_id) {if (port_id >=RTE_MAX_ETHPORTS || - rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED ) + (rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED && + rte_eth_devices[port_id].state !=RTE_ETH_DEV_DEFERRED ))return 0 ;else return 1 ;
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1589,6 +1589,7 @@ struct rte_eth_rxtx_callback {enum rte_eth_dev_state {RTE_ETH_DEV_UNUSED =0 ,RTE_ETH_DEV_ATTACHED , +RTE_ETH_DEV_DEFERRED , };/**
Signature · 1 line
2.1.4
PATCH v6 12/23 ethdev: save VLAN filter setting
In reply to Gaetan RivetOther configuration items (i.e. MAC addresses) are stored within rte_eth_dev_data, but not this one.
--- lib/librte_ether/rte_ethdev.c | 19 ++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +18 -1
@@ -1981,6 +1981,7 @@ int rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) { struct rte_eth_dev *dev; +int ret;RTE_ETH_VALID_PORTID_OR_ERR_RET (port_id, -ENODEV ); dev = &rte_eth_devices[port_id];
@@ -1996,7 +1997,23 @@ rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on) }RTE_FUNC_PTR_OR_ERR_RET (*dev->dev_ops->vlan_filter_set, -ENOTSUP ); -return (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); + ret = (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on); +if (ret ==0 ) { +struct rte_vlan_filter_conf *vfc; +int vidx; +int vbit; + + vfc = &dev->data->vlan_filter_conf; + vidx = vlan_id /64 ; + vbit = vlan_id %64 ; + +if (on) + vfc->ids[vidx] |=UINT64_C (1 ) << vbit; +else + vfc->ids[vidx] &= ~(UINT64_C (1 ) << vbit); + } + +return ret; }int
lib/librte_ether/rte_ethdev.h +10 -0
@@ -374,6 +374,14 @@ enum rte_vlan_type { };/** +* A structure used to describe a vlan filter. +* If the bit corresponding to a VID is set, such VID is on. +*/ +struct rte_vlan_filter_conf { +uint64_t ids[64 ]; +}; + +/** * A structure used to configure the Receive Side Scaling (RSS) feature * of an Ethernet port. * If not NULL, the *rss_key* pointer of the *rss_conf* structure points
@@ -1674,6 +1682,8 @@ struct rte_eth_dev_data {uint32_t dev_flags;/**< Capabilities */ enum rte_kernel_driver kdrv;/**< Kernel driver passthrough */ int numa_node;/**< NUMA node connection */ +struct rte_vlan_filter_conf vlan_filter_conf; +/**< VLAN filter configuration. */ };/** Device supports hotplug detach */
Signature · 1 line
2.1.4
PATCH v6 13/23 ethdev: add deferred intermediate device state
In reply to Gaetan RivetThis device state means that the device is managed externally, by whichever party has set this state (PMD or application).
Note: this new device state is only an information. The related device structure and operators are still valid and can be used normally.
It is however made private by device management helpers within ethdev, making the device invisible to applications.
--- lib/librte_ether/rte_ethdev.c | 3 ++- lib/librte_ether/rte_ethdev.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +2 -1
@@ -291,7 +291,8 @@ int rte_eth_dev_is_valid_port(uint8_t port_id) {if (port_id >=RTE_MAX_ETHPORTS || - rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED ) + (rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED && + rte_eth_devices[port_id].state !=RTE_ETH_DEV_DEFERRED ))return 0 ;else return 1 ;
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1589,6 +1589,7 @@ struct rte_eth_rxtx_callback {enum rte_eth_dev_state {RTE_ETH_DEV_UNUSED =0 ,RTE_ETH_DEV_ATTACHED , +RTE_ETH_DEV_DEFERRED , };/**
Signature · 1 line
2.1.4
PATCH v6 13/22 ethdev: count devices consistently
In reply to Gaetan RivetMake the rte_eth_dev_count() return the number of available devices even after some are detached by the hotplug API or put in a deferred state.
--- lib/librte_ether/rte_ethdev.c | 16 +++++++++------- lib/librte_ether/rte_ethdev.h | 13 ++++++------- 2 files changed, 15 insertions(+), 14 deletions(-)
lib/librte_ether/rte_ethdev.c +9 -7
@@ -72,7 +72,6 @@ static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS ];static struct rte_eth_dev_data *rte_eth_dev_data;static uint8_t eth_dev_last_created_port; -static uint8_t nb_ports;/* spinlock for eth device callbacks */ static rte_spinlock_t rte_eth_dev_cb_lock =RTE_SPINLOCK_INITIALIZER ;
@@ -210,7 +209,6 @@ eth_dev_get(uint8_t port_id)TAILQ_INIT (&(eth_dev->link_intr_cbs)); eth_dev_last_created_port = port_id; - nb_ports++;return eth_dev; }
@@ -283,7 +281,6 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)return -EINVAL ; eth_dev->state =RTE_ETH_DEV_UNUSED ; - nb_ports--;return 0 ; }
@@ -308,7 +305,15 @@ rte_eth_dev_socket_id(uint8_t port_id)uint8_t rte_eth_dev_count (void ) { -return nb_ports; +uint8_t p; +uint8_t count; + + count =0 ; + +RTE_ETH_FOREACH_DEV (p) + count++; + +return count; }int
@@ -341,9 +346,6 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)return -EINVAL ; } -if (!nb_ports) -return -ENODEV ; -RTE_ETH_FOREACH_DEV (i) {if (!rte_eth_devices[i].device)continue ;
lib/librte_ether/rte_ethdev.h +6 -7
@@ -1724,13 +1724,12 @@ uint8_t rte_eth_find_next(uint8_t port_id);/** * Get the total number of Ethernet devices that have been successfully -* initialized by the [matching] Ethernet driver during the PCI probing phase. -* All devices whose port identifier is in the range -* [0, rte_eth_dev_count() - 1] can be operated on by network applications -* immediately after invoking rte_eal_init(). -* If the application unplugs a port using hotplug function, The enabled port -* numbers may be noncontiguous. In the case, the applications need to manage -* enabled port by using the ``RTE_ETH_FOREACH_DEV()`` macro. +* initialized by the matching Ethernet driver during the PCI probing phase +* and that are available for applications to use. These devices must be +* accessed by using the ``RTE_ETH_FOREACH_DEV()`` macro to deal with +* non-contiguous ranges of devices. +* These non-contiguous ranges can be created by calls to hotplug functions or +* by some PMDs. * * @return * - The total number of usable Ethernet devices.
Signature · 1 line
2.1.4
PATCH v6 14/23 ethdev: count devices consistently
In reply to Gaetan RivetMake the rte_eth_dev_count() return the number of available devices even after some are detached by the hotplug API or put in a deferred state.
--- lib/librte_ether/rte_ethdev.c | 16 +++++++++------- lib/librte_ether/rte_ethdev.h | 13 ++++++------- 2 files changed, 15 insertions(+), 14 deletions(-)
lib/librte_ether/rte_ethdev.c +9 -7
@@ -72,7 +72,6 @@ static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS ];static struct rte_eth_dev_data *rte_eth_dev_data;static uint8_t eth_dev_last_created_port; -static uint8_t nb_ports;/* spinlock for eth device callbacks */ static rte_spinlock_t rte_eth_dev_cb_lock =RTE_SPINLOCK_INITIALIZER ;
@@ -210,7 +209,6 @@ eth_dev_get(uint8_t port_id)TAILQ_INIT (&(eth_dev->link_intr_cbs)); eth_dev_last_created_port = port_id; - nb_ports++;return eth_dev; }
@@ -283,7 +281,6 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)return -EINVAL ; eth_dev->state =RTE_ETH_DEV_UNUSED ; - nb_ports--;return 0 ; }
@@ -308,7 +305,15 @@ rte_eth_dev_socket_id(uint8_t port_id)uint8_t rte_eth_dev_count (void ) { -return nb_ports; +uint8_t p; +uint8_t count; + + count =0 ; + +RTE_ETH_FOREACH_DEV (p) + count++; + +return count; }int
@@ -341,9 +346,6 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)return -EINVAL ; } -if (!nb_ports) -return -ENODEV ; -RTE_ETH_FOREACH_DEV (i) {if (!rte_eth_devices[i].device)continue ;
lib/librte_ether/rte_ethdev.h +6 -7
@@ -1724,13 +1724,12 @@ uint8_t rte_eth_find_next(uint8_t port_id);/** * Get the total number of Ethernet devices that have been successfully -* initialized by the [matching] Ethernet driver during the PCI probing phase. -* All devices whose port identifier is in the range -* [0, rte_eth_dev_count() - 1] can be operated on by network applications -* immediately after invoking rte_eal_init(). -* If the application unplugs a port using hotplug function, The enabled port -* numbers may be noncontiguous. In the case, the applications need to manage -* enabled port by using the ``RTE_ETH_FOREACH_DEV()`` macro. +* initialized by the matching Ethernet driver during the PCI probing phase +* and that are available for applications to use. These devices must be +* accessed by using the ``RTE_ETH_FOREACH_DEV()`` macro to deal with +* non-contiguous ranges of devices. +* These non-contiguous ranges can be created by calls to hotplug functions or +* by some PMDs. * * @return * - The total number of usable Ethernet devices.
Signature · 1 line
2.1.4
PATCH v6 14/22 net/failsafe: add fail-safe PMD
In reply to Gaetan RivetIntroduce the fail-safe poll mode driver initialization and enable its build infrastructure.
This PMD allows for applications to benefit from true hot-plugging support without having to implement it.
It intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back. It also allows defining a contingency to the removal of a device, by designating a fail-over device that will take on transmitting operations if the preferred device is removed.
Applications only see a fail-safe instance, without caring for underlying activity ensuring their continued operations.
--- MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 133 +++++ doc/guides/nics/features/failsafe.ini | 24 + doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 76 +++ drivers/net/failsafe/failsafe.c | 231 ++++++++ drivers/net/failsafe/failsafe_args.c | 331 +++++++++++ drivers/net/failsafe/failsafe_eal.c | 154 +++++ drivers/net/failsafe/failsafe_ops.c | 663 ++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 227 ++++++++ drivers/net/failsafe/failsafe_rxtx.c | 107 ++++ drivers/net/failsafe/rte_pmd_failsafe_version.map | 4 + mk/rte.app.mk | 1 + 15 files changed, 1965 insertions(+) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c create mode 100644 drivers/net/failsafe/rte_pmd_failsafe_version.map
MAINTAINERS +5 -0
@@ -336,6 +336,11 @@ F: drivers/net/enic/ F: doc/guides/nics/enic.rst F: doc/guides/nics/features/enic.ini +Fail-safe PMD +M: Gaetan Rivet <[email protected]> +F: drivers/net/failsafe/ +F: doc/guides/nics/fail_safe.rst + Intel e1000 M: Wenzhuo Lu <[email protected]> F: drivers/net/e1000/
config/common_base +6 -0
@@ -420,6 +420,12 @@ CONFIG_RTE_LIBRTE_PMD_XENVIRT=n CONFIG_RTE_LIBRTE_PMD_NULL=y # +# Compile fail-safe PMD +# +CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y +CONFIG_RTE_LIBRTE_PMD_FAILSAFE_DEBUG=n + +# # Do prefetch of packet data within PMD driver receive function # CONFIG_RTE_PMD_PACKET_PREFETCH=y
doc/guides/nics/fail_safe.rst new file +133 -0
133 lines not on this page · raw message
doc/guides/nics/features/failsafe.ini new file +24 -0
@@ -0,0 +1,24 @@ +; +; Supported features of the 'fail-safe' poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Link status = Y +Queue start/stop = Y +MTU update = Y +Jumbo frame = Y +Promiscuous mode = Y +Allmulticast mode = Y +Unicast MAC filter = Y +Multicast MAC filter = Y +VLAN filter = Y +Packet type parsing = Y +Basic stats = Y +Stats per queue = Y +ARMv7 = Y +ARMv8 = Y +Power8 = Y +x86-32 = Y +x86-64 = Y +Usage doc = Y
doc/guides/nics/index.rst +1 -0
@@ -64,6 +64,7 @@ Network Interface Controller Drivers vhost vmxnet3 pcap_ring + fail_safe **Figures**
drivers/net/Makefile +2 -0
@@ -59,6 +59,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena DEPDIRS-ena = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic DEPDIRS-enic = $(core-libs) librte_hash +DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe +DEPDIRS-failsafe = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k DEPDIRS-fm10k = $(core-libs) librte_hash DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
drivers/net/failsafe/Makefile new file +76 -0
76 lines not on this page · raw message
drivers/net/failsafe/failsafe.c new file +231 -0
231 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c new file +331 -0
331 lines not on this page · raw message
drivers/net/failsafe/failsafe_eal.c new file +154 -0
154 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c new file +663 -0
663 lines not on this page · raw message
drivers/net/failsafe/failsafe_private.h new file +227 -0
227 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c new file +107 -0
107 lines not on this page · raw message
drivers/net/failsafe/rte_pmd_failsafe_version.map new file +4 -0
@@ -0,0 +1,4 @@ +DPDK_17.08 { + + local: *; +};
mk/rte.app.mk +1 -0
@@ -120,6 +120,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += -lrte_pmd_fm10k +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += -lrte_pmd_failsafe _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
Signature · 1 line
2.1.4
PATCH v6 15/22 net/failsafe: add plug-in support
In reply to Gaetan RivetPeriodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
--- doc/guides/nics/fail_safe.rst | 19 +++ drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 71 ++++++++++ drivers/net/failsafe/failsafe_args.c | 32 +++++ drivers/net/failsafe/failsafe_eal.c | 30 +---- drivers/net/failsafe/failsafe_ether.c | 228 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 25 ++-- drivers/net/failsafe/failsafe_private.h | 60 ++++++++- 8 files changed, 423 insertions(+), 43 deletions(-) create mode 100644 drivers/net/failsafe/failsafe_ether.c
doc/guides/nics/fail_safe.rst +19 -0
@@ -102,6 +102,11 @@ Fail-safe command line parameters address is generated, that will be subsequently applied to all sub-device once they are probed. +- **hotplug_poll** parameter [UINT64] (default **2000**) + + This parameter allows the user to configure the amount of time in milliseconds + between two slave upkeep round. + Usage example ~~~~~~~~~~~~~
@@ -131,3 +136,17 @@ Care must be taken, however, to respect the **ether** API concerning device access, and in particular, using the ``RTE_ETH_FOREACH_DEV`` macro to iterate over ethernet devices, instead of directly accessing them or by writing one's own device iterator. + +Plug-in feature +--------------- + +A sub-device can be defined without existing on the system when the fail-safe +PMD is initialized. Upon probing this device, the fail-safe PMD will detect its +absence and postpone its use. It will then register for a periodic check on any +missing sub-device. + +During this time, the fail-safe PMD can be used normally, configured and told to +emit and receive packets. It will store any applied configuration, and try to +apply it upon the probing of its missing sub-device. After this configuration +pass, the new sub-device will be synchronized with other sub-devices, i.e. be +started if the fail-safe PMD has been started by the user before.
drivers/net/failsafe/Makefile +1 -0
@@ -44,6 +44,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_args.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c # No exported include files
drivers/net/failsafe/failsafe.c +71 -0
83 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c +32 -0
@@ -45,9 +45,11 @@typedef int (parse_cb )(struct rte_eth_dev *dev,const char *params,uint8_t head); +uint64_t hotplug_poll;int mac_from_arg;const char *pmd_failsafe_init_parameters[] = { +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ,PMD_FAILSAFE_MAC_KVARG ,NULL , };
@@ -221,6 +223,24 @@ fs_remove_sub_devices_definition(char params[DEVARGS_MAXLEN]) }static int +fs_get_u64_arg(const char *key __rte_unused, +const char *value,void *out) +{ +uint64_t *u64 = out; +char *endptr =NULL ; + +if ((value ==NULL ) || (out ==NULL )) +return -EINVAL ; + errno =0 ; + *u64 =strtoull (value, &endptr,0 ); +if (errno !=0 ) +return -errno; +if (endptr == value) +return -1 ; +return 0 ; +} + +static int fs_get_mac_addr_arg(const char *key __rte_unused,const char *value,void *out) {
@@ -252,6 +272,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) ret =0 ; priv->subs_tx =FAILSAFE_MAX_ETHPORTS ;/* default parameters */ + hotplug_poll =FAILSAFE_HOTPLUG_DEFAULT_TIMEOUT_MS ; mac_from_arg =0 ; n =snprintf (mut_params,sizeof (mut_params),"%s" , params);if (n >=sizeof (mut_params)) {
@@ -274,6 +295,16 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) PMD_FAILSAFE_PARAM_STRING);return -1 ; } +/* PLUG_IN event poll timer */ + arg_count =rte_kvargs_count (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ); +if (arg_count ==1 ) { + ret =rte_kvargs_process (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG , + &fs_get_u64_arg, &hotplug_poll); +if (ret <0 ) + goto free_kvlist; + }/* MAC addr */ arg_count =rte_kvargs_count (kvlist,PMD_FAILSAFE_MAC_KVARG );
@@ -287,6 +318,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) mac_from_arg =1 ; } } +PRIV (dev)->state =DEV_PARSED ; free_kvlist:rte_kvargs_free (kvlist);return ret;
drivers/net/failsafe/failsafe_eal.c +4 -26
@@ -88,37 +88,14 @@ fs_bus_init(struct rte_eth_dev *dev)int failsafe_eal_init (struct rte_eth_dev *dev) { -struct sub_device *sdev; -uint8_t i;int ret; ret =fs_bus_init (dev);if (ret)return ret; -/* -* We only update TX_SUBDEV if we are not started. -* If a sub_device is emitting, we will switch the TX_SUBDEV to the -* preferred port only upon starting it, so that the switch is smoother. -*/ -if (PREFERRED_SUBDEV (dev)->state >=DEV_PROBED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev) && - (TX_SUBDEV (dev) ==NULL || - (TX_SUBDEV (dev) &&TX_SUBDEV (dev)->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 <DEV_PROBED ) || -TX_SUBDEV (dev) ==NULL ) { -/* Using first probed device */ - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_PROBED) { -DEBUG ("Switching tx_dev to sub_device %d" , - i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_PROBED ) +PRIV (dev)->state =DEV_PROBED ; +fs_switch_dev (dev);return 0 ; }
@@ -150,5 +127,6 @@ failsafe_eal_uninit(struct rte_eth_dev *dev) ret =fs_bus_uninit (dev);if (ret)return ret; +PRIV (dev)->state =DEV_PROBED -1 ;return 0 ; }
drivers/net/failsafe/failsafe_ether.c new file +228 -0
228 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +10 -15
@@ -89,6 +89,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } sdev->state =DEV_ACTIVE ; } +if (PRIV (dev)->state <DEV_ACTIVE ) +PRIV (dev)->state =DEV_ACTIVE ;return 0 ; }
@@ -108,21 +110,9 @@ fs_dev_start(struct rte_eth_dev *dev)return ret; sdev->state =DEV_STARTED ; } -if (PREFERRED_SUBDEV (dev)->state ==DEV_STARTED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev)) { -DEBUG ("Switching tx_dev to preferred sub_device" ); -PRIV (dev)->subs_tx =0 ; - } - }else { -if ((TX_SUBDEV (dev) &&TX_SUBDEV (dev)->state <DEV_STARTED ) || -TX_SUBDEV (dev) ==NULL ) { - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) { -DEBUG ("Switching tx_dev to sub_device %d" , i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_STARTED ) +PRIV (dev)->state =DEV_STARTED ; +fs_switch_dev (dev);return 0 ; }
@@ -132,6 +122,7 @@ fs_dev_stop(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +PRIV (dev)->state =DEV_STARTED -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) {rte_eth_dev_stop (PORT_ID (sdev)); sdev->state =DEV_STARTED -1 ;
@@ -183,6 +174,10 @@ fs_dev_close(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +failsafe_hotplug_alarm_cancel (dev); +if (PRIV (dev)->state ==DEV_STARTED ) + dev->dev_ops->dev_stop (dev); +PRIV (dev)->state =DEV_ACTIVE -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) {DEBUG ("Closing sub_device %d" , i);rte_eth_dev_close (PORT_ID (sdev));
drivers/net/failsafe/failsafe_private.h +58 -2
92 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v6 15/23 net/failsafe: add fail-safe PMD
In reply to Gaetan RivetIntroduce the fail-safe poll mode driver initialization and enable its build infrastructure.
This PMD allows for applications to benefit from true hot-plugging support without having to implement it.
It intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back. It also allows defining a contingency to the removal of a device, by designating a fail-over device that will take on transmitting operations if the preferred device is removed.
Applications only see a fail-safe instance, without caring for underlying activity ensuring their continued operations.
--- MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 133 +++++ doc/guides/nics/features/failsafe.ini | 24 + doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 76 +++ drivers/net/failsafe/failsafe.c | 231 ++++++++ drivers/net/failsafe/failsafe_args.c | 331 +++++++++++ drivers/net/failsafe/failsafe_eal.c | 154 +++++ drivers/net/failsafe/failsafe_ops.c | 663 ++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 227 ++++++++ drivers/net/failsafe/failsafe_rxtx.c | 107 ++++ drivers/net/failsafe/rte_pmd_failsafe_version.map | 4 + mk/rte.app.mk | 1 + 15 files changed, 1965 insertions(+) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c create mode 100644 drivers/net/failsafe/rte_pmd_failsafe_version.map
MAINTAINERS +5 -0
@@ -336,6 +336,11 @@ F: drivers/net/enic/ F: doc/guides/nics/enic.rst F: doc/guides/nics/features/enic.ini +Fail-safe PMD +M: Gaetan Rivet <[email protected]> +F: drivers/net/failsafe/ +F: doc/guides/nics/fail_safe.rst + Intel e1000 M: Wenzhuo Lu <[email protected]> F: drivers/net/e1000/
config/common_base +6 -0
@@ -420,6 +420,12 @@ CONFIG_RTE_LIBRTE_PMD_XENVIRT=n CONFIG_RTE_LIBRTE_PMD_NULL=y # +# Compile fail-safe PMD +# +CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y +CONFIG_RTE_LIBRTE_PMD_FAILSAFE_DEBUG=n + +# # Do prefetch of packet data within PMD driver receive function # CONFIG_RTE_PMD_PACKET_PREFETCH=y
doc/guides/nics/fail_safe.rst new file +133 -0
133 lines not on this page · raw message
doc/guides/nics/features/failsafe.ini new file +24 -0
@@ -0,0 +1,24 @@ +; +; Supported features of the 'fail-safe' poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Link status = Y +Queue start/stop = Y +MTU update = Y +Jumbo frame = Y +Promiscuous mode = Y +Allmulticast mode = Y +Unicast MAC filter = Y +Multicast MAC filter = Y +VLAN filter = Y +Packet type parsing = Y +Basic stats = Y +Stats per queue = Y +ARMv7 = Y +ARMv8 = Y +Power8 = Y +x86-32 = Y +x86-64 = Y +Usage doc = Y
doc/guides/nics/index.rst +1 -0
@@ -64,6 +64,7 @@ Network Interface Controller Drivers vhost vmxnet3 pcap_ring + fail_safe **Figures**
drivers/net/Makefile +2 -0
@@ -59,6 +59,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena DEPDIRS-ena = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic DEPDIRS-enic = $(core-libs) librte_hash +DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe +DEPDIRS-failsafe = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k DEPDIRS-fm10k = $(core-libs) librte_hash DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
drivers/net/failsafe/Makefile new file +76 -0
76 lines not on this page · raw message
drivers/net/failsafe/failsafe.c new file +231 -0
231 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c new file +331 -0
331 lines not on this page · raw message
drivers/net/failsafe/failsafe_eal.c new file +154 -0
154 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c new file +663 -0
663 lines not on this page · raw message
drivers/net/failsafe/failsafe_private.h new file +227 -0
227 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c new file +107 -0
107 lines not on this page · raw message
drivers/net/failsafe/rte_pmd_failsafe_version.map new file +4 -0
@@ -0,0 +1,4 @@ +DPDK_17.08 { + + local: *; +};
mk/rte.app.mk +1 -0
@@ -120,6 +120,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += -lrte_pmd_fm10k +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += -lrte_pmd_failsafe _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
Signature · 1 line
2.1.4
PATCH v6 16/22 net/failsafe: add flexible device definition
In reply to Gaetan RivetAdd the "exec" device type.
The parameters given to this type of device will be executed in a shell. The output of this command is then used as a definition for a device.
That command can be re-interpreted if the related device is not plugged-in. It allows for a device definition to react to system changes (e.g. changing PCI bus for a given device).
--- doc/guides/nics/fail_safe.rst | 20 +++++++ drivers/net/failsafe/failsafe_args.c | 99 +++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ether.c | 7 +++ drivers/net/failsafe/failsafe_private.h | 4 ++ 4 files changed, 130 insertions(+)
doc/guides/nics/fail_safe.rst +20 -0
@@ -91,6 +91,19 @@ Fail-safe command line parameters additional sub-device parameters if need be. They will be passed on to the sub-device. +- **exec(<shell command>)** parameter + + This parameter allows the user to provide a command to the fail-safe PMD to + execute and define a sub-device. + It is done within a regular shell context. + The first line of its output is read by the fail-safe PMD and otherwise + interpreted as if passed by the regular **dev** parameter. + Any other line is discarded. + If the command fail or output an incorrect string, the sub-device is not + initialized. + All commas within the ``shell command`` are replaced by spaces before + executing the command. This helps using scripts to specify devices. + - **mac** parameter [MAC address] This parameter allows the user to set a default MAC address to the fail-safe
@@ -126,6 +139,13 @@ This section shows some example of using **testpmd** with a fail-safe PMD. --vdev='net_failsafe0,mac=de:ad:be:ef:01:02,dev(84:00.0),dev(net_ring0,nodeaction=r1:0:CREATE)' -- \ -i +#. Start testpmd using a flexible device definition + + .. code-block:: console + + $RTE_TARGET/build/app/testpmd -c 0xff -n 4 --no-pci \ + --vdev='net_failsafe0,exec(echo 84:00.0)' -- -i + Using the Fail-safe PMD from an application -------------------------------------------
drivers/net/failsafe/failsafe_args.c +99 -0
126 lines not on this page · raw message
drivers/net/failsafe/failsafe_ether.c +7 -0
@@ -188,6 +188,13 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)int ret;uint8_t i; +if (PRIV (dev)->state <DEV_PARSED ) +return 0 ; + + ret =failsafe_args_parse_subs (dev); +if (ret) +return ret; +if (PRIV (dev)->state <DEV_PROBED )return 0 ; ret =failsafe_eal_init (dev);
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -44,6 +44,7 @@#define PMD_FAILSAFE_PLUG_IN_POLL_KVARG "hotplug_poll"#define PMD_FAILSAFE_PARAM_STRING \ "dev(<ifc>)," \ + "exec(<shell command>)," \ "mac=mac_addr," \ "hotplug_poll=u64" \ ""
@@ -87,6 +88,8 @@ struct sub_device {struct rte_eth_dev *edev;/* Device state machine */ enum dev_state state; +/* Some device are defined as a command line */ +char *cmdline; };struct fs_priv {
@@ -135,6 +138,7 @@ uint16_t failsafe_tx_burst(void *txq,int failsafe_args_parse (struct rte_eth_dev *dev,const char *params);void failsafe_args_free (struct rte_eth_dev *dev);int failsafe_args_count_subdevice (struct rte_eth_dev *dev,const char *params); +int failsafe_args_parse_subs (struct rte_eth_dev *dev);/* EAL */
Signature · 1 line
2.1.4
PATCH v6 16/23 net/failsafe: add plug-in support
In reply to Gaetan RivetPeriodically check for the existence of a device.
If a device has not been initialized and exists on the system, then it is probed and configured.
The configuration process strives to synchronize the states between the plugged-in sub-device and the fail-safe device.
--- doc/guides/nics/fail_safe.rst | 19 +++ drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 71 ++++++++++ drivers/net/failsafe/failsafe_args.c | 32 +++++ drivers/net/failsafe/failsafe_eal.c | 30 +---- drivers/net/failsafe/failsafe_ether.c | 228 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 25 ++-- drivers/net/failsafe/failsafe_private.h | 60 ++++++++- 8 files changed, 423 insertions(+), 43 deletions(-) create mode 100644 drivers/net/failsafe/failsafe_ether.c
doc/guides/nics/fail_safe.rst +19 -0
@@ -102,6 +102,11 @@ Fail-safe command line parameters address is generated, that will be subsequently applied to all sub-device once they are probed. +- **hotplug_poll** parameter [UINT64] (default **2000**) + + This parameter allows the user to configure the amount of time in milliseconds + between two slave upkeep round. + Usage example ~~~~~~~~~~~~~
@@ -131,3 +136,17 @@ Care must be taken, however, to respect the **ether** API concerning device access, and in particular, using the ``RTE_ETH_FOREACH_DEV`` macro to iterate over ethernet devices, instead of directly accessing them or by writing one's own device iterator. + +Plug-in feature +--------------- + +A sub-device can be defined without existing on the system when the fail-safe +PMD is initialized. Upon probing this device, the fail-safe PMD will detect its +absence and postpone its use. It will then register for a periodic check on any +missing sub-device. + +During this time, the fail-safe PMD can be used normally, configured and told to +emit and receive packets. It will store any applied configuration, and try to +apply it upon the probing of its missing sub-device. After this configuration +pass, the new sub-device will be synchronized with other sub-devices, i.e. be +started if the fail-safe PMD has been started by the user before.
drivers/net/failsafe/Makefile +1 -0
@@ -44,6 +44,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_args.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c # No exported include files
drivers/net/failsafe/failsafe.c +71 -0
83 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c +32 -0
@@ -45,9 +45,11 @@typedef int (parse_cb )(struct rte_eth_dev *dev,const char *params,uint8_t head); +uint64_t hotplug_poll;int mac_from_arg;const char *pmd_failsafe_init_parameters[] = { +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ,PMD_FAILSAFE_MAC_KVARG ,NULL , };
@@ -221,6 +223,24 @@ fs_remove_sub_devices_definition(char params[DEVARGS_MAXLEN]) }static int +fs_get_u64_arg(const char *key __rte_unused, +const char *value,void *out) +{ +uint64_t *u64 = out; +char *endptr =NULL ; + +if ((value ==NULL ) || (out ==NULL )) +return -EINVAL ; + errno =0 ; + *u64 =strtoull (value, &endptr,0 ); +if (errno !=0 ) +return -errno; +if (endptr == value) +return -1 ; +return 0 ; +} + +static int fs_get_mac_addr_arg(const char *key __rte_unused,const char *value,void *out) {
@@ -252,6 +272,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) ret =0 ; priv->subs_tx =FAILSAFE_MAX_ETHPORTS ;/* default parameters */ + hotplug_poll =FAILSAFE_HOTPLUG_DEFAULT_TIMEOUT_MS ; mac_from_arg =0 ; n =snprintf (mut_params,sizeof (mut_params),"%s" , params);if (n >=sizeof (mut_params)) {
@@ -274,6 +295,16 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) PMD_FAILSAFE_PARAM_STRING);return -1 ; } +/* PLUG_IN event poll timer */ + arg_count =rte_kvargs_count (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG ); +if (arg_count ==1 ) { + ret =rte_kvargs_process (kvlist, +PMD_FAILSAFE_PLUG_IN_POLL_KVARG , + &fs_get_u64_arg, &hotplug_poll); +if (ret <0 ) + goto free_kvlist; + }/* MAC addr */ arg_count =rte_kvargs_count (kvlist,PMD_FAILSAFE_MAC_KVARG );
@@ -287,6 +318,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) mac_from_arg =1 ; } } +PRIV (dev)->state =DEV_PARSED ; free_kvlist:rte_kvargs_free (kvlist);return ret;
drivers/net/failsafe/failsafe_eal.c +4 -26
@@ -88,37 +88,14 @@ fs_bus_init(struct rte_eth_dev *dev)int failsafe_eal_init (struct rte_eth_dev *dev) { -struct sub_device *sdev; -uint8_t i;int ret; ret =fs_bus_init (dev);if (ret)return ret; -/* -* We only update TX_SUBDEV if we are not started. -* If a sub_device is emitting, we will switch the TX_SUBDEV to the -* preferred port only upon starting it, so that the switch is smoother. -*/ -if (PREFERRED_SUBDEV (dev)->state >=DEV_PROBED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev) && - (TX_SUBDEV (dev) ==NULL || - (TX_SUBDEV (dev) &&TX_SUBDEV (dev)->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 <DEV_PROBED ) || -TX_SUBDEV (dev) ==NULL ) { -/* Using first probed device */ - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_PROBED) { -DEBUG ("Switching tx_dev to sub_device %d" , - i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_PROBED ) +PRIV (dev)->state =DEV_PROBED ; +fs_switch_dev (dev);return 0 ; }
@@ -150,5 +127,6 @@ failsafe_eal_uninit(struct rte_eth_dev *dev) ret =fs_bus_uninit (dev);if (ret)return ret; +PRIV (dev)->state =DEV_PROBED -1 ;return 0 ; }
drivers/net/failsafe/failsafe_ether.c new file +228 -0
228 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +10 -15
@@ -89,6 +89,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } sdev->state =DEV_ACTIVE ; } +if (PRIV (dev)->state <DEV_ACTIVE ) +PRIV (dev)->state =DEV_ACTIVE ;return 0 ; }
@@ -108,21 +110,9 @@ fs_dev_start(struct rte_eth_dev *dev)return ret; sdev->state =DEV_STARTED ; } -if (PREFERRED_SUBDEV (dev)->state ==DEV_STARTED ) { -if (TX_SUBDEV (dev) !=PREFERRED_SUBDEV (dev)) { -DEBUG ("Switching tx_dev to preferred sub_device" ); -PRIV (dev)->subs_tx =0 ; - } - }else { -if ((TX_SUBDEV (dev) &&TX_SUBDEV (dev)->state <DEV_STARTED ) || -TX_SUBDEV (dev) ==NULL ) { - FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) { -DEBUG ("Switching tx_dev to sub_device %d" , i); -PRIV (dev)->subs_tx = i; -break ; - } - } - } +if (PRIV (dev)->state <DEV_STARTED ) +PRIV (dev)->state =DEV_STARTED ; +fs_switch_dev (dev);return 0 ; }
@@ -132,6 +122,7 @@ fs_dev_stop(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +PRIV (dev)->state =DEV_STARTED -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_STARTED) {rte_eth_dev_stop (PORT_ID (sdev)); sdev->state =DEV_STARTED -1 ;
@@ -183,6 +174,10 @@ fs_dev_close(struct rte_eth_dev *dev)struct sub_device *sdev;uint8_t i; +failsafe_hotplug_alarm_cancel (dev); +if (PRIV (dev)->state ==DEV_STARTED ) + dev->dev_ops->dev_stop (dev); +PRIV (dev)->state =DEV_ACTIVE -1 ; FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) {DEBUG ("Closing sub_device %d" , i);rte_eth_dev_close (PORT_ID (sdev));
drivers/net/failsafe/failsafe_private.h +58 -2
92 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v6 17/23 net/failsafe: add flexible device definition
In reply to Gaetan RivetAdd the "exec" device type.
The parameters given to this type of device will be executed in a shell. The output of this command is then used as a definition for a device.
That command can be re-interpreted if the related device is not plugged-in. It allows for a device definition to react to system changes (e.g. changing PCI bus for a given device).
--- doc/guides/nics/fail_safe.rst | 20 +++++++ drivers/net/failsafe/failsafe_args.c | 99 +++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ether.c | 7 +++ drivers/net/failsafe/failsafe_private.h | 4 ++ 4 files changed, 130 insertions(+)
doc/guides/nics/fail_safe.rst +20 -0
@@ -91,6 +91,19 @@ Fail-safe command line parameters additional sub-device parameters if need be. They will be passed on to the sub-device. +- **exec(<shell command>)** parameter + + This parameter allows the user to provide a command to the fail-safe PMD to + execute and define a sub-device. + It is done within a regular shell context. + The first line of its output is read by the fail-safe PMD and otherwise + interpreted as if passed by the regular **dev** parameter. + Any other line is discarded. + If the command fail or output an incorrect string, the sub-device is not + initialized. + All commas within the ``shell command`` are replaced by spaces before + executing the command. This helps using scripts to specify devices. + - **mac** parameter [MAC address] This parameter allows the user to set a default MAC address to the fail-safe
@@ -126,6 +139,13 @@ This section shows some example of using **testpmd** with a fail-safe PMD. --vdev='net_failsafe0,mac=de:ad:be:ef:01:02,dev(84:00.0),dev(net_ring0,nodeaction=r1:0:CREATE)' -- \ -i +#. Start testpmd using a flexible device definition + + .. code-block:: console + + $RTE_TARGET/build/app/testpmd -c 0xff -n 4 --no-pci \ + --vdev='net_failsafe0,exec(echo 84:00.0)' -- -i + Using the Fail-safe PMD from an application -------------------------------------------
drivers/net/failsafe/failsafe_args.c +99 -0
126 lines not on this page · raw message
drivers/net/failsafe/failsafe_ether.c +7 -0
@@ -188,6 +188,13 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)int ret;uint8_t i; +if (PRIV (dev)->state <DEV_PARSED ) +return 0 ; + + ret =failsafe_args_parse_subs (dev); +if (ret) +return ret; +if (PRIV (dev)->state <DEV_PROBED )return 0 ; ret =failsafe_eal_init (dev);
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -44,6 +44,7 @@#define PMD_FAILSAFE_PLUG_IN_POLL_KVARG "hotplug_poll"#define PMD_FAILSAFE_PARAM_STRING \ "dev(<ifc>)," \ + "exec(<shell command>)," \ "mac=mac_addr," \ "hotplug_poll=u64" \ ""
@@ -87,6 +88,8 @@ struct sub_device {struct rte_eth_dev *edev;/* Device state machine */ enum dev_state state; +/* Some device are defined as a command line */ +char *cmdline; };struct fs_priv {
@@ -135,6 +138,7 @@ uint16_t failsafe_tx_burst(void *txq,int failsafe_args_parse (struct rte_eth_dev *dev,const char *params);void failsafe_args_free (struct rte_eth_dev *dev);int failsafe_args_count_subdevice (struct rte_eth_dev *dev,const char *params); +int failsafe_args_parse_subs (struct rte_eth_dev *dev);/* EAL */
Signature · 1 line
2.1.4
PATCH v6 17/22 net/failsafe: support flow API
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_eal.c | 1 + drivers/net/failsafe/failsafe_ether.c | 70 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 216 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 29 +++++ drivers/net/failsafe/failsafe_private.h | 18 +++ 8 files changed, 337 insertions(+) create mode 100644 drivers/net/failsafe/failsafe_flow.c
doc/guides/nics/features/failsafe.ini +1 -0
@@ -13,6 +13,7 @@ Allmulticast mode = Y Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y +Flow API = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/Makefile +1 -0
@@ -45,6 +45,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_flow.c # No exported include files
drivers/net/failsafe/failsafe.c +1 -0
@@ -177,6 +177,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) dev->data->mac_addrs = &PRIV (dev)->mac_addrs[0 ]; dev->data->dev_link = eth_link;PRIV (dev)->nb_mac_addr =1 ; +TAILQ_INIT (&PRIV (dev)->flow_list); dev->rx_pkt_burst = (eth_rx_burst_t)&failsafe_rx_burst; dev->tx_pkt_burst = (eth_tx_burst_t)&failsafe_tx_burst;if (params ==NULL ) {
drivers/net/failsafe/failsafe_eal.c +1 -0
@@ -78,6 +78,7 @@ fs_bus_init(struct rte_eth_dev *dev)ERROR ("sub_device %d init went wrong" , i);return -ENODEV ; } +SUB_ID (sdev) = i; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
drivers/net/failsafe/failsafe_ether.c +70 -0
90 lines not on this page · raw message
drivers/net/failsafe/failsafe_flow.c new file +216 -0
216 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +29 -0
@@ -35,6 +35,7 @@#include <stdint.h> #include <rte_ethdev.h> #include <rte_malloc.h> +#include <rte_flow.h> #include "failsafe_private.h"
@@ -628,6 +629,33 @@ fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)rte_eth_dev_default_mac_addr_set (PORT_ID (sdev), mac_addr); } +static int +fs_filter_ctrl (struct rte_eth_dev *dev, +enum rte_filter_type type, +enum rte_filter_op op, +void *arg) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + +if (type ==RTE_ETH_FILTER_GENERIC && + op ==RTE_ETH_FILTER_GET ) { + *(const void **)arg = &fs_flow_ops; +return 0 ; + } + FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) { +DEBUG ("Calling rte_eth_dev_filter_ctrl on sub_device %d" , i); + ret =rte_eth_dev_filter_ctrl (PORT_ID (sdev), type, op, arg); +if (ret) { +ERROR ("Operation rte_eth_dev_filter_ctrl failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + } +return 0 ; +} +const struct eth_dev_ops failsafe_ops = { .dev_configure = fs_dev_configure, .dev_start = fs_dev_start,
@@ -655,4 +683,5 @@ const struct eth_dev_ops failsafe_ops = { .mac_addr_remove = fs_mac_addr_remove, .mac_addr_add = fs_mac_addr_add, .mac_addr_set = fs_mac_addr_set, + .filter_ctrl = fs_filter_ctrl, };
drivers/net/failsafe/failsafe_private.h +18 -0
@@ -34,6 +34,8 @@#ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_#define _RTE_ETH_FAILSAFE_PRIVATE_H_ +#include <sys/queue.h> +#include <rte_dev.h> #include <rte_ethdev.h> #include <rte_devargs.h>
@@ -72,6 +74,14 @@ struct txq {struct rte_eth_txq_info info; }; +struct rte_flow { +TAILQ_ENTRY (rte_flow) next; +/* sub_flows */ +struct rte_flow *flows[FAILSAFE_MAX_ETHPORTS ]; +/* flow description for synchronization */ +struct rte_flow_desc *fd; +}; +enum dev_state {DEV_UNDEFINED =0 ,DEV_PARSED ,
@@ -86,6 +96,7 @@ struct sub_device {struct rte_bus *bus;struct rte_device *dev;struct rte_eth_dev *edev; +uint8_t sid;/* Device state machine */ enum dev_state state;/* Some device are defined as a command line */
@@ -104,6 +115,8 @@ struct fs_priv {uint8_t subs_tail;/* first invalid */ uint8_t subs_tx;/* current emitting device */ uint8_t current_probed; +/* flow mapping */ + TAILQ_HEAD(sub_flows, rte_flow) flow_list;/* current number of mac_addr slots allocated. */ uint32_t nb_mac_addr;struct ether_addr mac_addrs[FAILSAFE_MAX_ETHADDR ];
@@ -153,6 +166,7 @@ int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev);extern const char pmd_failsafe_driver_name[];extern const struct eth_dev_ops failsafe_ops; +extern const struct rte_flow_ops fs_flow_ops;extern uint64_t hotplug_poll;extern int mac_from_arg;
@@ -170,6 +184,10 @@ extern int mac_from_arg;#define PORT_ID (sdev) \ (ETH(sdev)->data->port_id) +/* sdev: (struct sub_device *) */ +#define SUB_ID (sdev) \ + ((sdev)->sid) +/** * Stateful iterator construct over fail-safe sub-devices: * s: (struct sub_device *), iterator
Signature · 1 line
2.1.4
PATCH v6 18/22 net/failsafe: support offload capabilities
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 6 ++ drivers/net/failsafe/failsafe_ops.c | 131 +++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-)
doc/guides/nics/features/failsafe.ini +6 -0
@@ -14,6 +14,12 @@ Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y Flow API = Y +VLAN offload = Y +QinQ offload = Y +L3 checksum offload = Y +L4 checksum offload = Y +Inner L3 checksum = Y +Inner L4 checksum = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/failsafe_ops.c +129 -2
151 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v6 18/23 net/failsafe: support flow API
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/Makefile | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_eal.c | 1 + drivers/net/failsafe/failsafe_ether.c | 70 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 216 ++++++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 29 +++++ drivers/net/failsafe/failsafe_private.h | 18 +++ 8 files changed, 337 insertions(+) create mode 100644 drivers/net/failsafe/failsafe_flow.c
doc/guides/nics/features/failsafe.ini +1 -0
@@ -13,6 +13,7 @@ Allmulticast mode = Y Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y +Flow API = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/Makefile +1 -0
@@ -45,6 +45,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_eal.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ops.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_flow.c # No exported include files
drivers/net/failsafe/failsafe.c +1 -0
@@ -177,6 +177,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) dev->data->mac_addrs = &PRIV (dev)->mac_addrs[0 ]; dev->data->dev_link = eth_link;PRIV (dev)->nb_mac_addr =1 ; +TAILQ_INIT (&PRIV (dev)->flow_list); dev->rx_pkt_burst = (eth_rx_burst_t)&failsafe_rx_burst; dev->tx_pkt_burst = (eth_tx_burst_t)&failsafe_tx_burst;if (params ==NULL ) {
drivers/net/failsafe/failsafe_eal.c +1 -0
@@ -78,6 +78,7 @@ fs_bus_init(struct rte_eth_dev *dev)ERROR ("sub_device %d init went wrong" , i);return -ENODEV ; } +SUB_ID (sdev) = i; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
drivers/net/failsafe/failsafe_ether.c +70 -0
90 lines not on this page · raw message
drivers/net/failsafe/failsafe_flow.c new file +216 -0
216 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +29 -0
@@ -35,6 +35,7 @@#include <stdint.h> #include <rte_ethdev.h> #include <rte_malloc.h> +#include <rte_flow.h> #include "failsafe_private.h"
@@ -628,6 +629,33 @@ fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)rte_eth_dev_default_mac_addr_set (PORT_ID (sdev), mac_addr); } +static int +fs_filter_ctrl (struct rte_eth_dev *dev, +enum rte_filter_type type, +enum rte_filter_op op, +void *arg) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + +if (type ==RTE_ETH_FILTER_GENERIC && + op ==RTE_ETH_FILTER_GET ) { + *(const void **)arg = &fs_flow_ops; +return 0 ; + } + FOREACH_SUBDEV_ST(sdev, i, dev, DEV_ACTIVE) { +DEBUG ("Calling rte_eth_dev_filter_ctrl on sub_device %d" , i); + ret =rte_eth_dev_filter_ctrl (PORT_ID (sdev), type, op, arg); +if (ret) { +ERROR ("Operation rte_eth_dev_filter_ctrl failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + } +return 0 ; +} +const struct eth_dev_ops failsafe_ops = { .dev_configure = fs_dev_configure, .dev_start = fs_dev_start,
@@ -655,4 +683,5 @@ const struct eth_dev_ops failsafe_ops = { .mac_addr_remove = fs_mac_addr_remove, .mac_addr_add = fs_mac_addr_add, .mac_addr_set = fs_mac_addr_set, + .filter_ctrl = fs_filter_ctrl, };
drivers/net/failsafe/failsafe_private.h +18 -0
@@ -34,6 +34,8 @@#ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_#define _RTE_ETH_FAILSAFE_PRIVATE_H_ +#include <sys/queue.h> +#include <rte_dev.h> #include <rte_ethdev.h> #include <rte_devargs.h>
@@ -72,6 +74,14 @@ struct txq {struct rte_eth_txq_info info; }; +struct rte_flow { +TAILQ_ENTRY (rte_flow) next; +/* sub_flows */ +struct rte_flow *flows[FAILSAFE_MAX_ETHPORTS ]; +/* flow description for synchronization */ +struct rte_flow_desc *fd; +}; +enum dev_state {DEV_UNDEFINED =0 ,DEV_PARSED ,
@@ -86,6 +96,7 @@ struct sub_device {struct rte_bus *bus;struct rte_device *dev;struct rte_eth_dev *edev; +uint8_t sid;/* Device state machine */ enum dev_state state;/* Some device are defined as a command line */
@@ -104,6 +115,8 @@ struct fs_priv {uint8_t subs_tail;/* first invalid */ uint8_t subs_tx;/* current emitting device */ uint8_t current_probed; +/* flow mapping */ + TAILQ_HEAD(sub_flows, rte_flow) flow_list;/* current number of mac_addr slots allocated. */ uint32_t nb_mac_addr;struct ether_addr mac_addrs[FAILSAFE_MAX_ETHADDR ];
@@ -153,6 +166,7 @@ int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev);extern const char pmd_failsafe_driver_name[];extern const struct eth_dev_ops failsafe_ops; +extern const struct rte_flow_ops fs_flow_ops;extern uint64_t hotplug_poll;extern int mac_from_arg;
@@ -170,6 +184,10 @@ extern int mac_from_arg;#define PORT_ID (sdev) \ (ETH(sdev)->data->port_id) +/* sdev: (struct sub_device *) */ +#define SUB_ID (sdev) \ + ((sdev)->sid) +/** * Stateful iterator construct over fail-safe sub-devices: * s: (struct sub_device *), iterator
Signature · 1 line
2.1.4
PATCH v6 19/22 net/failsafe: add fast burst functions
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_private.h | 8 +++ drivers/net/failsafe/failsafe_rxtx.c | 124 ++++++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 20 deletions(-)
drivers/net/failsafe/failsafe_private.h +8 -0
@@ -141,11 +141,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);
@@ -299,6 +306,7 @@ fs_switch_dev(struct rte_eth_dev *dev) }else {return ; } +set_burst_fn (dev,0 );rte_wmb (); }
drivers/net/failsafe/failsafe_rxtx.c +104 -20
154 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v6 19/23 net/failsafe: support offload capabilities
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 6 ++ drivers/net/failsafe/failsafe_ops.c | 131 +++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-)
doc/guides/nics/features/failsafe.ini +6 -0
@@ -14,6 +14,12 @@ Unicast MAC filter = Y Multicast MAC filter = Y VLAN filter = Y Flow API = Y +VLAN offload = Y +QinQ offload = Y +L3 checksum offload = Y +L4 checksum offload = Y +Inner L3 checksum = Y +Inner L4 checksum = Y Packet type parsing = Y Basic stats = Y Stats per queue = Y
drivers/net/failsafe/failsafe_ops.c +129 -2
151 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v6 20/23 net/failsafe: add fast burst functions
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_private.h | 8 +++ drivers/net/failsafe/failsafe_rxtx.c | 124 ++++++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 20 deletions(-)
drivers/net/failsafe/failsafe_private.h +8 -0
@@ -141,11 +141,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);
@@ -299,6 +306,7 @@ fs_switch_dev(struct rte_eth_dev *dev) }else {return ; } +set_burst_fn (dev,0 );rte_wmb (); }
drivers/net/failsafe/failsafe_rxtx.c +104 -20
154 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH v6 20/22 net/failsafe: support device removal
In reply to Gaetan RivetListen to INTR_RMV events issued by slaves.
Add atomic flags on slave queues to detect use of slave bursts function. If a removal is detected, set the recollection flag on this slave.
During a slave upkeep round, if its recollection flag is set and its burst functions are not in use by any thread, remove that slave.
--- doc/guides/nics/fail_safe.rst | 14 +++++ drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_args.c | 13 +++++ drivers/net/failsafe/failsafe_eal.c | 3 +- drivers/net/failsafe/failsafe_ether.c | 96 ++++++++++++++++++++++++++++++--- drivers/net/failsafe/failsafe_ops.c | 38 +++++++++++-- drivers/net/failsafe/failsafe_private.h | 72 ++++++++++++++++++++++--- drivers/net/failsafe/failsafe_rxtx.c | 17 +++++- 8 files changed, 234 insertions(+), 20 deletions(-)
doc/guides/nics/fail_safe.rst +14 -0
@@ -51,6 +51,12 @@ The Fail-safe PMD only supports a limited set of features. If you plan to use a device underneath the Fail-safe PMD with a specific feature, this feature must be supported by the Fail-safe PMD to avoid throwing any error. +A notable exception is the device removal feature. The fail-safe PMD being a +virtual device, it cannot currently be removed in the sense of a specific bus +hotplug, like for PCI for example. It will however enable this feature for its +sub-device automatically, detecting those that are capable and register the +relevant callback for such event. + Check the feature matrix for the complete set of supported features. Compilation options
@@ -170,3 +176,11 @@ emit and receive packets. It will store any applied configuration, and try to apply it upon the probing of its missing sub-device. After this configuration pass, the new sub-device will be synchronized with other sub-devices, i.e. be started if the fail-safe PMD has been started by the user before. + +Plug-out feature +---------------- + +A sub-device supporting the device removal event can be removed from its bus at +any time. The fail-safe PMD will register a callback for such event and react +accordingly. It will try to safely stop, close and uninit the sub-device having +emitted this event, allowing it to free its eventual resources.
drivers/net/failsafe/failsafe.c +1 -0
@@ -132,6 +132,7 @@ fs_hotplug_alarm(void *arg)if (!PRIV (dev)->pending_alarm)return ;PRIV (dev)->pending_alarm =0 ; +failsafe_dev_remove (dev); FOREACH_SUBDEV(sdev, i, dev)if (sdev->state !=PRIV (dev)->state)break ;
drivers/net/failsafe/failsafe_args.c +13 -0
@@ -443,6 +443,17 @@ failsafe_args_count_subdevice(struct rte_eth_dev *dev, dev, params); } +static int +fs_parse_sub_device (struct sub_device *sdev) +{ +struct rte_devargs *da; +char devstr[DEVARGS_MAXLEN ] ="" ; + + da = &sdev->devargs; +snprintf (devstr,sizeof (devstr),"%s,%s" , da->name, da->args); +return fs_parse_device (sdev, devstr); +} +int failsafe_args_parse_subs (struct rte_eth_dev *dev) {
@@ -455,6 +466,8 @@ failsafe_args_parse_subs(struct rte_eth_dev *dev)continue ;if (sdev->cmdline) ret =fs_execute_cmd (sdev, sdev->cmdline); +else + ret =fs_parse_sub_device (sdev);if (ret ==0 ) sdev->state =DEV_PARSED ; }
drivers/net/failsafe/failsafe_eal.c +2 -1
@@ -79,6 +79,7 @@ fs_bus_init(struct rte_eth_dev *dev)return -ENODEV ; }SUB_ID (sdev) = i; + sdev->fs_dev = dev; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
@@ -96,7 +97,7 @@ failsafe_eal_init(struct rte_eth_dev *dev)return ret;if (PRIV (dev)->state <DEV_PROBED )PRIV (dev)->state =DEV_PROBED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
drivers/net/failsafe/failsafe_ether.c +90 -6
130 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +35 -3
@@ -33,6 +33,8 @@#include <assert.h> #include <stdint.h> + +#include <rte_atomic.h> #include <rte_ethdev.h> #include <rte_malloc.h> #include <rte_flow.h>
@@ -204,9 +206,21 @@ fs_dev_configure(struct rte_eth_dev *dev) } } FOREACH_SUBDEV(sdev, i, dev) { +int rmv_interrupt =0 ; +if (sdev->state !=DEV_PROBED )continue ; + + rmv_interrupt =ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_RMV ; +if (rmv_interrupt) { +DEBUG ("Enabling RMV interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.rmv =1 ; + }else { +DEBUG ("sub_device %d does not support RMV event" , i); + }DEBUG ("Configuring sub-device %d" , i); + sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev), dev->data->nb_rx_queues, dev->data->nb_tx_queues,
@@ -215,6 +229,16 @@ fs_dev_configure(struct rte_eth_dev *dev)ERROR ("Could not configure sub_device %d" , i);return ret; } +if (rmv_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_RMV , + failsafe_eth_rmv_event_callback, + sdev); +if (ret) +WARN ("Failed to register RMV callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.rmv =0 ; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
@@ -240,7 +264,7 @@ fs_dev_start(struct rte_eth_dev *dev) }if (PRIV (dev)->state <DEV_STARTED )PRIV (dev)->state =DEV_STARTED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
@@ -351,10 +375,14 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,fs_rx_queue_release (rxq); dev->data->rx_queues[rx_queue_id] =NULL ; } - rxq =rte_zmalloc (NULL ,sizeof (*rxq), + rxq =rte_zmalloc (NULL , +sizeof (*rxq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (rxq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&rxq->refcnt[i]); rxq->qid = rx_queue_id; rxq->socket_id = socket_id; rxq->info.mp = mb_pool;
@@ -414,10 +442,14 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,fs_tx_queue_release (txq); dev->data->tx_queues[tx_queue_id] =NULL ; } - txq =rte_zmalloc ("ethdev TX queue" ,sizeof (*txq), + txq =rte_zmalloc ("ethdev TX queue" , +sizeof (*txq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (txq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&txq->refcnt[i]); txq->qid = tx_queue_id; txq->socket_id = socket_id; txq->info.conf = *tx_conf;
drivers/net/failsafe/failsafe_private.h +64 -8
133 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c +15 -2
@@ -33,6 +33,7 @@#include <assert.h> +#include <rte_atomic.h> #include <rte_mbuf.h> #include <rte_ethdev.h>
@@ -113,8 +114,10 @@ failsafe_rx_burst(void *queue,if (unlikely (fs_rx_unsafe (sdev)))continue ; sub_rxq =ETH (sdev)->data->rx_queues[rxq->qid]; +FS_ATOMIC_P (rxq->refcnt[sdev->sid]); nb_rx =ETH (sdev)->rx_pkt_burst (sub_rxq, rx_pkts, nb_pkts); +FS_ATOMIC_V (rxq->refcnt[sdev->sid]);if (nb_rx) { rxq->last_polled = i;return nb_rx;
@@ -147,8 +150,10 @@ failsafe_rx_burst_fast(void *queue, sdev = &priv->subs[i];assert (!fs_rx_unsafe (sdev)); sub_rxq =ETH (sdev)->data->rx_queues[rxq->qid]; +FS_ATOMIC_P (rxq->refcnt[sdev->sid]); nb_rx =ETH (sdev)->rx_pkt_burst (sub_rxq, rx_pkts, nb_pkts); +FS_ATOMIC_V (rxq->refcnt[sdev->sid]);if (nb_rx) { rxq->last_polled = i;return nb_rx;
@@ -165,13 +170,17 @@ failsafe_tx_burst(void *queue,struct sub_device *sdev;struct txq *txq;void *sub_txq; +uint16_t nb_tx; txq = queue; sdev =TX_SUBDEV (txq->priv->dev);if (unlikely (fs_tx_unsafe (sdev)))return 0 ; sub_txq =ETH (sdev)->data->tx_queues[txq->qid]; -return ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_P (txq->refcnt[sdev->sid]); + nb_tx =ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_V (txq->refcnt[sdev->sid]); +return nb_tx; }uint16_t
@@ -182,10 +191,14 @@ failsafe_tx_burst_fast(void *queue,struct sub_device *sdev;struct txq *txq;void *sub_txq; +uint16_t nb_tx; txq = queue; sdev =TX_SUBDEV (txq->priv->dev);assert (!fs_tx_unsafe (sdev)); sub_txq =ETH (sdev)->data->tx_queues[txq->qid]; -return ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_P (txq->refcnt[sdev->sid]); + nb_tx =ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_V (txq->refcnt[sdev->sid]); +return nb_tx; }
Signature · 1 line
2.1.4
PATCH v6 21/23 net/failsafe: support device removal
In reply to Gaetan RivetListen to INTR_RMV events issued by slaves.
Add atomic flags on slave queues to detect use of slave bursts function. If a removal is detected, set the recollection flag on this slave.
During a slave upkeep round, if its recollection flag is set and its burst functions are not in use by any thread, remove that slave.
--- doc/guides/nics/fail_safe.rst | 14 +++++ drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_args.c | 13 +++++ drivers/net/failsafe/failsafe_eal.c | 3 +- drivers/net/failsafe/failsafe_ether.c | 96 ++++++++++++++++++++++++++++++--- drivers/net/failsafe/failsafe_ops.c | 38 +++++++++++-- drivers/net/failsafe/failsafe_private.h | 72 ++++++++++++++++++++++--- drivers/net/failsafe/failsafe_rxtx.c | 17 +++++- 8 files changed, 234 insertions(+), 20 deletions(-)
doc/guides/nics/fail_safe.rst +14 -0
@@ -51,6 +51,12 @@ The Fail-safe PMD only supports a limited set of features. If you plan to use a device underneath the Fail-safe PMD with a specific feature, this feature must be supported by the Fail-safe PMD to avoid throwing any error. +A notable exception is the device removal feature. The fail-safe PMD being a +virtual device, it cannot currently be removed in the sense of a specific bus +hotplug, like for PCI for example. It will however enable this feature for its +sub-device automatically, detecting those that are capable and register the +relevant callback for such event. + Check the feature matrix for the complete set of supported features. Compilation options
@@ -170,3 +176,11 @@ emit and receive packets. It will store any applied configuration, and try to apply it upon the probing of its missing sub-device. After this configuration pass, the new sub-device will be synchronized with other sub-devices, i.e. be started if the fail-safe PMD has been started by the user before. + +Plug-out feature +---------------- + +A sub-device supporting the device removal event can be removed from its bus at +any time. The fail-safe PMD will register a callback for such event and react +accordingly. It will try to safely stop, close and uninit the sub-device having +emitted this event, allowing it to free its eventual resources.
drivers/net/failsafe/failsafe.c +1 -0
@@ -132,6 +132,7 @@ fs_hotplug_alarm(void *arg)if (!PRIV (dev)->pending_alarm)return ;PRIV (dev)->pending_alarm =0 ; +failsafe_dev_remove (dev); FOREACH_SUBDEV(sdev, i, dev)if (sdev->state !=PRIV (dev)->state)break ;
drivers/net/failsafe/failsafe_args.c +13 -0
@@ -443,6 +443,17 @@ failsafe_args_count_subdevice(struct rte_eth_dev *dev, dev, params); } +static int +fs_parse_sub_device (struct sub_device *sdev) +{ +struct rte_devargs *da; +char devstr[DEVARGS_MAXLEN ] ="" ; + + da = &sdev->devargs; +snprintf (devstr,sizeof (devstr),"%s,%s" , da->name, da->args); +return fs_parse_device (sdev, devstr); +} +int failsafe_args_parse_subs (struct rte_eth_dev *dev) {
@@ -455,6 +466,8 @@ failsafe_args_parse_subs(struct rte_eth_dev *dev)continue ;if (sdev->cmdline) ret =fs_execute_cmd (sdev, sdev->cmdline); +else + ret =fs_parse_sub_device (sdev);if (ret ==0 ) sdev->state =DEV_PARSED ; }
drivers/net/failsafe/failsafe_eal.c +2 -1
@@ -79,6 +79,7 @@ fs_bus_init(struct rte_eth_dev *dev)return -ENODEV ; }SUB_ID (sdev) = i; + sdev->fs_dev = dev; sdev->dev =ETH (sdev)->device;ETH (sdev)->state =RTE_ETH_DEV_DEFERRED ; sdev->state =DEV_PROBED ;
@@ -96,7 +97,7 @@ failsafe_eal_init(struct rte_eth_dev *dev)return ret;if (PRIV (dev)->state <DEV_PROBED )PRIV (dev)->state =DEV_PROBED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
drivers/net/failsafe/failsafe_ether.c +90 -6
130 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c +35 -3
@@ -33,6 +33,8 @@#include <assert.h> #include <stdint.h> + +#include <rte_atomic.h> #include <rte_ethdev.h> #include <rte_malloc.h> #include <rte_flow.h>
@@ -204,9 +206,21 @@ fs_dev_configure(struct rte_eth_dev *dev) } } FOREACH_SUBDEV(sdev, i, dev) { +int rmv_interrupt =0 ; +if (sdev->state !=DEV_PROBED )continue ; + + rmv_interrupt =ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_RMV ; +if (rmv_interrupt) { +DEBUG ("Enabling RMV interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.rmv =1 ; + }else { +DEBUG ("sub_device %d does not support RMV event" , i); + }DEBUG ("Configuring sub-device %d" , i); + sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev), dev->data->nb_rx_queues, dev->data->nb_tx_queues,
@@ -215,6 +229,16 @@ fs_dev_configure(struct rte_eth_dev *dev)ERROR ("Could not configure sub_device %d" , i);return ret; } +if (rmv_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_RMV , + failsafe_eth_rmv_event_callback, + sdev); +if (ret) +WARN ("Failed to register RMV callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.rmv =0 ; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
@@ -240,7 +264,7 @@ fs_dev_start(struct rte_eth_dev *dev) }if (PRIV (dev)->state <DEV_STARTED )PRIV (dev)->state =DEV_STARTED ; -fs_switch_dev (dev); +fs_switch_dev (dev,NULL );return 0 ; }
@@ -351,10 +375,14 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,fs_rx_queue_release (rxq); dev->data->rx_queues[rx_queue_id] =NULL ; } - rxq =rte_zmalloc (NULL ,sizeof (*rxq), + rxq =rte_zmalloc (NULL , +sizeof (*rxq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (rxq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&rxq->refcnt[i]); rxq->qid = rx_queue_id; rxq->socket_id = socket_id; rxq->info.mp = mb_pool;
@@ -414,10 +442,14 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,fs_tx_queue_release (txq); dev->data->tx_queues[tx_queue_id] =NULL ; } - txq =rte_zmalloc ("ethdev TX queue" ,sizeof (*txq), + txq =rte_zmalloc ("ethdev TX queue" , +sizeof (*txq) + +sizeof (rte_atomic64_t) *PRIV (dev)->subs_tail,RTE_CACHE_LINE_SIZE );if (txq ==NULL )return -ENOMEM ; + FOREACH_SUBDEV(sdev, i, dev) +rte_atomic64_init (&txq->refcnt[i]); txq->qid = tx_queue_id; txq->socket_id = socket_id; txq->info.conf = *tx_conf;
drivers/net/failsafe/failsafe_private.h +64 -8
133 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c +15 -2
@@ -33,6 +33,7 @@#include <assert.h> +#include <rte_atomic.h> #include <rte_mbuf.h> #include <rte_ethdev.h>
@@ -113,8 +114,10 @@ failsafe_rx_burst(void *queue,if (unlikely (fs_rx_unsafe (sdev)))continue ; sub_rxq =ETH (sdev)->data->rx_queues[rxq->qid]; +FS_ATOMIC_P (rxq->refcnt[sdev->sid]); nb_rx =ETH (sdev)->rx_pkt_burst (sub_rxq, rx_pkts, nb_pkts); +FS_ATOMIC_V (rxq->refcnt[sdev->sid]);if (nb_rx) { rxq->last_polled = i;return nb_rx;
@@ -147,8 +150,10 @@ failsafe_rx_burst_fast(void *queue, sdev = &priv->subs[i];assert (!fs_rx_unsafe (sdev)); sub_rxq =ETH (sdev)->data->rx_queues[rxq->qid]; +FS_ATOMIC_P (rxq->refcnt[sdev->sid]); nb_rx =ETH (sdev)->rx_pkt_burst (sub_rxq, rx_pkts, nb_pkts); +FS_ATOMIC_V (rxq->refcnt[sdev->sid]);if (nb_rx) { rxq->last_polled = i;return nb_rx;
@@ -165,13 +170,17 @@ failsafe_tx_burst(void *queue,struct sub_device *sdev;struct txq *txq;void *sub_txq; +uint16_t nb_tx; txq = queue; sdev =TX_SUBDEV (txq->priv->dev);if (unlikely (fs_tx_unsafe (sdev)))return 0 ; sub_txq =ETH (sdev)->data->tx_queues[txq->qid]; -return ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_P (txq->refcnt[sdev->sid]); + nb_tx =ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_V (txq->refcnt[sdev->sid]); +return nb_tx; }uint16_t
@@ -182,10 +191,14 @@ failsafe_tx_burst_fast(void *queue,struct sub_device *sdev;struct txq *txq;void *sub_txq; +uint16_t nb_tx; txq = queue; sdev =TX_SUBDEV (txq->priv->dev);assert (!fs_tx_unsafe (sdev)); sub_txq =ETH (sdev)->data->tx_queues[txq->qid]; -return ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_P (txq->refcnt[sdev->sid]); + nb_tx =ETH (sdev)->tx_pkt_burst (sub_txq, tx_pkts, nb_pkts); +FS_ATOMIC_V (txq->refcnt[sdev->sid]); +return nb_tx; }
Signature · 1 line
2.1.4
PATCH v6 21/22 net/failsafe: support link status change event
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_ether.c | 18 ++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 23 +++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 3 +++ 5 files changed, 46 insertions(+)
doc/guides/nics/features/failsafe.ini +1 -0
@@ -5,6 +5,7 @@ ; [Features] Link status = Y +Link status event = Y Queue start/stop = Y MTU update = Y Jumbo frame = Y
drivers/net/failsafe/failsafe.c +1 -0
@@ -240,6 +240,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) mac->addr_bytes[0 ], mac->addr_bytes[1 ], mac->addr_bytes[2 ], mac->addr_bytes[3 ], mac->addr_bytes[4], mac->addr_bytes[5]); + dev->data->dev_flags |=RTE_ETH_DEV_INTR_LSC ;return 0 ; free_args:failsafe_args_free (dev);
drivers/net/failsafe/failsafe_ether.c +18 -0
@@ -387,3 +387,21 @@ failsafe_eth_rmv_event_callback(uint8_t port_id __rte_unused, sdev->remove =1 ;return 0 ; } + +int +failsafe_eth_lsc_event_callback(uint8_t port_id __rte_unused, + enum rte_eth_event_type event __rte_unused, + void *cb_arg, void *out __rte_unused) +{ +struct rte_eth_dev *dev = cb_arg; +int ret; + + ret = dev->dev_ops->link_update (dev,0 ); +/* We must pass on the LSC event */ +if (ret) +return _rte_eth_dev_callback_process (dev, +RTE_ETH_EVENT_INTR_LSC , +NULL ,NULL ); +else +return 0 ; +}
drivers/net/failsafe/failsafe_ops.c +23 -0
@@ -207,6 +207,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } FOREACH_SUBDEV(sdev, i, dev) {int rmv_interrupt =0 ; +int lsc_interrupt =0 ; +int lsc_enabled;if (sdev->state !=DEV_PROBED )continue ;
@@ -219,6 +221,17 @@ fs_dev_configure(struct rte_eth_dev *dev) }else {DEBUG ("sub_device %d does not support RMV event" , i); } + lsc_enabled = dev->data->dev_conf.intr_conf.lsc; + lsc_interrupt = lsc_enabled && + (ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_LSC ); +if (lsc_interrupt) { +DEBUG ("Enabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =1 ; + }else if (lsc_enabled && !lsc_interrupt) { +DEBUG ("Disabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =0 ; + }DEBUG ("Configuring sub-device %d" , i); sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev),
@@ -239,6 +252,16 @@ fs_dev_configure(struct rte_eth_dev *dev) SUB_ID(sdev)); } dev->data->dev_conf.intr_conf.rmv =0 ; +if (lsc_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_LSC , + failsafe_eth_lsc_event_callback, + dev); +if (ret) +WARN ("Failed to register LSC callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.lsc = lsc_enabled; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
drivers/net/failsafe/failsafe_private.h +3 -0
@@ -179,6 +179,9 @@ void failsafe_dev_remove(struct rte_eth_dev *dev);int failsafe_eth_rmv_event_callback (uint8_t port_id,enum rte_eth_event_type type,void *arg,void *out); +int failsafe_eth_lsc_event_callback (uint8_t port_id, +enum rte_eth_event_type event, +void *cb_arg,void *out);/* GLOBALS */
Signature · 1 line
2.1.4
PATCH v6 22/22 net/failsafe: support flow API isolation mode
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_ether.c | 34 +++++++++++++++++++++++++++++++-- drivers/net/failsafe/failsafe_flow.c | 29 ++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 4 ++++ 3 files changed, 65 insertions(+), 2 deletions(-)
drivers/net/failsafe/failsafe_ether.c +32 -2
@@ -74,6 +74,28 @@ fs_flow_complain(struct rte_flow_error *error) }static int +eth_dev_flow_isolate_set (struct rte_eth_dev *dev, +struct sub_device *sdev) +{ +struct rte_flow_error ferror; +int ret; + +if (!PRIV (dev)->flow_isolated) { +DEBUG ("Flow isolation already disabled" ); + }else { +DEBUG ("Enabling flow isolation" ); + ret =rte_flow_isolate (PORT_ID (sdev), +PRIV (dev)->flow_isolated, + &ferror); +if (ret) { +fs_flow_complain (&ferror); +return ret; + } + } +return 0 ; +} + +static int fs_eth_dev_conf_apply (struct rte_eth_dev *dev,struct sub_device *sdev) {
@@ -334,9 +356,17 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)if (PRIV (dev)->state <DEV_ACTIVE )return 0 ; inactive =0 ; - FOREACH_SUBDEV(sdev, i, dev) -if (sdev->state ==DEV_PROBED ) + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state ==DEV_PROBED ) { inactive |=UINT32_C (1 ) << i; + ret =eth_dev_flow_isolate_set (dev, sdev); +if (ret) { +ERROR ("Could not apply configuration to sub_device %d" , + i); + goto err_remove; + } + } + } ret = dev->dev_ops->dev_configure (dev);if (ret) goto err_remove;
drivers/net/failsafe/failsafe_flow.c +29 -0
@@ -207,10 +207,39 @@ fs_flow_query(struct rte_eth_dev *dev,return -1 ; } +static int +fs_flow_isolate (struct rte_eth_dev *dev, +int set, +struct rte_flow_error *error) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state <DEV_PROBED ) +continue ; +DEBUG ("Calling rte_flow_isolate on sub_device %d" , i); +if (PRIV (dev)->flow_isolated != sdev->flow_isolated) +WARN ("flow isolation mode of sub_device %d in incoherent state." , + i); + ret =rte_flow_isolate (PORT_ID (sdev), set, error); +if (ret) { +ERROR ("Operation rte_flow_isolate failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + sdev->flow_isolated = set; + } +PRIV (dev)->flow_isolated = set; +return 0 ; +} +const struct rte_flow_ops fs_flow_ops = { .validate = fs_flow_validate, .create = fs_flow_create, .destroy = fs_flow_destroy, .flush = fs_flow_flush, .query = fs_flow_query, + .isolate = fs_flow_isolate, };
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -108,6 +108,8 @@ struct sub_device {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 {
@@ -139,6 +141,8 @@ struct fs_priv {*/ enum dev_state state; unsigned int pending_alarm:1; /* An alarm is pending */ +/* flow isolation state */ + int flow_isolated:1; };/* MISC */
Signature · 1 line
2.1.4
PATCH v6 22/23 net/failsafe: support link status change event
In reply to Gaetan Rivet--- doc/guides/nics/features/failsafe.ini | 1 + drivers/net/failsafe/failsafe.c | 1 + drivers/net/failsafe/failsafe_ether.c | 18 ++++++++++++++++++ drivers/net/failsafe/failsafe_ops.c | 23 +++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 3 +++ 5 files changed, 46 insertions(+)
doc/guides/nics/features/failsafe.ini +1 -0
@@ -5,6 +5,7 @@ ; [Features] Link status = Y +Link status event = Y Queue start/stop = Y MTU update = Y Jumbo frame = Y
drivers/net/failsafe/failsafe.c +1 -0
@@ -240,6 +240,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) mac->addr_bytes[0 ], mac->addr_bytes[1 ], mac->addr_bytes[2 ], mac->addr_bytes[3 ], mac->addr_bytes[4], mac->addr_bytes[5]); + dev->data->dev_flags |=RTE_ETH_DEV_INTR_LSC ;return 0 ; free_args:failsafe_args_free (dev);
drivers/net/failsafe/failsafe_ether.c +18 -0
@@ -387,3 +387,21 @@ failsafe_eth_rmv_event_callback(uint8_t port_id __rte_unused, sdev->remove =1 ;return 0 ; } + +int +failsafe_eth_lsc_event_callback(uint8_t port_id __rte_unused, + enum rte_eth_event_type event __rte_unused, + void *cb_arg, void *out __rte_unused) +{ +struct rte_eth_dev *dev = cb_arg; +int ret; + + ret = dev->dev_ops->link_update (dev,0 ); +/* We must pass on the LSC event */ +if (ret) +return _rte_eth_dev_callback_process (dev, +RTE_ETH_EVENT_INTR_LSC , +NULL ,NULL ); +else +return 0 ; +}
drivers/net/failsafe/failsafe_ops.c +23 -0
@@ -207,6 +207,8 @@ fs_dev_configure(struct rte_eth_dev *dev) } FOREACH_SUBDEV(sdev, i, dev) {int rmv_interrupt =0 ; +int lsc_interrupt =0 ; +int lsc_enabled;if (sdev->state !=DEV_PROBED )continue ;
@@ -219,6 +221,17 @@ fs_dev_configure(struct rte_eth_dev *dev) }else {DEBUG ("sub_device %d does not support RMV event" , i); } + lsc_enabled = dev->data->dev_conf.intr_conf.lsc; + lsc_interrupt = lsc_enabled && + (ETH (sdev)->data->dev_flags & +RTE_ETH_DEV_INTR_LSC ); +if (lsc_interrupt) { +DEBUG ("Enabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =1 ; + }else if (lsc_enabled && !lsc_interrupt) { +DEBUG ("Disabling LSC interrupts for sub_device %d" , i); + dev->data->dev_conf.intr_conf.lsc =0 ; + }DEBUG ("Configuring sub-device %d" , i); sdev->remove =0 ; ret = rte_eth_dev_configure(PORT_ID(sdev),
@@ -239,6 +252,16 @@ fs_dev_configure(struct rte_eth_dev *dev) SUB_ID(sdev)); } dev->data->dev_conf.intr_conf.rmv =0 ; +if (lsc_interrupt) { + ret =rte_eth_dev_callback_register (PORT_ID (sdev), +RTE_ETH_EVENT_INTR_LSC , + failsafe_eth_lsc_event_callback, + dev); +if (ret) +WARN ("Failed to register LSC callback for sub_device %d" , +SUB_ID (sdev)); + } + dev->data->dev_conf.intr_conf.lsc = lsc_enabled; sdev->state =DEV_ACTIVE ; }if (PRIV (dev)->state <DEV_ACTIVE )
drivers/net/failsafe/failsafe_private.h +3 -0
@@ -179,6 +179,9 @@ void failsafe_dev_remove(struct rte_eth_dev *dev);int failsafe_eth_rmv_event_callback (uint8_t port_id,enum rte_eth_event_type type,void *arg,void *out); +int failsafe_eth_lsc_event_callback (uint8_t port_id, +enum rte_eth_event_type event, +void *cb_arg,void *out);/* GLOBALS */
Signature · 1 line
2.1.4
PATCH v6 23/23 net/failsafe: support flow API isolation mode
In reply to Gaetan Rivet--- drivers/net/failsafe/failsafe_ether.c | 34 +++++++++++++++++++++++++++++++-- drivers/net/failsafe/failsafe_flow.c | 29 ++++++++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 4 ++++ 3 files changed, 65 insertions(+), 2 deletions(-)
drivers/net/failsafe/failsafe_ether.c +32 -2
@@ -74,6 +74,28 @@ fs_flow_complain(struct rte_flow_error *error) }static int +eth_dev_flow_isolate_set (struct rte_eth_dev *dev, +struct sub_device *sdev) +{ +struct rte_flow_error ferror; +int ret; + +if (!PRIV (dev)->flow_isolated) { +DEBUG ("Flow isolation already disabled" ); + }else { +DEBUG ("Enabling flow isolation" ); + ret =rte_flow_isolate (PORT_ID (sdev), +PRIV (dev)->flow_isolated, + &ferror); +if (ret) { +fs_flow_complain (&ferror); +return ret; + } + } +return 0 ; +} + +static int fs_eth_dev_conf_apply (struct rte_eth_dev *dev,struct sub_device *sdev) {
@@ -334,9 +356,17 @@ failsafe_eth_dev_state_sync(struct rte_eth_dev *dev)if (PRIV (dev)->state <DEV_ACTIVE )return 0 ; inactive =0 ; - FOREACH_SUBDEV(sdev, i, dev) -if (sdev->state ==DEV_PROBED ) + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state ==DEV_PROBED ) { inactive |=UINT32_C (1 ) << i; + ret =eth_dev_flow_isolate_set (dev, sdev); +if (ret) { +ERROR ("Could not apply configuration to sub_device %d" , + i); + goto err_remove; + } + } + } ret = dev->dev_ops->dev_configure (dev);if (ret) goto err_remove;
drivers/net/failsafe/failsafe_flow.c +29 -0
@@ -207,10 +207,39 @@ fs_flow_query(struct rte_eth_dev *dev,return -1 ; } +static int +fs_flow_isolate (struct rte_eth_dev *dev, +int set, +struct rte_flow_error *error) +{ +struct sub_device *sdev; +uint8_t i; +int ret; + + FOREACH_SUBDEV(sdev, i, dev) { +if (sdev->state <DEV_PROBED ) +continue ; +DEBUG ("Calling rte_flow_isolate on sub_device %d" , i); +if (PRIV (dev)->flow_isolated != sdev->flow_isolated) +WARN ("flow isolation mode of sub_device %d in incoherent state." , + i); + ret =rte_flow_isolate (PORT_ID (sdev), set, error); +if (ret) { +ERROR ("Operation rte_flow_isolate failed for sub_device %d" +" with error %d" , i, ret); +return ret; + } + sdev->flow_isolated = set; + } +PRIV (dev)->flow_isolated = set; +return 0 ; +} +const struct rte_flow_ops fs_flow_ops = { .validate = fs_flow_validate, .create = fs_flow_create, .destroy = fs_flow_destroy, .flush = fs_flow_flush, .query = fs_flow_query, + .isolate = fs_flow_isolate, };
drivers/net/failsafe/failsafe_private.h +4 -0
@@ -108,6 +108,8 @@ struct sub_device {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 {
@@ -139,6 +141,8 @@ struct fs_priv {*/ enum dev_state state; unsigned int pending_alarm:1; /* An alarm is pending */ +/* flow isolation state */ + int flow_isolated:1; };/* MISC */
Signature · 1 line
2.1.4
Quoted 104 lines · Gaetan Rivet
This PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixesv2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.v3 --> v4:
- Split back commits
net/failsafe: add fast burst functions net/failsafe: support device removal
That were squashed by error during a rebase
- Fix segfault on port plugin
- Fix isolate mode support for MLX4 ports pluginv4 --> v5:
- Follow new plug / unplug API.
v5 --> v6:
- Follow new hotplug API.
- Improve usability of hotplug API.
- Fixrte_devhotplug API implementation.
- Introducerte_eal_devargs_rmvAPI as EXPERIMENTAL.
- Use it to clean up resources onhotplug_remove.
- Fix hotplug implementation and support un pci bus. The scan was not idempotent, nor clean. Neither were the device fields.
- Implement plug operation for vdev bus.
This is needed for hotplug support and to make the EAL independent from vdev-specific API.
- Remove useless parameters from plug / unplug API.This patchset is fairly big and complex. The hotplug API has been rushed and has never been tested outside of the special case of vdev bus.
These evolutions are proposed alongside this PMD as only this PMD allows to test this API at the moment, and without those evolutions this PMD cannot be used.
Gaetan Rivet (22):
eal: return device handle upon plugin
eal: fix hotplug add
devargs: introduce removal function
eal: release devargs on device removal
pci: use given name as generic name
pci: fix generic driver pointer on probe error
pci: fix hotplug operations
vdev: add dev to vdev macro
vdev: implement plug operation
bus: remove useless plug parameter
ethdev: save VLAN filter setting
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMD
Quoted 8 lines
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support device removal
net/failsafe: support link status change event
net/failsafe: support flow API isolation mode
Hi Gaetan,
The failsafe PMD postponed to RC2, to mainly let eal level dependencies be resolved first, and I believe it is OK to get a PMD in RC2 because its scope is limited.
But in this new version of the patchset, there are many patches touches to eal and ethdev level. I don't think it is good idea to get these changes in RC2 and with next-net tree.
I believe these should be resolved in main repo, in RC1. And failsafe as a PMD, can go in RC2 via next-net.
What do you think separating eal and ethdev bits of the patchset and target RC1?
Thanks,
ferruh
Quoted 124 lines · Ferruh Yigit
Quoted 104 lines · Gaetan Rivet
This PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixesv2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.v3 --> v4:
- Split back commits
net/failsafe: add fast burst functions net/failsafe: support device removal
That were squashed by error during a rebase
- Fix segfault on port plugin
- Fix isolate mode support for MLX4 ports pluginv4 --> v5:
- Follow new plug / unplug API.
v5 --> v6:
- Follow new hotplug API.
- Improve usability of hotplug API.
- Fixrte_devhotplug API implementation.
- Introducerte_eal_devargs_rmvAPI as EXPERIMENTAL.
- Use it to clean up resources onhotplug_remove.
- Fix hotplug implementation and support un pci bus. The scan was not idempotent, nor clean. Neither were the device fields.
- Implement plug operation for vdev bus.
This is needed for hotplug support and to make the EAL independent from vdev-specific API.
- Remove useless parameters from plug / unplug API.This patchset is fairly big and complex. The hotplug API has been rushed and has never been tested outside of the special case of vdev bus.
These evolutions are proposed alongside this PMD as only this PMD allows to test this API at the moment, and without those evolutions this PMD cannot be used.
Gaetan Rivet (22):
eal: return device handle upon plugin
eal: fix hotplug add
devargs: introduce removal function
eal: release devargs on device removal
pci: use given name as generic name
pci: fix generic driver pointer on probe error
pci: fix hotplug operations
vdev: add dev to vdev macro
vdev: implement plug operation
bus: remove useless plug parameter
ethdev: save VLAN filter setting
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMDQuoted 8 lines
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support device removal
net/failsafe: support link status change event
net/failsafe: support flow API isolation modeHi Gaetan,
The failsafe PMD postponed to RC2, to mainly let eal level dependencies be resolved first, and I believe it is OK to get a PMD in RC2 because its scope is limited.
But in this new version of the patchset, there are many patches touches to eal and ethdev level. I don't think it is good idea to get these changes in RC2 and with next-net tree.
Quoted 6 lines
I believe these should be resolved in main repo, in RC1. And failsafe as a PMD, can go in RC2 via next-net.
What do you think separating eal and ethdev bits of the patchset and target RC1?
Sure, I'm all for it. The only reason I presented them both at once was because the changes that would then be included in RC1 will be hard to test without the fail-safe PMD.
But it makes sense to stabilize the lib changes before integrating the fail-safe.
Quoted 2 lines
Thanks,
ferruh
Signature · 2 lines
Gaëtan Rivet 6WIND
v7 cover introduce fail-safe PMD
In reply to Gaetan RivetThis PMD intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back so that existing applications do not need to be modified to benefit from true hot-plugging support.
The stacked PMD approach shares many similarities with the bonding PMD but with a different purpose. While bonding provides the ability to group several links into a single logical device for enhanced throughput and supports fail-over at link level, this one manages the sudden disappearance of the underlying device; it guarantees applications face a valid device in working order at all times.
Each fail-safe instance is configured to run atop one or several devices, with one defined as the preferred device. Hot-plug events are handled on all of them, and Tx is always directed to the preferred device if present or to the next available failover device (Rx is always performed on all devices for simplicity).
Moreover, the configured slaves (preferred or failover) do not need to be present at initialization time and may appear later.
Slaves configuration is continuously synchronized with that of the virtual device, which exposes their common set of capabilities to the application. Failure to apply the current configuration state to a slave for any reason simply reschedules its initialization.
This patchset depends on:
eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-May/066366.html
http://dpdk.org/dev/patchwork/patch/24522/
ethdev: add flow API rule copy function
http://dpdk.org/ml/archives/dev/2017-May/066145.html
http://dpdk.org/dev/patchwork/patch/24406/
ethdev: add isolated mode to flow API
http://dpdk.org/ml/archives/dev/2017-April/064327.html
http://dpdk.org/dev/patchwork/patch/23741/
v1 --> v2:
- Wrote documentation
- Fixed commit logs, signed-off-by
- Added LSC event support
- A few minor fixes
v2 --> v3:
- Numerous bug fixes.
- Complete sub-EAL rework to follow new bus API.
- burst protection on sub removal.
- more flexible sub definition.
- flow isolated mode support.
v3 --> v4:
- Split back commits
net/failsafe: add fast burst functions net/failsafe: support device removal
That were squashed by error during a rebase
- Fix segfault on port plugin
- Fix isolate mode support for MLX4 ports plugin
v4 --> v5:
- Follow new plug / unplug API.
v5 --> v6:
- Follow new hotplug API.
- Improve usability of hotplug API.
- Fix rte_dev hotplug API implementation.
- Introduce rte_eal_devargs_rmv API as EXPERIMENTAL.
- Use it to clean up resources on hotplug_remove.
- Fix hotplug implementation and support un pci bus. The scan was not idempotent, nor clean. Neither were the device fields.
- Implement plug operation for vdev bus.
This is needed for hotplug support and to make the EAL independent from vdev-specific API.
- Remove useless parameters from plug / unplug API.
This patchset is fairly big and complex. The hotplug API has been rushed and has never been tested outside of the special case of vdev bus.
These evolutions are proposed alongside this PMD as only this PMD allows to test this API at the moment, and without those evolutions this PMD cannot be used.
v6 --> v7
- Split the series in three, with
vlan filter configuration store standing alone Hotplug API fixes separated
Fail-safe PMD on its own.
These changes should ease integration.
Gaetan Rivet (11):
ethdev: add deferred intermediate device state
ethdev: count devices consistently
net/failsafe: add fail-safe PMD
net/failsafe: add plug-in support
net/failsafe: add flexible device definition
net/failsafe: support flow API
net/failsafe: support offload capabilities
net/failsafe: add fast burst functions
net/failsafe: support device removal
net/failsafe: support link status change event
net/failsafe: support flow API isolation mode
MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 186 +++++ doc/guides/nics/features/failsafe.ini | 32 + doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 78 ++ drivers/net/failsafe/failsafe.c | 305 ++++++++ drivers/net/failsafe/failsafe_args.c | 475 ++++++++++++ drivers/net/failsafe/failsafe_eal.c | 134 ++++ drivers/net/failsafe/failsafe_ether.c | 437 +++++++++++ drivers/net/failsafe/failsafe_flow.c | 245 ++++++ drivers/net/failsafe/failsafe_ops.c | 869 ++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 376 ++++++++++ drivers/net/failsafe/failsafe_rxtx.c | 204 +++++ drivers/net/failsafe/rte_pmd_failsafe_version.map | 4 + lib/librte_ether/rte_ethdev.c | 19 +- lib/librte_ether/rte_ethdev.h | 14 +- mk/rte.app.mk | 1 + 19 files changed, 3378 insertions(+), 15 deletions(-) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ether.c create mode 100644 drivers/net/failsafe/failsafe_flow.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c create mode 100644 drivers/net/failsafe/rte_pmd_failsafe_version.map
Signature · 1 line
2.1.4
PATCH v7 1/11 ethdev: add deferred intermediate device state
This device state means that the device is managed externally, by whichever party has set this state (PMD or application).
Note: this new device state is only an information. The related device structure and operators are still valid and can be used normally.
It is however made private by device management helpers within ethdev, making the device invisible to applications.
--- lib/librte_ether/rte_ethdev.c | 3 ++- lib/librte_ether/rte_ethdev.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
lib/librte_ether/rte_ethdev.c +2 -1
@@ -291,7 +291,8 @@ int rte_eth_dev_is_valid_port(uint8_t port_id) {if (port_id >=RTE_MAX_ETHPORTS || - rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED ) + (rte_eth_devices[port_id].state !=RTE_ETH_DEV_ATTACHED && + rte_eth_devices[port_id].state !=RTE_ETH_DEV_DEFERRED ))return 0 ;else return 1 ;
lib/librte_ether/rte_ethdev.h +1 -0
@@ -1589,6 +1589,7 @@ struct rte_eth_rxtx_callback {enum rte_eth_dev_state {RTE_ETH_DEV_UNUSED =0 ,RTE_ETH_DEV_ATTACHED , +RTE_ETH_DEV_DEFERRED , };/**
Signature · 1 line
2.1.4
PATCH v7 2/11 ethdev: count devices consistently
In reply to Gaetan RivetMake the rte_eth_dev_count() return the number of available devices even after some are detached by the hotplug API or put in a deferred state.
--- lib/librte_ether/rte_ethdev.c | 16 +++++++++------- lib/librte_ether/rte_ethdev.h | 13 ++++++------- 2 files changed, 15 insertions(+), 14 deletions(-)
lib/librte_ether/rte_ethdev.c +9 -7
@@ -72,7 +72,6 @@ static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS ];static struct rte_eth_dev_data *rte_eth_dev_data;static uint8_t eth_dev_last_created_port; -static uint8_t nb_ports;/* spinlock for eth device callbacks */ static rte_spinlock_t rte_eth_dev_cb_lock =RTE_SPINLOCK_INITIALIZER ;
@@ -210,7 +209,6 @@ eth_dev_get(uint8_t port_id)TAILQ_INIT (&(eth_dev->link_intr_cbs)); eth_dev_last_created_port = port_id; - nb_ports++;return eth_dev; }
@@ -283,7 +281,6 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)return -EINVAL ; eth_dev->state =RTE_ETH_DEV_UNUSED ; - nb_ports--;return 0 ; }
@@ -308,7 +305,15 @@ rte_eth_dev_socket_id(uint8_t port_id)uint8_t rte_eth_dev_count (void ) { -return nb_ports; +uint8_t p; +uint8_t count; + + count =0 ; + +RTE_ETH_FOREACH_DEV (p) + count++; + +return count; }int
@@ -341,9 +346,6 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)return -EINVAL ; } -if (!nb_ports) -return -ENODEV ; -RTE_ETH_FOREACH_DEV (i) {if (!rte_eth_devices[i].device)continue ;
lib/librte_ether/rte_ethdev.h +6 -7
@@ -1724,13 +1724,12 @@ uint8_t rte_eth_find_next(uint8_t port_id);/** * Get the total number of Ethernet devices that have been successfully -* initialized by the [matching] Ethernet driver during the PCI probing phase. -* All devices whose port identifier is in the range -* [0, rte_eth_dev_count() - 1] can be operated on by network applications -* immediately after invoking rte_eal_init(). -* If the application unplugs a port using hotplug function, The enabled port -* numbers may be noncontiguous. In the case, the applications need to manage -* enabled port by using the ``RTE_ETH_FOREACH_DEV()`` macro. +* initialized by the matching Ethernet driver during the PCI probing phase +* and that are available for applications to use. These devices must be +* accessed by using the ``RTE_ETH_FOREACH_DEV()`` macro to deal with +* non-contiguous ranges of devices. +* These non-contiguous ranges can be created by calls to hotplug functions or +* by some PMDs. * * @return * - The total number of usable Ethernet devices.
Signature · 1 line
2.1.4
PATCH v7 3/11 net/failsafe: add fail-safe PMD
In reply to Gaetan RivetIntroduce the fail-safe poll mode driver initialization and enable its build infrastructure.
This PMD allows for applications to benefit from true hot-plugging support without having to implement it.
It intercepts and manages Ethernet device removal events issued by slave PMDs and re-initializes them transparently when brought back. It also allows defining a contingency to the removal of a device, by designating a fail-over device that will take on transmitting operations if the preferred device is removed.
Applications only see a fail-safe instance, without caring for underlying activity ensuring their continued operations.
--- MAINTAINERS | 5 + config/common_base | 6 + doc/guides/nics/fail_safe.rst | 133 +++++ doc/guides/nics/features/failsafe.ini | 24 + doc/guides/nics/index.rst | 1 + drivers/net/Makefile | 2 + drivers/net/failsafe/Makefile | 76 +++ drivers/net/failsafe/failsafe.c | 231 ++++++++ drivers/net/failsafe/failsafe_args.c | 331 +++++++++++ drivers/net/failsafe/failsafe_eal.c | 154 +++++ drivers/net/failsafe/failsafe_ops.c | 663 ++++++++++++++++++++++ drivers/net/failsafe/failsafe_private.h | 227 ++++++++ drivers/net/failsafe/failsafe_rxtx.c | 107 ++++ drivers/net/failsafe/rte_pmd_failsafe_version.map | 4 + mk/rte.app.mk | 1 + 15 files changed, 1965 insertions(+) create mode 100644 doc/guides/nics/fail_safe.rst create mode 100644 doc/guides/nics/features/failsafe.ini create mode 100644 drivers/net/failsafe/Makefile create mode 100644 drivers/net/failsafe/failsafe.c create mode 100644 drivers/net/failsafe/failsafe_args.c create mode 100644 drivers/net/failsafe/failsafe_eal.c create mode 100644 drivers/net/failsafe/failsafe_ops.c create mode 100644 drivers/net/failsafe/failsafe_private.h create mode 100644 drivers/net/failsafe/failsafe_rxtx.c create mode 100644 drivers/net/failsafe/rte_pmd_failsafe_version.map
MAINTAINERS +5 -0
@@ -336,6 +336,11 @@ F: drivers/net/enic/ F: doc/guides/nics/enic.rst F: doc/guides/nics/features/enic.ini +Fail-safe PMD +M: Gaetan Rivet <[email protected]> +F: drivers/net/failsafe/ +F: doc/guides/nics/fail_safe.rst + Intel e1000 M: Wenzhuo Lu <[email protected]> F: drivers/net/e1000/
config/common_base +6 -0
@@ -420,6 +420,12 @@ CONFIG_RTE_LIBRTE_PMD_XENVIRT=n CONFIG_RTE_LIBRTE_PMD_NULL=y # +# Compile fail-safe PMD +# +CONFIG_RTE_LIBRTE_PMD_FAILSAFE=y +CONFIG_RTE_LIBRTE_PMD_FAILSAFE_DEBUG=n + +# # Do prefetch of packet data within PMD driver receive function # CONFIG_RTE_PMD_PACKET_PREFETCH=y
doc/guides/nics/fail_safe.rst new file +133 -0
133 lines not on this page · raw message
doc/guides/nics/features/failsafe.ini new file +24 -0
@@ -0,0 +1,24 @@ +; +; Supported features of the 'fail-safe' poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Link status = Y +Queue start/stop = Y +MTU update = Y +Jumbo frame = Y +Promiscuous mode = Y +Allmulticast mode = Y +Unicast MAC filter = Y +Multicast MAC filter = Y +VLAN filter = Y +Packet type parsing = Y +Basic stats = Y +Stats per queue = Y +ARMv7 = Y +ARMv8 = Y +Power8 = Y +x86-32 = Y +x86-64 = Y +Usage doc = Y
doc/guides/nics/index.rst +1 -0
@@ -64,6 +64,7 @@ Network Interface Controller Drivers vhost vmxnet3 pcap_ring + fail_safe **Figures**
drivers/net/Makefile +2 -0
@@ -59,6 +59,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena DEPDIRS-ena = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += enic DEPDIRS-enic = $(core-libs) librte_hash +DIRS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe +DEPDIRS-failsafe = $(core-libs) DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k DEPDIRS-fm10k = $(core-libs) librte_hash DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
drivers/net/failsafe/Makefile new file +76 -0
76 lines not on this page · raw message
drivers/net/failsafe/failsafe.c new file +231 -0
231 lines not on this page · raw message
drivers/net/failsafe/failsafe_args.c new file +331 -0
331 lines not on this page · raw message
drivers/net/failsafe/failsafe_eal.c new file +154 -0
154 lines not on this page · raw message
drivers/net/failsafe/failsafe_ops.c new file +663 -0
663 lines not on this page · raw message
drivers/net/failsafe/failsafe_private.h new file +227 -0
227 lines not on this page · raw message
drivers/net/failsafe/failsafe_rxtx.c new file +107 -0
107 lines not on this page · raw message
drivers/net/failsafe/rte_pmd_failsafe_version.map new file +4 -0
@@ -0,0 +1,4 @@ +DPDK_17.08 { + + local: *; +};
mk/rte.app.mk +1 -0
@@ -120,6 +120,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000 _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += -lrte_pmd_fm10k +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += -lrte_pmd_failsafe _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
Signature · 1 line
2.1.4