From 1bd9b61222f3a81ffe770fc00b70ded6e760c42b Mon Sep 17 00:00:00 2001 From: Christian Ehrhardt Date: Fri, 1 Jun 2018 09:09:08 +0200 Subject: New upstream version 18.05 Change-Id: Icd4170ddc4f63aeae5d0559490e5195b5349f9c2 Signed-off-by: Christian Ehrhardt --- drivers/net/bonding/Makefile | 1 + drivers/net/bonding/meson.build | 3 +- drivers/net/bonding/rte_eth_bond_8023ad.c | 126 ++++---- drivers/net/bonding/rte_eth_bond_alb.c | 4 +- drivers/net/bonding/rte_eth_bond_api.c | 79 ++++- drivers/net/bonding/rte_eth_bond_args.c | 11 +- drivers/net/bonding/rte_eth_bond_flow.c | 228 +++++++++++++++ drivers/net/bonding/rte_eth_bond_pmd.c | 414 ++++++++++++++++----------- drivers/net/bonding/rte_eth_bond_private.h | 32 ++- drivers/net/bonding/rte_pmd_bond_version.map | 1 + 10 files changed, 661 insertions(+), 238 deletions(-) create mode 100644 drivers/net/bonding/rte_eth_bond_flow.c (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile index 4a6633ed..acad16a1 100644 --- a/drivers/net/bonding/Makefile +++ b/drivers/net/bonding/Makefile @@ -27,6 +27,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_pmd.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_args.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_8023ad.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_alb.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_flow.c # # Export include files diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build index b90abc6d..602d2880 100644 --- a/drivers/net/bonding/meson.build +++ b/drivers/net/bonding/meson.build @@ -2,7 +2,8 @@ # Copyright(c) 2017 Intel Corporation name = 'bond' #, james bond :-) -sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', +version = 2 +sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', 'rte_eth_bond_flow.c', 'rte_eth_bond_args.c', 'rte_eth_bond_8023ad.c', 'rte_eth_bond_alb.c') deps += 'sched' # needed for rte_bitmap.h diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c index c452318f..f8cea4b6 100644 --- a/drivers/net/bonding/rte_eth_bond_8023ad.c +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c @@ -16,9 +16,12 @@ static void bond_mode_8023ad_ext_periodic_cb(void *arg); #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD -#define MODE4_DEBUG(fmt, ...) RTE_LOG(DEBUG, PMD, "%6u [Port %u: %s] " fmt, \ - bond_dbg_get_time_diff_ms(), slave_id, \ - __func__, ##__VA_ARGS__) + +#define MODE4_DEBUG(fmt, ...) \ + rte_log(RTE_LOG_DEBUG, bond_logtype, \ + "%6u [Port %u: %s] " fmt, \ + bond_dbg_get_time_diff_ms(), slave_id, \ + __func__, ##__VA_ARGS__) static uint64_t start_time; @@ -77,44 +80,46 @@ bond_print_lacp(struct lacpdu *l) if (p_len && p_state[p_len-1] == ' ') p_state[p_len-1] = '\0'; - RTE_LOG(DEBUG, PMD, "LACP: {\n"\ - " subtype= %02X\n"\ - " ver_num=%02X\n"\ - " actor={ tlv=%02X, len=%02X\n"\ - " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"\ - " state={ %s }\n"\ - " }\n"\ - " partner={ tlv=%02X, len=%02X\n"\ - " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"\ - " state={ %s }\n"\ - " }\n"\ - " collector={info=%02X, length=%02X, max_delay=%04X\n, " \ - "type_term=%02X, terminator_length = %02X}\n",\ - l->subtype,\ - l->version_number,\ - l->actor.tlv_type_info,\ - l->actor.info_length,\ - l->actor.port_params.system_priority,\ - a_address,\ - l->actor.port_params.key,\ - l->actor.port_params.port_priority,\ - l->actor.port_params.port_number,\ - a_state,\ - l->partner.tlv_type_info,\ - l->partner.info_length,\ - l->partner.port_params.system_priority,\ - p_address,\ - l->partner.port_params.key,\ - l->partner.port_params.port_priority,\ - l->partner.port_params.port_number,\ - p_state,\ - l->tlv_type_collector_info,\ - l->collector_info_length,\ - l->collector_max_delay,\ - l->tlv_type_terminator,\ - l->terminator_length); + RTE_BOND_LOG(DEBUG, + "LACP: {\n" + " subtype= %02X\n" + " ver_num=%02X\n" + " actor={ tlv=%02X, len=%02X\n" + " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n" + " state={ %s }\n" + " }\n" + " partner={ tlv=%02X, len=%02X\n" + " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n" + " state={ %s }\n" + " }\n" + " collector={info=%02X, length=%02X, max_delay=%04X\n, " + "type_term=%02X, terminator_length = %02X }", + l->subtype, + l->version_number, + l->actor.tlv_type_info, + l->actor.info_length, + l->actor.port_params.system_priority, + a_address, + l->actor.port_params.key, + l->actor.port_params.port_priority, + l->actor.port_params.port_number, + a_state, + l->partner.tlv_type_info, + l->partner.info_length, + l->partner.port_params.system_priority, + p_address, + l->partner.port_params.key, + l->partner.port_params.port_priority, + l->partner.port_params.port_number, + p_state, + l->tlv_type_collector_info, + l->collector_info_length, + l->collector_max_delay, + l->tlv_type_terminator, + l->terminator_length); } + #define BOND_PRINT_LACP(lacpdu) bond_print_lacp(lacpdu) #else #define BOND_PRINT_LACP(lacpdu) do { } while (0) @@ -200,31 +205,34 @@ show_warnings(uint16_t slave_id) rte_get_tsc_hz() / 1000); if (warnings & WRN_RX_QUEUE_FULL) { - RTE_LOG(DEBUG, PMD, - "Slave %u: failed to enqueue LACP packet into RX ring.\n" - "Receive and transmit functions must be invoked on bonded\n" - "interface at least 10 times per second or LACP will not\n" - "work correctly\n", slave_id); + RTE_BOND_LOG(DEBUG, + "Slave %u: failed to enqueue LACP packet into RX ring.\n" + "Receive and transmit functions must be invoked on bonded" + "interface at least 10 times per second or LACP will notwork correctly", + slave_id); } if (warnings & WRN_TX_QUEUE_FULL) { - RTE_LOG(DEBUG, PMD, - "Slave %u: failed to enqueue LACP packet into TX ring.\n" - "Receive and transmit functions must be invoked on bonded\n" - "interface at least 10 times per second or LACP will not\n" - "work correctly\n", slave_id); + RTE_BOND_LOG(DEBUG, + "Slave %u: failed to enqueue LACP packet into TX ring.\n" + "Receive and transmit functions must be invoked on bonded" + "interface at least 10 times per second or LACP will not work correctly", + slave_id); } if (warnings & WRN_RX_MARKER_TO_FAST) - RTE_LOG(INFO, PMD, "Slave %u: marker to early - ignoring.\n", slave_id); + RTE_BOND_LOG(INFO, "Slave %u: marker to early - ignoring.", + slave_id); if (warnings & WRN_UNKNOWN_SLOW_TYPE) { - RTE_LOG(INFO, PMD, - "Slave %u: ignoring unknown slow protocol frame type", slave_id); + RTE_BOND_LOG(INFO, + "Slave %u: ignoring unknown slow protocol frame type", + slave_id); } if (warnings & WRN_UNKNOWN_MARKER_TYPE) - RTE_LOG(INFO, PMD, "Slave %u: ignoring unknown marker type", slave_id); + RTE_BOND_LOG(INFO, "Slave %u: ignoring unknown marker type", + slave_id); if (warnings & WRN_NOT_LACP_CAPABLE) MODE4_DEBUG("Port %u is not LACP capable!\n", slave_id); @@ -507,8 +515,8 @@ mux_machine(struct bond_dev_private *internals, uint16_t slave_id) ACTOR_STATE_SET(port, DISTRIBUTING); SM_FLAG_SET(port, NTT); MODE4_DEBUG("COLLECTING -> DISTRIBUTING\n"); - RTE_LOG(INFO, PMD, - "Bond %u: slave id %u distributing started.\n", + RTE_BOND_LOG(INFO, + "Bond %u: slave id %u distributing started.", internals->port_id, slave_id); } } else { @@ -518,8 +526,8 @@ mux_machine(struct bond_dev_private *internals, uint16_t slave_id) ACTOR_STATE_CLR(port, DISTRIBUTING); SM_FLAG_SET(port, NTT); MODE4_DEBUG("DISTRIBUTING -> COLLECTING\n"); - RTE_LOG(INFO, PMD, - "Bond %u: slave id %u distributing stopped.\n", + RTE_BOND_LOG(INFO, + "Bond %u: slave id %u distributing stopped.", internals->port_id, slave_id); } } @@ -557,7 +565,7 @@ tx_machine(struct bond_dev_private *internals, uint16_t slave_id) lacp_pkt = rte_pktmbuf_alloc(port->mbuf_pool); if (lacp_pkt == NULL) { - RTE_LOG(ERR, PMD, "Failed to allocate LACP packet from pool\n"); + RTE_BOND_LOG(ERR, "Failed to allocate LACP packet from pool"); return; } @@ -1337,7 +1345,7 @@ bond_8023ad_setup_validate(uint16_t port_id, conf->tx_period_ms == 0 || conf->rx_marker_period_ms == 0 || conf->update_timeout_ms == 0) { - RTE_LOG(ERR, PMD, "given mode 4 configuration is invalid\n"); + RTE_BOND_LOG(ERR, "given mode 4 configuration is invalid"); return -EINVAL; } } diff --git a/drivers/net/bonding/rte_eth_bond_alb.c b/drivers/net/bonding/rte_eth_bond_alb.c index 3f9945b3..c3891c7e 100644 --- a/drivers/net/bonding/rte_eth_bond_alb.c +++ b/drivers/net/bonding/rte_eth_bond_alb.c @@ -60,8 +60,8 @@ bond_mode_alb_enable(struct rte_eth_dev *bond_dev) 0, data_size, socket_id); if (internals->mode6.mempool == NULL) { - RTE_LOG(ERR, PMD, "%s: Failed to initialize ALB mempool.\n", - bond_dev->device->name); + RTE_BOND_LOG(ERR, "%s: Failed to initialize ALB mempool.\n", + bond_dev->device->name); goto mempool_alloc_error; } } diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c index f854b737..d558df8b 100644 --- a/drivers/net/bonding/rte_eth_bond_api.c +++ b/drivers/net/bonding/rte_eth_bond_api.c @@ -194,7 +194,8 @@ slave_vlan_filter_set(uint16_t bonded_port_id, uint16_t slave_port_id) uint16_t first; bonded_eth_dev = &rte_eth_devices[bonded_port_id]; - if (bonded_eth_dev->data->dev_conf.rxmode.hw_vlan_filter == 0) + if ((bonded_eth_dev->data->dev_conf.rxmode.offloads & + DEV_RX_OFFLOAD_VLAN_FILTER) == 0) return 0; internals = bonded_eth_dev->data->dev_private; @@ -211,9 +212,12 @@ slave_vlan_filter_set(uint16_t bonded_port_id, uint16_t slave_port_id) for (i = 0, mask = 1; i < RTE_BITMAP_SLAB_BIT_SIZE; i ++, mask <<= 1) { - if (unlikely(slab & mask)) + if (unlikely(slab & mask)) { + uint16_t vlan_id = pos + i; + res = rte_eth_dev_vlan_filter(slave_port_id, - (uint16_t)pos, 1); + vlan_id, 1); + } } found = rte_bitmap_scan(internals->vlan_filter_bmp, &pos, &slab); @@ -222,6 +226,49 @@ slave_vlan_filter_set(uint16_t bonded_port_id, uint16_t slave_port_id) return res; } +static int +slave_rte_flow_prepare(uint16_t slave_id, struct bond_dev_private *internals) +{ + struct rte_flow *flow; + struct rte_flow_error ferror; + uint16_t slave_port_id = internals->slaves[slave_id].port_id; + + if (internals->flow_isolated_valid != 0) { + rte_eth_dev_stop(slave_port_id); + if (rte_flow_isolate(slave_port_id, internals->flow_isolated, + &ferror)) { + RTE_BOND_LOG(ERR, "rte_flow_isolate failed for slave" + " %d: %s", slave_id, ferror.message ? + ferror.message : "(no stated reason)"); + return -1; + } + } + TAILQ_FOREACH(flow, &internals->flow_list, next) { + flow->flows[slave_id] = rte_flow_create(slave_port_id, + &flow->fd->attr, + flow->fd->items, + flow->fd->actions, + &ferror); + if (flow->flows[slave_id] == NULL) { + RTE_BOND_LOG(ERR, "Cannot create flow for slave" + " %d: %s", slave_id, + ferror.message ? ferror.message : + "(no stated reason)"); + /* Destroy successful bond flows from the slave */ + TAILQ_FOREACH(flow, &internals->flow_list, next) { + if (flow->flows[slave_id] != NULL) { + rte_flow_destroy(slave_port_id, + flow->flows[slave_id], + &ferror); + flow->flows[slave_id] = NULL; + } + } + return -1; + } + } + return 0; +} + static int __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id) { @@ -284,6 +331,8 @@ __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id) /* Take the first dev's offload capabilities */ internals->rx_offload_capa = dev_info.rx_offload_capa; internals->tx_offload_capa = dev_info.tx_offload_capa; + internals->rx_queue_offload_capa = dev_info.rx_queue_offload_capa; + internals->tx_queue_offload_capa = dev_info.tx_queue_offload_capa; internals->flow_type_rss_offloads = dev_info.flow_type_rss_offloads; /* Inherit first slave's max rx packet size */ @@ -292,6 +341,8 @@ __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id) } else { internals->rx_offload_capa &= dev_info.rx_offload_capa; internals->tx_offload_capa &= dev_info.tx_offload_capa; + internals->rx_queue_offload_capa &= dev_info.rx_queue_offload_capa; + internals->tx_queue_offload_capa &= dev_info.tx_queue_offload_capa; internals->flow_type_rss_offloads &= dev_info.flow_type_rss_offloads; if (link_properties_valid(bonded_eth_dev, @@ -316,6 +367,12 @@ __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id) bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf &= internals->flow_type_rss_offloads; + if (slave_rte_flow_prepare(internals->slave_count, internals) != 0) { + RTE_BOND_LOG(ERR, "Failed to prepare new slave flows: port=%d", + slave_port_id); + return -1; + } + internals->slave_count++; if (bonded_eth_dev->data->dev_started) { @@ -393,6 +450,8 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, struct rte_eth_dev *bonded_eth_dev; struct bond_dev_private *internals; struct rte_eth_dev *slave_eth_dev; + struct rte_flow_error flow_error; + struct rte_flow *flow; int i, slave_idx; bonded_eth_dev = &rte_eth_devices[bonded_port_id]; @@ -432,6 +491,18 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, rte_eth_dev_default_mac_addr_set(slave_port_id, &(internals->slaves[slave_idx].persisted_mac_addr)); + /* + * Remove bond device flows from slave device. + * Note: don't restore flow isolate mode. + */ + TAILQ_FOREACH(flow, &internals->flow_list, next) { + if (flow->flows[slave_idx] != NULL) { + rte_flow_destroy(slave_port_id, flow->flows[slave_idx], + &flow_error); + flow->flows[slave_idx] = NULL; + } + } + slave_eth_dev = &rte_eth_devices[slave_port_id]; slave_remove(internals, slave_eth_dev); slave_eth_dev->data->dev_flags &= (~RTE_ETH_DEV_BONDED_SLAVE); @@ -458,6 +529,8 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, if (internals->slave_count == 0) { internals->rx_offload_capa = 0; internals->tx_offload_capa = 0; + internals->rx_queue_offload_capa = 0; + internals->tx_queue_offload_capa = 0; internals->flow_type_rss_offloads = ETH_RSS_PROTO_MASK; internals->reta_size = 0; internals->candidate_max_rx_pktlen = 0; diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c index 27d3101b..b60fde6a 100644 --- a/drivers/net/bonding/rte_eth_bond_args.c +++ b/drivers/net/bonding/rte_eth_bond_args.c @@ -32,7 +32,7 @@ find_port_id_by_pci_addr(const struct rte_pci_addr *pci_addr) struct rte_pci_addr *eth_pci_addr; unsigned i; - for (i = 0; i < rte_eth_dev_count(); i++) { + RTE_ETH_FOREACH_DEV(i) { pci_dev = RTE_ETH_DEV_TO_PCI(&rte_eth_devices[i]); eth_pci_addr = &pci_dev->addr; @@ -50,7 +50,7 @@ find_port_id_by_dev_name(const char *name) { unsigned i; - for (i = 0; i < rte_eth_dev_count(); i++) { + RTE_ETH_FOREACH_DEV(i) { if (rte_eth_devices[i].data == NULL) continue; @@ -92,7 +92,7 @@ parse_port_id(const char *port_str) if (pci_bus->parse(port_str, &dev_addr) == 0) { dev = pci_bus->find_device(NULL, bond_pci_addr_cmp, &dev_addr); if (dev == NULL) { - RTE_LOG(ERR, PMD, "unable to find PCI device\n"); + RTE_BOND_LOG(ERR, "unable to find PCI device"); return -1; } port_id = find_port_id_by_pci_addr(&dev_addr); @@ -134,7 +134,8 @@ bond_ethdev_parse_slave_port_kvarg(const char *key, if (strcmp(key, PMD_BOND_SLAVE_PORT_KVARG) == 0) { int port_id = parse_port_id(value); if (port_id < 0) { - RTE_BOND_LOG(ERR, "Invalid slave port value (%s) specified", value); + RTE_BOND_LOG(ERR, "Invalid slave port value (%s) specified", + value); return -1; } else slave_ports->slaves[slave_ports->slave_count++] = @@ -244,7 +245,7 @@ bond_ethdev_parse_primary_slave_port_id_kvarg(const char *key __rte_unused, if (primary_slave_port_id < 0) return -1; - *(uint8_t *)extra_args = (uint8_t)primary_slave_port_id; + *(uint16_t *)extra_args = (uint16_t)primary_slave_port_id; return 0; } diff --git a/drivers/net/bonding/rte_eth_bond_flow.c b/drivers/net/bonding/rte_eth_bond_flow.c new file mode 100644 index 00000000..31e4bcae --- /dev/null +++ b/drivers/net/bonding/rte_eth_bond_flow.c @@ -0,0 +1,228 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#include + +#include +#include +#include + +#include "rte_eth_bond_private.h" + +static struct rte_flow * +bond_flow_alloc(int numa_node, const struct rte_flow_attr *attr, + const struct rte_flow_item *items, + const struct rte_flow_action *actions) +{ + struct rte_flow *flow; + size_t fdsz; + + fdsz = rte_flow_copy(NULL, 0, attr, items, actions); + flow = rte_zmalloc_socket(NULL, sizeof(struct rte_flow) + fdsz, + RTE_CACHE_LINE_SIZE, numa_node); + if (unlikely(flow == NULL)) { + RTE_BOND_LOG(ERR, "Could not allocate new flow"); + return NULL; + } + flow->fd = (void *)((uintptr_t)flow + sizeof(*flow)); + if (unlikely(rte_flow_copy(flow->fd, fdsz, attr, items, actions) != + fdsz)) { + RTE_BOND_LOG(ERR, "Failed to copy flow description"); + rte_free(flow); + return NULL; + } + return flow; +} + +static void +bond_flow_release(struct rte_flow **flow) +{ + rte_free(*flow); + *flow = NULL; +} + +static int +bond_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + const struct rte_flow_item patterns[], + const struct rte_flow_action actions[], + struct rte_flow_error *err) +{ + struct bond_dev_private *internals = dev->data->dev_private; + int i; + int ret; + + for (i = 0; i < internals->slave_count; i++) { + ret = rte_flow_validate(internals->slaves[i].port_id, attr, + patterns, actions, err); + if (ret) { + RTE_BOND_LOG(ERR, "Operation rte_flow_validate failed" + " for slave %d with error %d", i, ret); + return ret; + } + } + return 0; +} + +static struct rte_flow * +bond_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + const struct rte_flow_item patterns[], + const struct rte_flow_action actions[], + struct rte_flow_error *err) +{ + struct bond_dev_private *internals = dev->data->dev_private; + struct rte_flow *flow; + int i; + + flow = bond_flow_alloc(dev->data->numa_node, attr, patterns, actions); + if (unlikely(flow == NULL)) { + rte_flow_error_set(err, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, rte_strerror(ENOMEM)); + return NULL; + } + for (i = 0; i < internals->slave_count; i++) { + flow->flows[i] = rte_flow_create(internals->slaves[i].port_id, + attr, patterns, actions, err); + if (unlikely(flow->flows[i] == NULL)) { + RTE_BOND_LOG(ERR, "Failed to create flow on slave %d", + i); + goto err; + } + } + TAILQ_INSERT_TAIL(&internals->flow_list, flow, next); + return flow; +err: + /* Destroy all slaves flows. */ + for (i = 0; i < internals->slave_count; i++) { + if (flow->flows[i] != NULL) + rte_flow_destroy(internals->slaves[i].port_id, + flow->flows[i], err); + } + bond_flow_release(&flow); + return NULL; +} + +static int +bond_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, + struct rte_flow_error *err) +{ + struct bond_dev_private *internals = dev->data->dev_private; + int i; + int ret = 0; + + for (i = 0; i < internals->slave_count; i++) { + int lret; + + if (unlikely(flow->flows[i] == NULL)) + continue; + lret = rte_flow_destroy(internals->slaves[i].port_id, + flow->flows[i], err); + if (unlikely(lret != 0)) { + RTE_BOND_LOG(ERR, "Failed to destroy flow on slave %d:" + " %d", i, lret); + ret = lret; + } + } + TAILQ_REMOVE(&internals->flow_list, flow, next); + bond_flow_release(&flow); + return ret; +} + +static int +bond_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *err) +{ + struct bond_dev_private *internals = dev->data->dev_private; + struct rte_flow *flow; + void *tmp; + int ret = 0; + int lret; + + /* Destroy all bond flows from its slaves instead of flushing them to + * keep the LACP flow or any other external flows. + */ + TAILQ_FOREACH_SAFE(flow, &internals->flow_list, next, tmp) { + lret = bond_flow_destroy(dev, flow, err); + if (unlikely(lret != 0)) + ret = lret; + } + if (unlikely(ret != 0)) + RTE_BOND_LOG(ERR, "Failed to flush flow in all slaves"); + return ret; +} + +static int +bond_flow_query_count(struct rte_eth_dev *dev, struct rte_flow *flow, + const struct rte_flow_action *action, + struct rte_flow_query_count *count, + struct rte_flow_error *err) +{ + struct bond_dev_private *internals = dev->data->dev_private; + struct rte_flow_query_count slave_count; + int i; + int ret; + + count->bytes = 0; + count->hits = 0; + rte_memcpy(&slave_count, count, sizeof(slave_count)); + for (i = 0; i < internals->slave_count; i++) { + ret = rte_flow_query(internals->slaves[i].port_id, + flow->flows[i], action, + &slave_count, err); + if (unlikely(ret != 0)) { + RTE_BOND_LOG(ERR, "Failed to query flow on" + " slave %d: %d", i, ret); + return ret; + } + count->bytes += slave_count.bytes; + count->hits += slave_count.hits; + slave_count.bytes = 0; + slave_count.hits = 0; + } + return 0; +} + +static int +bond_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow, + const struct rte_flow_action *action, void *arg, + struct rte_flow_error *err) +{ + switch (action->type) { + case RTE_FLOW_ACTION_TYPE_COUNT: + return bond_flow_query_count(dev, flow, action, arg, err); + default: + return rte_flow_error_set(err, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, arg, + rte_strerror(ENOTSUP)); + } +} + +static int +bond_flow_isolate(struct rte_eth_dev *dev, int set, + struct rte_flow_error *err) +{ + struct bond_dev_private *internals = dev->data->dev_private; + int i; + int ret; + + for (i = 0; i < internals->slave_count; i++) { + ret = rte_flow_isolate(internals->slaves[i].port_id, set, err); + if (unlikely(ret != 0)) { + RTE_BOND_LOG(ERR, "Operation rte_flow_isolate failed" + " for slave %d with error %d", i, ret); + internals->flow_isolated_valid = 0; + return ret; + } + } + internals->flow_isolated = set; + internals->flow_isolated_valid = 1; + return 0; +} + +const struct rte_flow_ops bond_flow_ops = { + .validate = bond_flow_validate, + .create = bond_flow_create, + .destroy = bond_flow_destroy, + .flush = bond_flow_flush, + .query = bond_flow_query, + .isolate = bond_flow_isolate, +}; diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c index c34c3251..02d94b1b 100644 --- a/drivers/net/bonding/rte_eth_bond_pmd.c +++ b/drivers/net/bonding/rte_eth_bond_pmd.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "rte_eth_bond.h" #include "rte_eth_bond_private.h" @@ -570,34 +571,21 @@ update_client_stats(uint32_t addr, uint16_t port, uint32_t *TXorRXindicator) } #ifdef RTE_LIBRTE_BOND_DEBUG_ALB -#define MODE6_DEBUG(info, src_ip, dst_ip, eth_h, arp_op, port, burstnumber) \ - RTE_LOG(DEBUG, PMD, \ - "%s " \ - "port:%d " \ - "SrcMAC:%02X:%02X:%02X:%02X:%02X:%02X " \ - "SrcIP:%s " \ - "DstMAC:%02X:%02X:%02X:%02X:%02X:%02X " \ - "DstIP:%s " \ - "%s " \ - "%d\n", \ - info, \ - port, \ - eth_h->s_addr.addr_bytes[0], \ - eth_h->s_addr.addr_bytes[1], \ - eth_h->s_addr.addr_bytes[2], \ - eth_h->s_addr.addr_bytes[3], \ - eth_h->s_addr.addr_bytes[4], \ - eth_h->s_addr.addr_bytes[5], \ - src_ip, \ - eth_h->d_addr.addr_bytes[0], \ - eth_h->d_addr.addr_bytes[1], \ - eth_h->d_addr.addr_bytes[2], \ - eth_h->d_addr.addr_bytes[3], \ - eth_h->d_addr.addr_bytes[4], \ - eth_h->d_addr.addr_bytes[5], \ - dst_ip, \ - arp_op, \ - ++burstnumber) +#define MODE6_DEBUG(info, src_ip, dst_ip, eth_h, arp_op, port, burstnumber) \ + rte_log(RTE_LOG_DEBUG, bond_logtype, \ + "%s port:%d SrcMAC:%02X:%02X:%02X:%02X:%02X:%02X SrcIP:%s " \ + "DstMAC:%02X:%02X:%02X:%02X:%02X:%02X DstIP:%s %s %d\n", \ + info, \ + port, \ + eth_h->s_addr.addr_bytes[0], eth_h->s_addr.addr_bytes[1], \ + eth_h->s_addr.addr_bytes[2], eth_h->s_addr.addr_bytes[3], \ + eth_h->s_addr.addr_bytes[4], eth_h->s_addr.addr_bytes[5], \ + src_ip, \ + eth_h->d_addr.addr_bytes[0], eth_h->d_addr.addr_bytes[1], \ + eth_h->d_addr.addr_bytes[2], eth_h->d_addr.addr_bytes[3], \ + eth_h->d_addr.addr_bytes[4], eth_h->d_addr.addr_bytes[5], \ + dst_ip, \ + arp_op, ++burstnumber) #endif static void @@ -617,7 +605,7 @@ mode6_debug(const char __attribute__((unused)) *info, struct ether_hdr *eth_h, uint16_t offset = get_vlan_offset(eth_h, ðer_type); #ifdef RTE_LIBRTE_BOND_DEBUG_ALB - snprintf(buf, 16, "%s", info); + strlcpy(buf, info, 16); #endif if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) { @@ -1138,7 +1126,8 @@ bond_ethdev_tx_burst_alb(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) /* Allocate new packet to send ARP update on current slave */ upd_pkt = rte_pktmbuf_alloc(internals->mode6.mempool); if (upd_pkt == NULL) { - RTE_LOG(ERR, PMD, "Failed to allocate ARP packet from pool\n"); + RTE_BOND_LOG(ERR, + "Failed to allocate ARP packet from pool"); continue; } pkt_size = sizeof(struct ether_hdr) + sizeof(struct arp_hdr) @@ -1560,12 +1549,12 @@ mac_address_get(struct rte_eth_dev *eth_dev, struct ether_addr *dst_mac_addr) struct ether_addr *mac_addr; if (eth_dev == NULL) { - RTE_LOG(ERR, PMD, "%s: NULL pointer eth_dev specified\n", __func__); + RTE_BOND_LOG(ERR, "NULL pointer eth_dev specified"); return -1; } if (dst_mac_addr == NULL) { - RTE_LOG(ERR, PMD, "%s: NULL pointer MAC specified\n", __func__); + RTE_BOND_LOG(ERR, "NULL pointer MAC specified"); return -1; } @@ -1686,9 +1675,9 @@ bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, int mode) if (internals->mode4.dedicated_queues.enabled == 0) { eth_dev->rx_pkt_burst = bond_ethdev_rx_burst_8023ad; eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_8023ad; - RTE_LOG(WARNING, PMD, + RTE_BOND_LOG(WARNING, "Using mode 4, it is necessary to do TX burst " - "and RX burst at least every 100ms.\n"); + "and RX burst at least every 100ms."); } else { /* Use flow director's optimization */ eth_dev->rx_pkt_burst = @@ -1818,8 +1807,13 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev, bonded_eth_dev->data->dev_conf.rxmode.mq_mode; } - slave_eth_dev->data->dev_conf.rxmode.hw_vlan_filter = - bonded_eth_dev->data->dev_conf.rxmode.hw_vlan_filter; + if (bonded_eth_dev->data->dev_conf.rxmode.offloads & + DEV_RX_OFFLOAD_VLAN_FILTER) + slave_eth_dev->data->dev_conf.rxmode.offloads |= + DEV_RX_OFFLOAD_VLAN_FILTER; + else + slave_eth_dev->data->dev_conf.rxmode.offloads &= + ~DEV_RX_OFFLOAD_VLAN_FILTER; nb_rx_queues = bonded_eth_dev->data->nb_rx_queues; nb_tx_queues = bonded_eth_dev->data->nb_tx_queues; @@ -1831,12 +1825,20 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev, } } + errval = rte_eth_dev_set_mtu(slave_eth_dev->data->port_id, + bonded_eth_dev->data->mtu); + if (errval != 0 && errval != -ENOTSUP) { + RTE_BOND_LOG(ERR, "rte_eth_dev_set_mtu: port %u, err (%d)", + slave_eth_dev->data->port_id, errval); + return errval; + } + /* Configure device */ errval = rte_eth_dev_configure(slave_eth_dev->data->port_id, nb_rx_queues, nb_tx_queues, &(slave_eth_dev->data->dev_conf)); if (errval != 0) { - RTE_BOND_LOG(ERR, "Cannot configure slave device: port %u , err (%d)", + RTE_BOND_LOG(ERR, "Cannot configure slave device: port %u, err (%d)", slave_eth_dev->data->port_id, errval); return errval; } @@ -1918,10 +1920,10 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev, &internals->reta_conf[0], internals->slaves[i].reta_size); if (errval != 0) { - RTE_LOG(WARNING, PMD, - "rte_eth_dev_rss_reta_update on slave port %d fails (err %d)." - " RSS Configuration for bonding may be inconsistent.\n", - slave_eth_dev->data->port_id, errval); + RTE_BOND_LOG(WARNING, + "rte_eth_dev_rss_reta_update on slave port %d fails (err %d)." + " RSS Configuration for bonding may be inconsistent.", + slave_eth_dev->data->port_id, errval); } break; } @@ -1950,10 +1952,19 @@ slave_remove(struct bond_dev_private *internals, slave_eth_dev->data->port_id) break; - if (i < (internals->slave_count - 1)) + if (i < (internals->slave_count - 1)) { + struct rte_flow *flow; + memmove(&internals->slaves[i], &internals->slaves[i + 1], sizeof(internals->slaves[0]) * (internals->slave_count - i - 1)); + TAILQ_FOREACH(flow, &internals->flow_list, next) { + memmove(&flow->flows[i], &flow->flows[i + 1], + sizeof(flow->flows[0]) * + (internals->slave_count - i - 1)); + flow->flows[internals->slave_count - 1] = NULL; + } + } internals->slave_count--; @@ -2026,7 +2037,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev) if (internals->slave_count == 0) { RTE_BOND_LOG(ERR, "Cannot start port since there are no slave devices"); - return -1; + goto out_err; } if (internals->user_defined_mac == 0) { @@ -2037,18 +2048,18 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev) new_mac_addr = &internals->slaves[i].persisted_mac_addr; if (new_mac_addr == NULL) - return -1; + goto out_err; if (mac_address_set(eth_dev, new_mac_addr) != 0) { RTE_BOND_LOG(ERR, "bonded port (%d) failed to update MAC address", eth_dev->data->port_id); - return -1; + goto out_err; } } /* Update all slave devices MACs*/ if (mac_address_slaves_update(eth_dev) != 0) - return -1; + goto out_err; /* If bonded device is configure in promiscuous mode then re-apply config */ if (internals->promiscuous_en) @@ -2073,7 +2084,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev) "bonded port (%d) failed to reconfigure slave device (%d)", eth_dev->data->port_id, internals->slaves[i].port_id); - return -1; + goto out_err; } /* We will need to poll for link status if any slave doesn't * support interrupts @@ -2081,6 +2092,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev) if (internals->slaves[i].link_status_poll_enabled) internals->link_status_polling_enabled = 1; } + /* start polling if needed */ if (internals->link_status_polling_enabled) { rte_eal_alarm_set( @@ -2100,6 +2112,10 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev) bond_tlb_enable(internals); return 0; + +out_err: + eth_dev->data->dev_started = 0; + return -1; } static void @@ -2172,20 +2188,22 @@ bond_ethdev_close(struct rte_eth_dev *dev) struct bond_dev_private *internals = dev->data->dev_private; uint8_t bond_port_id = internals->port_id; int skipped = 0; + struct rte_flow_error ferror; - RTE_LOG(INFO, EAL, "Closing bonded device %s\n", dev->device->name); + RTE_BOND_LOG(INFO, "Closing bonded device %s", dev->device->name); while (internals->slave_count != skipped) { uint16_t port_id = internals->slaves[skipped].port_id; rte_eth_dev_stop(port_id); if (rte_eth_bond_slave_remove(bond_port_id, port_id) != 0) { - RTE_LOG(ERR, EAL, - "Failed to remove port %d from bonded device " - "%s\n", port_id, dev->device->name); + RTE_BOND_LOG(ERR, + "Failed to remove port %d from bonded device %s", + port_id, dev->device->name); skipped++; } } + bond_flow_ops.flush(dev, &ferror); bond_ethdev_free_queues(dev); rte_bitmap_reset(internals->vlan_filter_bmp); } @@ -2244,6 +2262,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->rx_offload_capa = internals->rx_offload_capa; dev_info->tx_offload_capa = internals->tx_offload_capa; + dev_info->rx_queue_offload_capa = internals->rx_queue_offload_capa; + dev_info->tx_queue_offload_capa = internals->tx_queue_offload_capa; dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads; dev_info->reta_size = internals->reta_size; @@ -2269,9 +2289,9 @@ bond_ethdev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) res = rte_eth_dev_vlan_filter(port_id, vlan_id, on); if (res == ENOTSUP) - RTE_LOG(WARNING, PMD, - "Setting VLAN filter on slave port %u not supported.\n", - port_id); + RTE_BOND_LOG(WARNING, + "Setting VLAN filter on slave port %u not supported.", + port_id); } rte_spinlock_unlock(&internals->lock); @@ -2633,14 +2653,21 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, if (!valid_slave) return rc; + /* Synchronize lsc callback parallel calls either by real link event + * from the slaves PMDs or by the bonding PMD itself. + */ + rte_spinlock_lock(&internals->lsc_lock); + /* Search for port in active port list */ active_pos = find_slave_by_id(internals->active_slaves, internals->active_slave_count, port_id); rte_eth_link_get_nowait(port_id, &link); if (link.link_status) { - if (active_pos < internals->active_slave_count) + if (active_pos < internals->active_slave_count) { + rte_spinlock_unlock(&internals->lsc_lock); return rc; + } /* if no active slave ports then set this port to be primary port */ if (internals->active_slave_count < 1) { @@ -2659,8 +2686,10 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, internals->primary_port == port_id) bond_ethdev_primary_set(internals, port_id); } else { - if (active_pos == internals->active_slave_count) + if (active_pos == internals->active_slave_count) { + rte_spinlock_unlock(&internals->lsc_lock); return rc; + } /* Remove from active slave list */ deactivate_slave(bonded_eth_dev, port_id); @@ -2713,6 +2742,9 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, NULL); } } + + rte_spinlock_unlock(&internals->lsc_lock); + return 0; } @@ -2851,11 +2883,26 @@ bond_ethdev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return 0; } -static void +static int bond_ethdev_mac_address_set(struct rte_eth_dev *dev, struct ether_addr *addr) { - if (mac_address_set(dev, addr)) + if (mac_address_set(dev, addr)) { RTE_BOND_LOG(ERR, "Failed to update MAC address"); + return -EINVAL; + } + + return 0; +} + +static int +bond_filter_ctrl(struct rte_eth_dev *dev __rte_unused, + enum rte_filter_type type, enum rte_filter_op op, void *arg) +{ + if (type == RTE_ETH_FILTER_GENERIC && op == RTE_ETH_FILTER_GET) { + *(const void **)arg = &bond_flow_ops; + return 0; + } + return -ENOTSUP; } const struct eth_dev_ops default_dev_ops = { @@ -2879,7 +2926,8 @@ const struct eth_dev_ops default_dev_ops = { .rss_hash_update = bond_ethdev_rss_hash_update, .rss_hash_conf_get = bond_ethdev_rss_hash_conf_get, .mtu_set = bond_ethdev_mtu_set, - .mac_addr_set = bond_ethdev_mac_address_set + .mac_addr_set = bond_ethdev_mac_address_set, + .filter_ctrl = bond_filter_ctrl }; static int @@ -2917,6 +2965,7 @@ bond_alloc(struct rte_vdev_device *dev, uint8_t mode) eth_dev->data->dev_flags = RTE_ETH_DEV_INTR_LSC; rte_spinlock_init(&internals->lock); + rte_spinlock_init(&internals->lsc_lock); internals->port_id = eth_dev->data->port_id; internals->mode = BONDING_MODE_INVALID; @@ -2936,6 +2985,8 @@ bond_alloc(struct rte_vdev_device *dev, uint8_t mode) internals->active_slave_count = 0; internals->rx_offload_capa = 0; internals->tx_offload_capa = 0; + internals->rx_queue_offload_capa = 0; + internals->tx_queue_offload_capa = 0; internals->candidate_max_rx_pktlen = 0; internals->max_rx_pktlen = 0; @@ -2945,10 +2996,13 @@ bond_alloc(struct rte_vdev_device *dev, uint8_t mode) memset(internals->active_slaves, 0, sizeof(internals->active_slaves)); memset(internals->slaves, 0, sizeof(internals->slaves)); + TAILQ_INIT(&internals->flow_list); + internals->flow_isolated_valid = 0; + /* Set mode 4 default configuration */ bond_mode_8023ad_setup(eth_dev, NULL); if (bond_ethdev_mode_set(eth_dev, mode)) { - RTE_BOND_LOG(ERR, "Failed to set bonded device %d mode too %d", + RTE_BOND_LOG(ERR, "Failed to set bonded device %d mode to %d", eth_dev->data->port_id, mode); goto err; } @@ -2959,7 +3013,7 @@ bond_alloc(struct rte_vdev_device *dev, uint8_t mode) RTE_CACHE_LINE_SIZE); if (internals->vlan_filter_bmpmem == NULL) { RTE_BOND_LOG(ERR, - "Failed to allocate vlan bitmap for bonded device %u\n", + "Failed to allocate vlan bitmap for bonded device %u", eth_dev->data->port_id); goto err; } @@ -2968,7 +3022,7 @@ bond_alloc(struct rte_vdev_device *dev, uint8_t mode) internals->vlan_filter_bmpmem, vlan_filter_bmp_size); if (internals->vlan_filter_bmp == NULL) { RTE_BOND_LOG(ERR, - "Failed to init vlan bitmap for bonded device %u\n", + "Failed to init vlan bitmap for bonded device %u", eth_dev->data->port_id); rte_free(internals->vlan_filter_bmpmem); goto err; @@ -2994,12 +3048,26 @@ bond_probe(struct rte_vdev_device *dev) uint8_t bonding_mode, socket_id/*, agg_mode*/; int arg_count, port_id; uint8_t agg_mode; + struct rte_eth_dev *eth_dev; if (!dev) return -EINVAL; name = rte_vdev_device_name(dev); - RTE_LOG(INFO, EAL, "Initializing pmd_bond for %s\n", name); + RTE_BOND_LOG(INFO, "Initializing pmd_bond for %s", name); + + if (rte_eal_process_type() == RTE_PROC_SECONDARY && + strlen(rte_vdev_device_args(dev)) == 0) { + eth_dev = rte_eth_dev_attach_secondary(name); + if (!eth_dev) { + RTE_BOND_LOG(ERR, "Failed to probe %s", name); + return -1; + } + /* TODO: request info from primary to set up Rx and Tx */ + eth_dev->dev_ops = &default_dev_ops; + rte_eth_dev_probing_finish(eth_dev); + return 0; + } kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), pmd_bond_init_valid_arguments); @@ -3011,13 +3079,13 @@ bond_probe(struct rte_vdev_device *dev) if (rte_kvargs_process(kvlist, PMD_BOND_MODE_KVARG, &bond_ethdev_parse_slave_mode_kvarg, &bonding_mode) != 0) { - RTE_LOG(ERR, EAL, "Invalid mode for bonded device %s\n", + RTE_BOND_LOG(ERR, "Invalid mode for bonded device %s", name); goto parse_error; } } else { - RTE_LOG(ERR, EAL, "Mode must be specified only once for bonded " - "device %s\n", name); + RTE_BOND_LOG(ERR, "Mode must be specified only once for bonded " + "device %s", name); goto parse_error; } @@ -3027,13 +3095,13 @@ bond_probe(struct rte_vdev_device *dev) if (rte_kvargs_process(kvlist, PMD_BOND_SOCKET_ID_KVARG, &bond_ethdev_parse_socket_id_kvarg, &socket_id) != 0) { - RTE_LOG(ERR, EAL, "Invalid socket Id specified for " - "bonded device %s\n", name); + RTE_BOND_LOG(ERR, "Invalid socket Id specified for " + "bonded device %s", name); goto parse_error; } } else if (arg_count > 1) { - RTE_LOG(ERR, EAL, "Socket Id can be specified only once for " - "bonded device %s\n", name); + RTE_BOND_LOG(ERR, "Socket Id can be specified only once for " + "bonded device %s", name); goto parse_error; } else { socket_id = rte_socket_id(); @@ -3044,8 +3112,8 @@ bond_probe(struct rte_vdev_device *dev) /* Create link bonding eth device */ port_id = bond_alloc(dev, bonding_mode); if (port_id < 0) { - RTE_LOG(ERR, EAL, "Failed to create socket %s in mode %u on " - "socket %u.\n", name, bonding_mode, socket_id); + RTE_BOND_LOG(ERR, "Failed to create socket %s in mode %u on " + "socket %u.", name, bonding_mode, socket_id); goto parse_error; } internals = rte_eth_devices[port_id].data->dev_private; @@ -3057,8 +3125,8 @@ bond_probe(struct rte_vdev_device *dev) PMD_BOND_AGG_MODE_KVARG, &bond_ethdev_parse_slave_agg_mode_kvarg, &agg_mode) != 0) { - RTE_LOG(ERR, EAL, - "Failed to parse agg selection mode for bonded device %s\n", + RTE_BOND_LOG(ERR, + "Failed to parse agg selection mode for bonded device %s", name); goto parse_error; } @@ -3070,8 +3138,9 @@ bond_probe(struct rte_vdev_device *dev) rte_eth_bond_8023ad_agg_selection_set(port_id, AGG_STABLE); } - RTE_LOG(INFO, EAL, "Create bonded device %s on port %d in mode %u on " - "socket %u.\n", name, port_id, bonding_mode, socket_id); + rte_eth_dev_probing_finish(&rte_eth_devices[port_id]); + RTE_BOND_LOG(INFO, "Create bonded device %s on port %d in mode %u on " + "socket %u.", name, port_id, bonding_mode, socket_id); return 0; parse_error: @@ -3091,7 +3160,7 @@ bond_remove(struct rte_vdev_device *dev) return -EINVAL; name = rte_vdev_device_name(dev); - RTE_LOG(INFO, EAL, "Uninitializing pmd_bond for %s\n", name); + RTE_BOND_LOG(INFO, "Uninitializing pmd_bond for %s", name); /* now free all data allocation - for eth_dev structure, * dummy pci driver and internal (private) data @@ -3118,6 +3187,10 @@ bond_remove(struct rte_vdev_device *dev) eth_dev->tx_pkt_burst = NULL; internals = eth_dev->data->dev_private; + /* Try to release mempool used in mode6. If the bond + * device is not mode6, free the NULL is not problem. + */ + rte_mempool_free(internals->mode6.mempool); rte_bitmap_free(internals->vlan_filter_bmp); rte_free(internals->vlan_filter_bmpmem); rte_free(eth_dev->data->dev_private); @@ -3178,23 +3251,23 @@ bond_ethdev_configure(struct rte_eth_dev *dev) struct ether_addr bond_mac; if (rte_kvargs_process(kvlist, PMD_BOND_MAC_ADDR_KVARG, - &bond_ethdev_parse_bond_mac_addr_kvarg, &bond_mac) < 0) { - RTE_LOG(INFO, EAL, "Invalid mac address for bonded device %s\n", - name); + &bond_ethdev_parse_bond_mac_addr_kvarg, &bond_mac) < 0) { + RTE_BOND_LOG(INFO, "Invalid mac address for bonded device %s", + name); return -1; } /* Set MAC address */ if (rte_eth_bond_mac_address_set(port_id, &bond_mac) != 0) { - RTE_LOG(ERR, EAL, - "Failed to set mac address on bonded device %s\n", - name); + RTE_BOND_LOG(ERR, + "Failed to set mac address on bonded device %s", + name); return -1; } } else if (arg_count > 1) { - RTE_LOG(ERR, EAL, - "MAC address can be specified only once for bonded device %s\n", - name); + RTE_BOND_LOG(ERR, + "MAC address can be specified only once for bonded device %s", + name); return -1; } @@ -3204,40 +3277,40 @@ bond_ethdev_configure(struct rte_eth_dev *dev) uint8_t xmit_policy; if (rte_kvargs_process(kvlist, PMD_BOND_XMIT_POLICY_KVARG, - &bond_ethdev_parse_balance_xmit_policy_kvarg, &xmit_policy) != - 0) { - RTE_LOG(INFO, EAL, - "Invalid xmit policy specified for bonded device %s\n", - name); + &bond_ethdev_parse_balance_xmit_policy_kvarg, &xmit_policy) != + 0) { + RTE_BOND_LOG(INFO, + "Invalid xmit policy specified for bonded device %s", + name); return -1; } /* Set balance mode transmit policy*/ if (rte_eth_bond_xmit_policy_set(port_id, xmit_policy) != 0) { - RTE_LOG(ERR, EAL, - "Failed to set balance xmit policy on bonded device %s\n", - name); + RTE_BOND_LOG(ERR, + "Failed to set balance xmit policy on bonded device %s", + name); return -1; } } else if (arg_count > 1) { - RTE_LOG(ERR, EAL, - "Transmit policy can be specified only once for bonded device" - " %s\n", name); + RTE_BOND_LOG(ERR, + "Transmit policy can be specified only once for bonded device %s", + name); return -1; } if (rte_kvargs_count(kvlist, PMD_BOND_AGG_MODE_KVARG) == 1) { if (rte_kvargs_process(kvlist, - PMD_BOND_AGG_MODE_KVARG, - &bond_ethdev_parse_slave_agg_mode_kvarg, - &agg_mode) != 0) { - RTE_LOG(ERR, EAL, - "Failed to parse agg selection mode for bonded device %s\n", - name); + PMD_BOND_AGG_MODE_KVARG, + &bond_ethdev_parse_slave_agg_mode_kvarg, + &agg_mode) != 0) { + RTE_BOND_LOG(ERR, + "Failed to parse agg selection mode for bonded device %s", + name); } if (internals->mode == BONDING_MODE_8023AD) - rte_eth_bond_8023ad_agg_selection_set(port_id, - agg_mode); + rte_eth_bond_8023ad_agg_selection_set(port_id, + agg_mode); } /* Parse/add slave ports to bonded device */ @@ -3248,23 +3321,23 @@ bond_ethdev_configure(struct rte_eth_dev *dev) memset(&slave_ports, 0, sizeof(slave_ports)); if (rte_kvargs_process(kvlist, PMD_BOND_SLAVE_PORT_KVARG, - &bond_ethdev_parse_slave_port_kvarg, &slave_ports) != 0) { - RTE_LOG(ERR, EAL, - "Failed to parse slave ports for bonded device %s\n", - name); + &bond_ethdev_parse_slave_port_kvarg, &slave_ports) != 0) { + RTE_BOND_LOG(ERR, + "Failed to parse slave ports for bonded device %s", + name); return -1; } for (i = 0; i < slave_ports.slave_count; i++) { if (rte_eth_bond_slave_add(port_id, slave_ports.slaves[i]) != 0) { - RTE_LOG(ERR, EAL, - "Failed to add port %d as slave to bonded device %s\n", - slave_ports.slaves[i], name); + RTE_BOND_LOG(ERR, + "Failed to add port %d as slave to bonded device %s", + slave_ports.slaves[i], name); } } } else { - RTE_LOG(INFO, EAL, "No slaves specified for bonded device %s\n", name); + RTE_BOND_LOG(INFO, "No slaves specified for bonded device %s", name); return -1; } @@ -3274,27 +3347,27 @@ bond_ethdev_configure(struct rte_eth_dev *dev) uint16_t primary_slave_port_id; if (rte_kvargs_process(kvlist, - PMD_BOND_PRIMARY_SLAVE_KVARG, - &bond_ethdev_parse_primary_slave_port_id_kvarg, - &primary_slave_port_id) < 0) { - RTE_LOG(INFO, EAL, - "Invalid primary slave port id specified for bonded device" - " %s\n", name); + PMD_BOND_PRIMARY_SLAVE_KVARG, + &bond_ethdev_parse_primary_slave_port_id_kvarg, + &primary_slave_port_id) < 0) { + RTE_BOND_LOG(INFO, + "Invalid primary slave port id specified for bonded device %s", + name); return -1; } /* Set balance mode transmit policy*/ if (rte_eth_bond_primary_set(port_id, primary_slave_port_id) - != 0) { - RTE_LOG(ERR, EAL, - "Failed to set primary slave port %d on bonded device %s\n", - primary_slave_port_id, name); + != 0) { + RTE_BOND_LOG(ERR, + "Failed to set primary slave port %d on bonded device %s", + primary_slave_port_id, name); return -1; } } else if (arg_count > 1) { - RTE_LOG(INFO, EAL, - "Primary slave can be specified only once for bonded device" - " %s\n", name); + RTE_BOND_LOG(INFO, + "Primary slave can be specified only once for bonded device %s", + name); return -1; } @@ -3304,26 +3377,26 @@ bond_ethdev_configure(struct rte_eth_dev *dev) uint32_t lsc_poll_interval_ms; if (rte_kvargs_process(kvlist, - PMD_BOND_LSC_POLL_PERIOD_KVARG, - &bond_ethdev_parse_time_ms_kvarg, - &lsc_poll_interval_ms) < 0) { - RTE_LOG(INFO, EAL, - "Invalid lsc polling interval value specified for bonded" - " device %s\n", name); + PMD_BOND_LSC_POLL_PERIOD_KVARG, + &bond_ethdev_parse_time_ms_kvarg, + &lsc_poll_interval_ms) < 0) { + RTE_BOND_LOG(INFO, + "Invalid lsc polling interval value specified for bonded" + " device %s", name); return -1; } if (rte_eth_bond_link_monitoring_set(port_id, lsc_poll_interval_ms) - != 0) { - RTE_LOG(ERR, EAL, - "Failed to set lsc monitor polling interval (%u ms) on" - " bonded device %s\n", lsc_poll_interval_ms, name); + != 0) { + RTE_BOND_LOG(ERR, + "Failed to set lsc monitor polling interval (%u ms) on bonded device %s", + lsc_poll_interval_ms, name); return -1; } } else if (arg_count > 1) { - RTE_LOG(INFO, EAL, - "LSC polling interval can be specified only once for bonded" - " device %s\n", name); + RTE_BOND_LOG(INFO, + "LSC polling interval can be specified only once for bonded" + " device %s", name); return -1; } @@ -3333,27 +3406,27 @@ bond_ethdev_configure(struct rte_eth_dev *dev) uint32_t link_up_delay_ms; if (rte_kvargs_process(kvlist, - PMD_BOND_LINK_UP_PROP_DELAY_KVARG, - &bond_ethdev_parse_time_ms_kvarg, - &link_up_delay_ms) < 0) { - RTE_LOG(INFO, EAL, - "Invalid link up propagation delay value specified for" - " bonded device %s\n", name); + PMD_BOND_LINK_UP_PROP_DELAY_KVARG, + &bond_ethdev_parse_time_ms_kvarg, + &link_up_delay_ms) < 0) { + RTE_BOND_LOG(INFO, + "Invalid link up propagation delay value specified for" + " bonded device %s", name); return -1; } /* Set balance mode transmit policy*/ if (rte_eth_bond_link_up_prop_delay_set(port_id, link_up_delay_ms) - != 0) { - RTE_LOG(ERR, EAL, - "Failed to set link up propagation delay (%u ms) on bonded" - " device %s\n", link_up_delay_ms, name); + != 0) { + RTE_BOND_LOG(ERR, + "Failed to set link up propagation delay (%u ms) on bonded" + " device %s", link_up_delay_ms, name); return -1; } } else if (arg_count > 1) { - RTE_LOG(INFO, EAL, - "Link up propagation delay can be specified only once for" - " bonded device %s\n", name); + RTE_BOND_LOG(INFO, + "Link up propagation delay can be specified only once for" + " bonded device %s", name); return -1; } @@ -3363,27 +3436,27 @@ bond_ethdev_configure(struct rte_eth_dev *dev) uint32_t link_down_delay_ms; if (rte_kvargs_process(kvlist, - PMD_BOND_LINK_DOWN_PROP_DELAY_KVARG, - &bond_ethdev_parse_time_ms_kvarg, - &link_down_delay_ms) < 0) { - RTE_LOG(INFO, EAL, - "Invalid link down propagation delay value specified for" - " bonded device %s\n", name); + PMD_BOND_LINK_DOWN_PROP_DELAY_KVARG, + &bond_ethdev_parse_time_ms_kvarg, + &link_down_delay_ms) < 0) { + RTE_BOND_LOG(INFO, + "Invalid link down propagation delay value specified for" + " bonded device %s", name); return -1; } /* Set balance mode transmit policy*/ if (rte_eth_bond_link_down_prop_delay_set(port_id, link_down_delay_ms) - != 0) { - RTE_LOG(ERR, EAL, - "Failed to set link down propagation delay (%u ms) on" - " bonded device %s\n", link_down_delay_ms, name); + != 0) { + RTE_BOND_LOG(ERR, + "Failed to set link down propagation delay (%u ms) on bonded device %s", + link_down_delay_ms, name); return -1; } } else if (arg_count > 1) { - RTE_LOG(INFO, EAL, - "Link down propagation delay can be specified only once for" - " bonded device %s\n", name); + RTE_BOND_LOG(INFO, + "Link down propagation delay can be specified only once for bonded device %s", + name); return -1; } @@ -3409,3 +3482,14 @@ RTE_PMD_REGISTER_PARAM_STRING(net_bonding, "lsc_poll_period_ms= " "up_delay= " "down_delay="); + +int bond_logtype; + +RTE_INIT(bond_init_log); +static void +bond_init_log(void) +{ + bond_logtype = rte_log_register("pmd.net.bon"); + if (bond_logtype >= 0) + rte_log_set_level(bond_logtype, RTE_LOG_NOTICE); +} diff --git a/drivers/net/bonding/rte_eth_bond_private.h b/drivers/net/bonding/rte_eth_bond_private.h index 92e15f8c..65445b86 100644 --- a/drivers/net/bonding/rte_eth_bond_private.h +++ b/drivers/net/bonding/rte_eth_bond_private.h @@ -5,9 +5,12 @@ #ifndef _RTE_ETH_BOND_PRIVATE_H_ #define _RTE_ETH_BOND_PRIVATE_H_ +#include + #include #include #include +#include #include "rte_eth_bond.h" #include "rte_eth_bond_8023ad_private.h" @@ -28,8 +31,11 @@ #define PMD_BOND_XMIT_POLICY_LAYER23_KVARG ("l23") #define PMD_BOND_XMIT_POLICY_LAYER34_KVARG ("l34") +extern int bond_logtype; + #define RTE_BOND_LOG(lvl, msg, ...) \ - RTE_LOG(lvl, PMD, "%s(%d) - " msg "\n", __func__, __LINE__, ##__VA_ARGS__) + rte_log(RTE_LOG_ ## lvl, bond_logtype, \ + "%s(%d) - " msg "\n", __func__, __LINE__, ##__VA_ARGS__) #define BONDING_MODE_INVALID 0xFF @@ -37,6 +43,8 @@ extern const char *pmd_bond_init_valid_arguments[]; extern struct rte_vdev_driver pmd_bond_drv; +extern const struct rte_flow_ops bond_flow_ops; + /** Port Queue Mapping Structure */ struct bond_rx_queue { uint16_t queue_id; @@ -80,6 +88,14 @@ struct bond_slave_details { uint16_t reta_size; }; +struct rte_flow { + TAILQ_ENTRY(rte_flow) next; + /* Slaves flows */ + struct rte_flow *flows[RTE_MAX_ETHPORTS]; + /* Flow description for synchronization */ + struct rte_flow_desc *fd; +}; + typedef void (*burst_xmit_hash_t)(struct rte_mbuf **buf, uint16_t nb_pkts, uint8_t slave_count, uint16_t *slaves); @@ -89,6 +105,7 @@ struct bond_dev_private { uint8_t mode; /**< Link Bonding Mode */ rte_spinlock_t lock; + rte_spinlock_t lsc_lock; uint16_t primary_port; /**< Primary Slave Port */ uint16_t current_primary_port; /**< Primary Slave Port */ @@ -128,8 +145,17 @@ struct bond_dev_private { /**< TLB active slaves send order */ struct mode_alb_private mode6; - uint32_t rx_offload_capa; /** Rx offload capability */ - uint32_t tx_offload_capa; /** Tx offload capability */ + uint64_t rx_offload_capa; /** Rx offload capability */ + uint64_t tx_offload_capa; /** Tx offload capability */ + uint64_t rx_queue_offload_capa; /** per queue Rx offload capability */ + uint64_t tx_queue_offload_capa; /** per queue Tx offload capability */ + + /**< List of the configured flows */ + TAILQ_HEAD(sub_flows, rte_flow) flow_list; + + /**< Flow isolation state */ + int flow_isolated; + int flow_isolated_valid; /** Bit mask of RSS offloads, the bit offset also means flow type */ uint64_t flow_type_rss_offloads; diff --git a/drivers/net/bonding/rte_pmd_bond_version.map b/drivers/net/bonding/rte_pmd_bond_version.map index ec3374b0..03ddb44e 100644 --- a/drivers/net/bonding/rte_pmd_bond_version.map +++ b/drivers/net/bonding/rte_pmd_bond_version.map @@ -1,6 +1,7 @@ DPDK_2.0 { global: + rte_eth_bond_8023ad_slave_info; rte_eth_bond_active_slaves_get; rte_eth_bond_create; rte_eth_bond_link_monitoring_set; -- cgit 1.2.3-korg