diff options
Diffstat (limited to 'drivers/net/failsafe')
-rw-r--r-- | drivers/net/failsafe/Makefile | 33 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe.c | 52 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe_args.c | 9 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe_eal.c | 61 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe_ether.c | 55 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe_flow.c | 6 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe_intr.c | 2 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe_ops.c | 151 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe_private.h | 18 | ||||
-rw-r--r-- | drivers/net/failsafe/failsafe_rxtx.c | 2 | ||||
-rw-r--r-- | drivers/net/failsafe/meson.build | 23 |
11 files changed, 251 insertions, 161 deletions
diff --git a/drivers/net/failsafe/Makefile b/drivers/net/failsafe/Makefile index bd2f0198..81802d09 100644 --- a/drivers/net/failsafe/Makefile +++ b/drivers/net/failsafe/Makefile @@ -1,33 +1,6 @@ -# BSD LICENSE -# -# Copyright 2017 6WIND S.A. -# Copyright 2017 Mellanox. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of 6WIND S.A. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2017 6WIND S.A. +# Copyright 2017 Mellanox Technologies, Ltd include $(RTE_SDK)/mk/rte.vars.mk diff --git a/drivers/net/failsafe/failsafe.c b/drivers/net/failsafe/failsafe.c index c499bfb9..657919f9 100644 --- a/drivers/net/failsafe/failsafe.c +++ b/drivers/net/failsafe/failsafe.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2017 6WIND S.A. - * Copyright 2017 Mellanox. + * Copyright 2017 Mellanox Technologies, Ltd */ #include <rte_alarm.h> @@ -13,6 +13,8 @@ #include "failsafe_private.h" +int failsafe_logtype; + const char pmd_failsafe_driver_name[] = FAILSAFE_DRIVER_NAME; static const struct rte_eth_link eth_link = { .link_speed = ETH_SPEED_NUM_10G, @@ -202,16 +204,25 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) } snprintf(priv->my_owner.name, sizeof(priv->my_owner.name), FAILSAFE_OWNER_NAME); + DEBUG("Failsafe port %u owner info: %s_%016"PRIX64, dev->data->port_id, + priv->my_owner.name, priv->my_owner.id); + ret = rte_eth_dev_callback_register(RTE_ETH_ALL, RTE_ETH_EVENT_NEW, + failsafe_eth_new_event_callback, + dev); + if (ret) { + ERROR("Failed to register NEW callback"); + goto free_args; + } ret = failsafe_eal_init(dev); if (ret) - goto free_args; + goto unregister_new_callback; ret = fs_mutex_init(priv); if (ret) - goto free_args; + goto unregister_new_callback; ret = failsafe_hotplug_alarm_install(dev); if (ret) { ERROR("Could not set up plug-in event detection"); - goto free_args; + goto unregister_new_callback; } mac = &dev->data->mac_addrs[0]; if (mac_from_arg) { @@ -224,7 +235,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) mac); if (ret) { ERROR("Failed to set default MAC address"); - goto free_args; + goto cancel_alarm; } } } else { @@ -257,7 +268,13 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) .fd = -1, .type = RTE_INTR_HANDLE_EXT, }; + rte_eth_dev_probing_finish(dev); return 0; +cancel_alarm: + failsafe_hotplug_alarm_cancel(dev); +unregister_new_callback: + rte_eth_dev_callback_unregister(RTE_ETH_ALL, RTE_ETH_EVENT_NEW, + failsafe_eth_new_event_callback, dev); free_args: failsafe_args_free(dev); free_subs: @@ -277,6 +294,8 @@ fs_rte_eth_free(const char *name) dev = rte_eth_dev_allocated(name); if (dev == NULL) return -ENODEV; + rte_eth_dev_callback_unregister(RTE_ETH_ALL, RTE_ETH_EVENT_NEW, + failsafe_eth_new_event_callback, dev); ret = failsafe_eal_uninit(dev); if (ret) ERROR("Error while uninitializing sub-EAL"); @@ -294,10 +313,26 @@ static int rte_pmd_failsafe_probe(struct rte_vdev_device *vdev) { const char *name; + struct rte_eth_dev *eth_dev; name = rte_vdev_device_name(vdev); INFO("Initializing " FAILSAFE_DRIVER_NAME " for %s", name); + + if (rte_eal_process_type() == RTE_PROC_SECONDARY && + strlen(rte_vdev_device_args(vdev)) == 0) { + eth_dev = rte_eth_dev_attach_secondary(name); + if (!eth_dev) { + ERROR("Failed to probe %s", name); + return -1; + } + /* TODO: request info from primary to set up Rx and Tx */ + eth_dev->dev_ops = &failsafe_ops; + eth_dev->device = &vdev->device; + rte_eth_dev_probing_finish(eth_dev); + return 0; + } + return fs_eth_dev_create(vdev); } @@ -318,3 +353,10 @@ static struct rte_vdev_driver failsafe_drv = { RTE_PMD_REGISTER_VDEV(net_failsafe, failsafe_drv); RTE_PMD_REGISTER_PARAM_STRING(net_failsafe, PMD_FAILSAFE_PARAM_STRING); + +RTE_INIT(failsafe_init_log) +{ + failsafe_logtype = rte_log_register("pmd.net.failsafe"); + if (failsafe_logtype >= 0) + rte_log_set_level(failsafe_logtype, RTE_LOG_NOTICE); +} diff --git a/drivers/net/failsafe/failsafe_args.c b/drivers/net/failsafe/failsafe_args.c index 366dbea1..626883ce 100644 --- a/drivers/net/failsafe/failsafe_args.c +++ b/drivers/net/failsafe/failsafe_args.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2017 6WIND S.A. - * Copyright 2017 Mellanox. + * Copyright 2017 Mellanox Technologies, Ltd */ #include <fcntl.h> @@ -14,6 +14,7 @@ #include <rte_devargs.h> #include <rte_malloc.h> #include <rte_kvargs.h> +#include <rte_string_fns.h> #include "failsafe_private.h" @@ -62,7 +63,7 @@ fs_parse_device(struct sub_device *sdev, char *args) d = &sdev->devargs; DEBUG("%s", args); - ret = rte_eal_devargs_parse(args, d); + ret = rte_devargs_parse(d, args); if (ret) { DEBUG("devargs parsing failed with code %d", ret); return ret; @@ -340,7 +341,7 @@ fs_remove_sub_devices_definition(char params[DEVARGS_MAXLEN]) a = b + 1; } out: - snprintf(params, DEVARGS_MAXLEN, "%s", buffer); + strlcpy(params, buffer, DEVARGS_MAXLEN); return 0; } @@ -392,7 +393,7 @@ failsafe_args_parse(struct rte_eth_dev *dev, const char *params) ret = 0; priv->subs_tx = FAILSAFE_MAX_ETHPORTS; /* default parameters */ - n = snprintf(mut_params, sizeof(mut_params), "%s", params); + n = strlcpy(mut_params, params, sizeof(mut_params)); if (n >= sizeof(mut_params)) { ERROR("Parameter string too long (>=%zu)", sizeof(mut_params)); diff --git a/drivers/net/failsafe/failsafe_eal.c b/drivers/net/failsafe/failsafe_eal.c index c3d67312..ce1633f1 100644 --- a/drivers/net/failsafe/failsafe_eal.c +++ b/drivers/net/failsafe/failsafe_eal.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2017 6WIND S.A. - * Copyright 2017 Mellanox. + * Copyright 2017 Mellanox Technologies, Ltd */ #include <rte_malloc.h> @@ -18,8 +18,9 @@ fs_ethdev_portid_get(const char *name, uint16_t *port_id) return -EINVAL; } len = strlen(name); - RTE_ETH_FOREACH_DEV(pid) { - if (!strncmp(name, rte_eth_devices[pid].device->name, len)) { + for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) { + if (rte_eth_dev_is_valid_port(pid) && + !strncmp(name, rte_eth_devices[pid].device->name, len)) { *port_id = pid; return 0; } @@ -41,6 +42,8 @@ fs_bus_init(struct rte_eth_dev *dev) continue; da = &sdev->devargs; if (fs_ethdev_portid_get(da->name, &pid) != 0) { + struct rte_eth_dev_owner pid_owner; + ret = rte_eal_hotplug_add(da->bus->name, da->name, da->args); @@ -55,12 +58,26 @@ fs_bus_init(struct rte_eth_dev *dev) ERROR("sub_device %d init went wrong", i); return -ENODEV; } + /* + * The NEW callback tried to take ownership, check + * whether it succeed or didn't. + */ + rte_eth_dev_owner_get(pid, &pid_owner); + if (pid_owner.id != PRIV(dev)->my_owner.id) { + INFO("sub_device %d owner(%s_%016"PRIX64") is not my," + " owner(%s_%016"PRIX64"), will try again later", + i, pid_owner.name, pid_owner.id, + PRIV(dev)->my_owner.name, + PRIV(dev)->my_owner.id); + continue; + } } else { + /* The sub-device port was found. */ char devstr[DEVARGS_MAXLEN] = ""; struct rte_devargs *probed_da = rte_eth_devices[pid].device->devargs; - /* Take control of device probed by EAL options. */ + /* Take control of probed device. */ free(da->args); memset(da, 0, sizeof(*da)); if (probed_da != NULL) @@ -69,7 +86,7 @@ fs_bus_init(struct rte_eth_dev *dev) else snprintf(devstr, sizeof(devstr), "%s", rte_eth_devices[pid].device->name); - ret = rte_eal_devargs_parse(devstr, da); + ret = rte_devargs_parse(da, devstr); if (ret) { ERROR("Probed devargs parsing failed with code" " %d", ret); @@ -77,28 +94,28 @@ fs_bus_init(struct rte_eth_dev *dev) } INFO("Taking control of a probed sub device" " %d named %s", i, da->name); - } - ret = rte_eth_dev_owner_set(pid, &PRIV(dev)->my_owner); - if (ret < 0) { - INFO("sub_device %d owner set failed (%s)," - " will try again later", i, strerror(-ret)); - continue; - } else if (strncmp(rte_eth_devices[pid].device->name, da->name, - strlen(da->name)) != 0) { - /* - * The device probably was removed and its port id was - * reallocated before ownership set. - */ - rte_eth_dev_owner_unset(pid, PRIV(dev)->my_owner.id); - INFO("sub_device %d was probably removed before taking" - " ownership, will try again later", i); - continue; + ret = rte_eth_dev_owner_set(pid, &PRIV(dev)->my_owner); + if (ret < 0) { + INFO("sub_device %d owner set failed (%s), " + "will try again later", i, strerror(-ret)); + continue; + } else if (strncmp(rte_eth_devices[pid].device->name, + da->name, strlen(da->name)) != 0) { + /* + * The device probably was removed and its port + * id was reallocated before ownership set. + */ + rte_eth_dev_owner_unset(pid, + PRIV(dev)->my_owner.id); + INFO("sub_device %d was removed before taking" + " ownership, will try again later", i); + continue; + } } ETH(sdev) = &rte_eth_devices[pid]; SUB_ID(sdev) = i; sdev->fs_dev = dev; sdev->dev = ETH(sdev)->device; - ETH(sdev)->state = RTE_ETH_DEV_DEFERRED; sdev->state = DEV_PROBED; } return 0; diff --git a/drivers/net/failsafe/failsafe_ether.c b/drivers/net/failsafe/failsafe_ether.c index 2c0bf936..5b5cb3b4 100644 --- a/drivers/net/failsafe/failsafe_ether.c +++ b/drivers/net/failsafe/failsafe_ether.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2017 6WIND S.A. - * Copyright 2017 Mellanox. + * Copyright 2017 Mellanox Technologies, Ltd */ #include <unistd.h> @@ -260,6 +260,7 @@ fs_dev_remove(struct sub_device *sdev) sdev->state = DEV_ACTIVE; /* fallthrough */ case DEV_ACTIVE: + failsafe_eth_dev_unregister_callbacks(sdev); rte_eth_dev_close(PORT_ID(sdev)); sdev->state = DEV_PROBED; /* fallthrough */ @@ -321,6 +322,35 @@ fs_rxtx_clean(struct sub_device *sdev) } void +failsafe_eth_dev_unregister_callbacks(struct sub_device *sdev) +{ + int ret; + + if (sdev == NULL) + return; + if (sdev->rmv_callback) { + ret = rte_eth_dev_callback_unregister(PORT_ID(sdev), + RTE_ETH_EVENT_INTR_RMV, + failsafe_eth_rmv_event_callback, + sdev); + if (ret) + WARN("Failed to unregister RMV callback for sub_device" + " %d", SUB_ID(sdev)); + sdev->rmv_callback = 0; + } + if (sdev->lsc_callback) { + ret = rte_eth_dev_callback_unregister(PORT_ID(sdev), + RTE_ETH_EVENT_INTR_LSC, + failsafe_eth_lsc_event_callback, + sdev); + if (ret) + WARN("Failed to unregister LSC callback for sub_device" + " %d", SUB_ID(sdev)); + sdev->lsc_callback = 0; + } +} + +void failsafe_dev_remove(struct rte_eth_dev *dev) { struct sub_device *sdev; @@ -463,3 +493,26 @@ failsafe_eth_lsc_event_callback(uint16_t port_id __rte_unused, else return 0; } + +/* Take sub-device ownership before it becomes exposed to the application. */ +int +failsafe_eth_new_event_callback(uint16_t port_id, + enum rte_eth_event_type event __rte_unused, + void *cb_arg, void *out __rte_unused) +{ + struct rte_eth_dev *fs_dev = cb_arg; + struct sub_device *sdev; + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + uint8_t i; + + FOREACH_SUBDEV_STATE(sdev, i, fs_dev, DEV_PARSED) { + if (sdev->state >= DEV_PROBED) + continue; + if (strcmp(sdev->devargs.name, dev->device->name) != 0) + continue; + rte_eth_dev_owner_set(port_id, &PRIV(fs_dev)->my_owner); + /* The actual owner will be checked after the port probing. */ + break; + } + return 0; +} diff --git a/drivers/net/failsafe/failsafe_flow.c b/drivers/net/failsafe/failsafe_flow.c index ec8c909b..bfe42fce 100644 --- a/drivers/net/failsafe/failsafe_flow.c +++ b/drivers/net/failsafe/failsafe_flow.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2017 6WIND S.A. - * Copyright 2017 Mellanox. + * Copyright 2017 Mellanox Technologies, Ltd */ #include <sys/queue.h> @@ -174,7 +174,7 @@ fs_flow_flush(struct rte_eth_dev *dev, static int fs_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow, - enum rte_flow_action_type type, + const struct rte_flow_action *action, void *arg, struct rte_flow_error *error) { @@ -185,7 +185,7 @@ fs_flow_query(struct rte_eth_dev *dev, if (sdev != NULL) { int ret = rte_flow_query(PORT_ID(sdev), flow->flows[SUB_ID(sdev)], - type, arg, error); + action, arg, error); if ((ret = fs_err(sdev, ret))) { fs_unlock(dev, 0); diff --git a/drivers/net/failsafe/failsafe_intr.c b/drivers/net/failsafe/failsafe_intr.c index 6b7f9c1a..fc6ec37f 100644 --- a/drivers/net/failsafe/failsafe_intr.c +++ b/drivers/net/failsafe/failsafe_intr.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2018 Mellanox Technologies, Ltd. + * Copyright 2018 Mellanox Technologies, Ltd */ /** diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c index 057e435c..24e91c93 100644 --- a/drivers/net/failsafe/failsafe_ops.c +++ b/drivers/net/failsafe/failsafe_ops.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2017 6WIND S.A. - * Copyright 2017 Mellanox. + * Copyright 2017 Mellanox Technologies, Ltd */ #include <stdbool.h> @@ -13,6 +13,7 @@ #include <rte_malloc.h> #include <rte_flow.h> #include <rte_cycles.h> +#include <rte_ethdev.h> #include "failsafe_private.h" @@ -81,30 +82,22 @@ static struct rte_eth_dev_info default_infos = { DEV_TX_OFFLOAD_MULTI_SEGS | DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM, - .flow_type_rss_offloads = 0x0, + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_TCP_TSO, + .flow_type_rss_offloads = + ETH_RSS_IP | + ETH_RSS_UDP | + ETH_RSS_TCP, }; static int fs_dev_configure(struct rte_eth_dev *dev) { struct sub_device *sdev; - uint64_t supp_tx_offloads; - uint64_t tx_offloads; uint8_t i; int ret; fs_lock(dev, 0); - supp_tx_offloads = PRIV(dev)->infos.tx_offload_capa; - tx_offloads = dev->data->dev_conf.txmode.offloads; - if ((tx_offloads & supp_tx_offloads) != tx_offloads) { - rte_errno = ENOTSUP; - ERROR("Some Tx offloads are not supported, " - "requested 0x%" PRIx64 " supported 0x%" PRIx64, - tx_offloads, supp_tx_offloads); - fs_unlock(dev, 0); - return -rte_errno; - } FOREACH_SUBDEV(sdev, i, dev) { int rmv_interrupt = 0; int lsc_interrupt = 0; @@ -145,7 +138,7 @@ fs_dev_configure(struct rte_eth_dev *dev) fs_unlock(dev, 0); return ret; } - if (rmv_interrupt) { + if (rmv_interrupt && sdev->rmv_callback == 0) { ret = rte_eth_dev_callback_register(PORT_ID(sdev), RTE_ETH_EVENT_INTR_RMV, failsafe_eth_rmv_event_callback, @@ -153,9 +146,11 @@ fs_dev_configure(struct rte_eth_dev *dev) if (ret) WARN("Failed to register RMV callback for sub_device %d", SUB_ID(sdev)); + else + sdev->rmv_callback = 1; } dev->data->dev_conf.intr_conf.rmv = 0; - if (lsc_interrupt) { + if (lsc_interrupt && sdev->lsc_callback == 0) { ret = rte_eth_dev_callback_register(PORT_ID(sdev), RTE_ETH_EVENT_INTR_LSC, failsafe_eth_lsc_event_callback, @@ -163,6 +158,8 @@ fs_dev_configure(struct rte_eth_dev *dev) if (ret) WARN("Failed to register LSC callback for sub_device %d", SUB_ID(sdev)); + else + sdev->lsc_callback = 1; } dev->data->dev_conf.intr_conf.lsc = lsc_enabled; sdev->state = DEV_ACTIVE; @@ -289,6 +286,7 @@ fs_dev_close(struct rte_eth_dev *dev) PRIV(dev)->state = DEV_ACTIVE - 1; FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) { DEBUG("Closing sub_device %d", i); + failsafe_eth_dev_unregister_callbacks(sdev); rte_eth_dev_close(PORT_ID(sdev)); sdev->state = DEV_ACTIVE - 1; } @@ -296,25 +294,6 @@ fs_dev_close(struct rte_eth_dev *dev) fs_unlock(dev, 0); } -static bool -fs_rxq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads) -{ - uint64_t port_offloads; - uint64_t queue_supp_offloads; - uint64_t port_supp_offloads; - - port_offloads = dev->data->dev_conf.rxmode.offloads; - queue_supp_offloads = PRIV(dev)->infos.rx_queue_offload_capa; - port_supp_offloads = PRIV(dev)->infos.rx_offload_capa; - if ((offloads & (queue_supp_offloads | port_supp_offloads)) != - offloads) - return false; - /* Verify we have no conflict with port offloads */ - if ((port_offloads ^ offloads) & port_supp_offloads) - return false; - return true; -} - static void fs_rx_queue_release(void *queue) { @@ -367,19 +346,6 @@ fs_rx_queue_setup(struct rte_eth_dev *dev, fs_rx_queue_release(rxq); dev->data->rx_queues[rx_queue_id] = NULL; } - /* Verify application offloads are valid for our port and queue. */ - if (fs_rxq_offloads_valid(dev, rx_conf->offloads) == false) { - rte_errno = ENOTSUP; - ERROR("Rx queue offloads 0x%" PRIx64 - " don't match port offloads 0x%" PRIx64 - " or supported offloads 0x%" PRIx64, - rx_conf->offloads, - dev->data->dev_conf.rxmode.offloads, - PRIV(dev)->infos.rx_offload_capa | - PRIV(dev)->infos.rx_queue_offload_capa); - fs_unlock(dev, 0); - return -rte_errno; - } rxq = rte_zmalloc(NULL, sizeof(*rxq) + sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail, @@ -498,25 +464,6 @@ unlock: return rc; } -static bool -fs_txq_offloads_valid(struct rte_eth_dev *dev, uint64_t offloads) -{ - uint64_t port_offloads; - uint64_t queue_supp_offloads; - uint64_t port_supp_offloads; - - port_offloads = dev->data->dev_conf.txmode.offloads; - queue_supp_offloads = PRIV(dev)->infos.tx_queue_offload_capa; - port_supp_offloads = PRIV(dev)->infos.tx_offload_capa; - if ((offloads & (queue_supp_offloads | port_supp_offloads)) != - offloads) - return false; - /* Verify we have no conflict with port offloads */ - if ((port_offloads ^ offloads) & port_supp_offloads) - return false; - return true; -} - static void fs_tx_queue_release(void *queue) { @@ -556,24 +503,6 @@ fs_tx_queue_setup(struct rte_eth_dev *dev, fs_tx_queue_release(txq); dev->data->tx_queues[tx_queue_id] = NULL; } - /* - * Don't verify queue offloads for applications which - * use the old API. - */ - if (tx_conf != NULL && - (tx_conf->txq_flags & ETH_TXQ_FLAGS_IGNORE) && - fs_txq_offloads_valid(dev, tx_conf->offloads) == false) { - rte_errno = ENOTSUP; - ERROR("Tx queue offloads 0x%" PRIx64 - " don't match port offloads 0x%" PRIx64 - " or supported offloads 0x%" PRIx64, - tx_conf->offloads, - dev->data->dev_conf.txmode.offloads, - PRIV(dev)->infos.tx_offload_capa | - PRIV(dev)->infos.tx_queue_offload_capa); - fs_unlock(dev, 0); - return -rte_errno; - } txq = rte_zmalloc("ethdev TX queue", sizeof(*txq) + sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail, @@ -804,26 +733,29 @@ fs_dev_infos_get(struct rte_eth_dev *dev, } else { uint64_t rx_offload_capa; uint64_t rxq_offload_capa; + uint64_t rss_hf_offload_capa; rx_offload_capa = default_infos.rx_offload_capa; rxq_offload_capa = default_infos.rx_queue_offload_capa; + rss_hf_offload_capa = default_infos.flow_type_rss_offloads; FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_PROBED) { rte_eth_dev_info_get(PORT_ID(sdev), &PRIV(dev)->infos); rx_offload_capa &= PRIV(dev)->infos.rx_offload_capa; rxq_offload_capa &= PRIV(dev)->infos.rx_queue_offload_capa; + rss_hf_offload_capa &= + PRIV(dev)->infos.flow_type_rss_offloads; } sdev = TX_SUBDEV(dev); rte_eth_dev_info_get(PORT_ID(sdev), &PRIV(dev)->infos); PRIV(dev)->infos.rx_offload_capa = rx_offload_capa; PRIV(dev)->infos.rx_queue_offload_capa = rxq_offload_capa; + PRIV(dev)->infos.flow_type_rss_offloads = rss_hf_offload_capa; PRIV(dev)->infos.tx_offload_capa &= default_infos.tx_offload_capa; PRIV(dev)->infos.tx_queue_offload_capa &= default_infos.tx_queue_offload_capa; - PRIV(dev)->infos.flow_type_rss_offloads &= - default_infos.flow_type_rss_offloads; } rte_memcpy(infos, &PRIV(dev)->infos, sizeof(*infos)); } @@ -997,16 +929,52 @@ fs_mac_addr_add(struct rte_eth_dev *dev, return 0; } -static void +static int fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr) { struct sub_device *sdev; uint8_t i; + int ret; fs_lock(dev, 0); - FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) - rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr); + FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) { + ret = rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr); + ret = fs_err(sdev, ret); + if (ret) { + ERROR("Operation rte_eth_dev_mac_addr_set failed for sub_device %d with error %d", + i, ret); + fs_unlock(dev, 0); + return ret; + } + } + fs_unlock(dev, 0); + + return 0; +} + +static int +fs_rss_hash_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + struct sub_device *sdev; + uint8_t i; + int ret; + + fs_lock(dev, 0); + FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) { + ret = rte_eth_dev_rss_hash_update(PORT_ID(sdev), rss_conf); + ret = fs_err(sdev, ret); + if (ret) { + ERROR("Operation rte_eth_dev_rss_hash_update" + " failed for sub_device %d with error %d", + i, ret); + fs_unlock(dev, 0); + return ret; + } + } fs_unlock(dev, 0); + + return 0; } static int @@ -1068,5 +1036,6 @@ 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, + .rss_hash_update = fs_rss_hash_update, .filter_ctrl = fs_filter_ctrl, }; diff --git a/drivers/net/failsafe/failsafe_private.h b/drivers/net/failsafe/failsafe_private.h index 2d16ba4c..886af861 100644 --- a/drivers/net/failsafe/failsafe_private.h +++ b/drivers/net/failsafe/failsafe_private.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2017 6WIND S.A. - * Copyright 2017 Mellanox. + * Copyright 2017 Mellanox Technologies, Ltd */ #ifndef _RTE_ETH_FAILSAFE_PRIVATE_H_ @@ -119,6 +119,10 @@ struct sub_device { volatile unsigned int remove:1; /* flow isolation state */ int flow_isolated:1; + /* RMV callback registration state */ + unsigned int rmv_callback:1; + /* LSC callback registration state */ + unsigned int lsc_callback:1; }; struct fs_priv { @@ -211,6 +215,7 @@ int failsafe_eal_uninit(struct rte_eth_dev *dev); /* ETH_DEV */ int failsafe_eth_dev_state_sync(struct rte_eth_dev *dev); +void failsafe_eth_dev_unregister_callbacks(struct sub_device *sdev); void failsafe_dev_remove(struct rte_eth_dev *dev); void failsafe_stats_increment(struct rte_eth_stats *to, struct rte_eth_stats *from); @@ -220,6 +225,9 @@ int failsafe_eth_rmv_event_callback(uint16_t port_id, int failsafe_eth_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type event, void *cb_arg, void *out); +int failsafe_eth_new_event_callback(uint16_t port_id, + enum rte_eth_event_type event, + void *cb_arg, void *out); /* GLOBALS */ @@ -326,8 +334,12 @@ extern int mac_from_arg; #define FS_THREADID_FMT "lu" #endif -#define LOG__(level, m, ...) \ - RTE_LOG(level, PMD, "net_failsafe: " m "%c", __VA_ARGS__) +extern int failsafe_logtype; + +#define LOG__(l, m, ...) \ + rte_log(RTE_LOG_ ## l, failsafe_logtype, \ + "net_failsafe: " m "%c", __VA_ARGS__) + #define LOG_(level, ...) LOG__(level, __VA_ARGS__, '\n') #define DEBUG(...) LOG_(DEBUG, __VA_ARGS__) #define INFO(...) LOG_(INFO, __VA_ARGS__) diff --git a/drivers/net/failsafe/failsafe_rxtx.c b/drivers/net/failsafe/failsafe_rxtx.c index 363cf7ba..7bd0f963 100644 --- a/drivers/net/failsafe/failsafe_rxtx.c +++ b/drivers/net/failsafe/failsafe_rxtx.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2017 6WIND S.A. - * Copyright 2017 Mellanox. + * Copyright 2017 Mellanox Technologies, Ltd */ #include <rte_atomic.h> diff --git a/drivers/net/failsafe/meson.build b/drivers/net/failsafe/meson.build new file mode 100644 index 00000000..a249ff4a --- /dev/null +++ b/drivers/net/failsafe/meson.build @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Intel Corporation + +cflags += '-std=gnu99' +cflags += '-D_DEFAULT_SOURCE' +cflags += '-D_XOPEN_SOURCE=700' +cflags += '-pedantic' +if host_machine.system() == 'linux' + cflags += '-DLINUX' +else + cflags += '-DBSD' +endif + +allow_experimental_apis = true + +sources = files('failsafe_args.c', + 'failsafe.c', + 'failsafe_eal.c', + 'failsafe_ether.c', + 'failsafe_flow.c', + 'failsafe_intr.c', + 'failsafe_ops.c', + 'failsafe_rxtx.c') |