From 6d72657ce379e159b745be27edcad72ac0266aac Mon Sep 17 00:00:00 2001 From: Daniel Mrzyglod Date: Wed, 19 Jul 2017 16:31:17 +0200 Subject: [PATCH] net/bonding: add other aggregator modes This patch add support for setting additional aggregator modes for IEEE802.3AD in similar manner that are supported in kernel mode. This will add support for other manner: stable - default mode taken from IEEE802.11AX this is default aggregator mode bandwidth - takes aggregator with highest bandwidth count - takes aggregator with biggest number of slaves Signed-off-by: Daniel Mrzyglod Acked-by: Declan Doherty --- drivers/net/bonding/rte_eth_bond_8023ad.c | 194 ++++++++++++++++-- drivers/net/bonding/rte_eth_bond_8023ad.h | 32 +++ .../net/bonding/rte_eth_bond_8023ad_private.h | 1 + drivers/net/bonding/rte_eth_bond_args.c | 33 +++ drivers/net/bonding/rte_eth_bond_pmd.c | 19 +- drivers/net/bonding/rte_eth_bond_private.h | 5 + drivers/net/bonding/rte_eth_bond_version.map | 5 + 7 files changed, 275 insertions(+), 14 deletions(-) diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c index a2313b327f..20b5a89612 100644 --- a/drivers/net/bonding/rte_eth_bond_8023ad.c +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c @@ -44,7 +44,6 @@ #include "rte_eth_bond_private.h" 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, \ @@ -660,6 +659,25 @@ tx_machine(struct bond_dev_private *internals, uint8_t slave_id) SM_FLAG_CLR(port, NTT); } +static uint8_t +max_index(uint64_t *a, int n) +{ + if (n <= 0) + return -1; + + int i, max_i = 0; + uint64_t max = a[0]; + + for (i = 1; i < n; ++i) { + if (a[i] > max) { + max = a[i]; + max_i = i; + } + } + + return max_i; +} + /** * Function assigns port to aggregator. * @@ -670,8 +688,13 @@ static void selection_logic(struct bond_dev_private *internals, uint8_t slave_id) { struct port *agg, *port; - uint8_t slaves_count, new_agg_id, i; + uint8_t slaves_count, new_agg_id, i, j = 0; uint8_t *slaves; + uint64_t agg_bandwidth[8] = {0}; + uint64_t agg_count[8] = {0}; + uint8_t default_slave = 0; + uint8_t mode_count_id, mode_band_id; + struct rte_eth_link link_info; slaves = internals->active_slaves; slaves_count = internals->active_slave_count; @@ -684,6 +707,10 @@ selection_logic(struct bond_dev_private *internals, uint8_t slave_id) if (agg->aggregator_port_id != slaves[i]) continue; + agg_count[agg->aggregator_port_id] += 1; + rte_eth_link_get_nowait(slaves[i], &link_info); + agg_bandwidth[agg->aggregator_port_id] += link_info.link_speed; + /* Actors system ID is not checked since all slave device have the same * ID (MAC address). */ if ((agg->actor.key == port->actor.key && @@ -694,15 +721,36 @@ selection_logic(struct bond_dev_private *internals, uint8_t slave_id) (agg->actor.key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) { - break; + if (j == 0) + default_slave = i; + j++; } } - /* By default, port uses it self as agregator */ - if (i == slaves_count) - new_agg_id = slave_id; - else - new_agg_id = slaves[i]; + switch (internals->mode4.agg_selection) { + case AGG_COUNT: + mode_count_id = max_index( + (uint64_t *)agg_count, slaves_count); + new_agg_id = mode_count_id; + break; + case AGG_BANDWIDTH: + mode_band_id = max_index( + (uint64_t *)agg_bandwidth, slaves_count); + new_agg_id = mode_band_id; + break; + case AGG_STABLE: + if (default_slave == slaves_count) + new_agg_id = slave_id; + else + new_agg_id = slaves[default_slave]; + break; + default: + if (default_slave == slaves_count) + new_agg_id = slave_id; + else + new_agg_id = slaves[default_slave]; + break; + } if (new_agg_id != port->aggregator_port_id) { port->aggregator_port_id = new_agg_id; @@ -909,7 +957,7 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, uint8_t slave_id) /* default states */ port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED; - port->partner_state = STATE_LACP_ACTIVE; + port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION; port->sm_flags = SM_FLAGS_BEGIN; /* use this port as agregator */ @@ -1076,6 +1124,18 @@ bond_mode_8023ad_conf_get_v1607(struct rte_eth_dev *dev, conf->slowrx_cb = mode4->slowrx_cb; } +static void +bond_mode_8023ad_conf_get_v1708(struct rte_eth_dev *dev, + struct rte_eth_bond_8023ad_conf *conf) +{ + struct bond_dev_private *internals = dev->data->dev_private; + struct mode8023ad_private *mode4 = &internals->mode4; + + bond_mode_8023ad_conf_get(dev, conf); + conf->slowrx_cb = mode4->slowrx_cb; + conf->agg_selection = mode4->agg_selection; +} + static void bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf) { @@ -1088,6 +1148,7 @@ bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf) conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS; conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS; conf->slowrx_cb = NULL; + conf->agg_selection = AGG_STABLE; } static void @@ -1144,9 +1205,31 @@ bond_mode_8023ad_setup(struct rte_eth_dev *dev, bond_mode_8023ad_conf_get_default(conf); } + bond_mode_8023ad_stop(dev); + bond_mode_8023ad_conf_assign(mode4, conf); + + + if (dev->data->dev_started) + bond_mode_8023ad_start(dev); +} + +static void +bond_mode_8023ad_setup_v1708(struct rte_eth_dev *dev, + struct rte_eth_bond_8023ad_conf *conf) +{ + struct rte_eth_bond_8023ad_conf def_conf; + struct bond_dev_private *internals = dev->data->dev_private; + struct mode8023ad_private *mode4 = &internals->mode4; + + if (conf == NULL) { + conf = &def_conf; + bond_mode_8023ad_conf_get_default(conf); + } + bond_mode_8023ad_stop(dev); bond_mode_8023ad_conf_assign(mode4, conf); mode4->slowrx_cb = conf->slowrx_cb; + mode4->agg_selection = AGG_STABLE; if (dev->data->dev_started) bond_mode_8023ad_start(dev); @@ -1308,10 +1391,71 @@ rte_eth_bond_8023ad_conf_get_v1607(uint8_t port_id, bond_mode_8023ad_conf_get_v1607(bond_dev, conf); return 0; } -BIND_DEFAULT_SYMBOL(rte_eth_bond_8023ad_conf_get, _v1607, 16.07); +VERSION_SYMBOL(rte_eth_bond_8023ad_conf_get, _v1607, 16.07); + +int +rte_eth_bond_8023ad_conf_get_v1708(uint8_t port_id, + struct rte_eth_bond_8023ad_conf *conf) +{ + struct rte_eth_dev *bond_dev; + + if (valid_bonded_port_id(port_id) != 0) + return -EINVAL; + + if (conf == NULL) + return -EINVAL; + + bond_dev = &rte_eth_devices[port_id]; + bond_mode_8023ad_conf_get_v1708(bond_dev, conf); + return 0; +} MAP_STATIC_SYMBOL(int rte_eth_bond_8023ad_conf_get(uint8_t port_id, struct rte_eth_bond_8023ad_conf *conf), - rte_eth_bond_8023ad_conf_get_v1607); + rte_eth_bond_8023ad_conf_get_v1708); +BIND_DEFAULT_SYMBOL(rte_eth_bond_8023ad_conf_get, _v1708, 17.08); + +int +rte_eth_bond_8023ad_agg_selection_set(uint8_t port_id, + enum rte_bond_8023ad_agg_selection agg_selection) +{ + struct rte_eth_dev *bond_dev; + struct bond_dev_private *internals; + struct mode8023ad_private *mode4; + + bond_dev = &rte_eth_devices[port_id]; + internals = bond_dev->data->dev_private; + + if (valid_bonded_port_id(port_id) != 0) + return -EINVAL; + if (internals->mode != 4) + return -EINVAL; + + mode4 = &internals->mode4; + if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH + || agg_selection == AGG_STABLE) + mode4->agg_selection = agg_selection; + return 0; +} + +int rte_eth_bond_8023ad_agg_selection_get(uint8_t port_id) +{ + struct rte_eth_dev *bond_dev; + struct bond_dev_private *internals; + struct mode8023ad_private *mode4; + + bond_dev = &rte_eth_devices[port_id]; + internals = bond_dev->data->dev_private; + + if (valid_bonded_port_id(port_id) != 0) + return -EINVAL; + if (internals->mode != 4) + return -EINVAL; + mode4 = &internals->mode4; + + return mode4->agg_selection; +} + + static int bond_8023ad_setup_validate(uint8_t port_id, @@ -1372,10 +1516,34 @@ rte_eth_bond_8023ad_setup_v1607(uint8_t port_id, return 0; } -BIND_DEFAULT_SYMBOL(rte_eth_bond_8023ad_setup, _v1607, 16.07); +VERSION_SYMBOL(rte_eth_bond_8023ad_setup, _v1607, 16.07); + + +int +rte_eth_bond_8023ad_setup_v1708(uint8_t port_id, + struct rte_eth_bond_8023ad_conf *conf) +{ + struct rte_eth_dev *bond_dev; + int err; + + err = bond_8023ad_setup_validate(port_id, conf); + if (err != 0) + return err; + + bond_dev = &rte_eth_devices[port_id]; + bond_mode_8023ad_setup_v1708(bond_dev, conf); + + return 0; +} +BIND_DEFAULT_SYMBOL(rte_eth_bond_8023ad_setup, _v1708, 17.08); MAP_STATIC_SYMBOL(int rte_eth_bond_8023ad_setup(uint8_t port_id, struct rte_eth_bond_8023ad_conf *conf), - rte_eth_bond_8023ad_setup_v1607); + rte_eth_bond_8023ad_setup_v1708); + + + + + int rte_eth_bond_8023ad_slave_info(uint8_t port_id, uint8_t slave_id, diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.h b/drivers/net/bonding/rte_eth_bond_8023ad.h index 5c61e66ad3..1d353c7348 100644 --- a/drivers/net/bonding/rte_eth_bond_8023ad.h +++ b/drivers/net/bonding/rte_eth_bond_8023ad.h @@ -73,6 +73,12 @@ enum rte_bond_8023ad_selection { SELECTED }; +enum rte_bond_8023ad_agg_selection { + AGG_BANDWIDTH, + AGG_COUNT, + AGG_STABLE +}; + /** Generic slow protocol structure */ struct slow_protocol { uint8_t subtype; @@ -161,6 +167,7 @@ struct rte_eth_bond_8023ad_conf { uint32_t rx_marker_period_ms; uint32_t update_timeout_ms; rte_eth_bond_8023ad_ext_slowrx_fn slowrx_cb; + enum rte_bond_8023ad_agg_selection agg_selection; }; struct rte_eth_bond_8023ad_slave_info { @@ -193,6 +200,9 @@ rte_eth_bond_8023ad_conf_get_v20(uint8_t port_id, int rte_eth_bond_8023ad_conf_get_v1607(uint8_t port_id, struct rte_eth_bond_8023ad_conf *conf); +int +rte_eth_bond_8023ad_conf_get_v1708(uint8_t port_id, + struct rte_eth_bond_8023ad_conf *conf); /** * @internal @@ -214,6 +224,9 @@ rte_eth_bond_8023ad_setup_v20(uint8_t port_id, int rte_eth_bond_8023ad_setup_v1607(uint8_t port_id, struct rte_eth_bond_8023ad_conf *conf); +int +rte_eth_bond_8023ad_setup_v1708(uint8_t port_id, + struct rte_eth_bond_8023ad_conf *conf); /** * @internal @@ -344,4 +357,23 @@ rte_eth_bond_8023ad_dedicated_queues_enable(uint8_t port_id); int rte_eth_bond_8023ad_dedicated_queues_disable(uint8_t port_id); +/* + * Get aggregator mode for 8023ad + * @param port_id Bonding device id + * + * @return + * agregator mode on success, negative value otherwise + */ +int +rte_eth_bond_8023ad_agg_selection_get(uint8_t port_id); + +/** + * Set aggregator mode for 8023ad + * @param port_id Bonding device id + * @return + * 0 on success, negative value otherwise + */ +int +rte_eth_bond_8023ad_agg_selection_set(uint8_t port_id, + enum rte_bond_8023ad_agg_selection agg_selection); #endif /* RTE_ETH_BOND_8023AD_H_ */ diff --git a/drivers/net/bonding/rte_eth_bond_8023ad_private.h b/drivers/net/bonding/rte_eth_bond_8023ad_private.h index 802551d1c4..d46e44a841 100644 --- a/drivers/net/bonding/rte_eth_bond_8023ad_private.h +++ b/drivers/net/bonding/rte_eth_bond_8023ad_private.h @@ -195,6 +195,7 @@ struct mode8023ad_private { uint16_t rx_qid; uint16_t tx_qid; } dedicated_queues; + enum rte_bond_8023ad_agg_selection agg_selection; }; /** diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c index 4f12050b84..bb634c62ef 100644 --- a/drivers/net/bonding/rte_eth_bond_args.c +++ b/drivers/net/bonding/rte_eth_bond_args.c @@ -48,6 +48,7 @@ const char *pmd_bond_init_valid_arguments[] = { PMD_BOND_XMIT_POLICY_KVARG, PMD_BOND_SOCKET_ID_KVARG, PMD_BOND_MAC_ADDR_KVARG, + PMD_BOND_AGG_MODE_KVARG, "driver", NULL }; @@ -190,6 +191,38 @@ bond_ethdev_parse_slave_mode_kvarg(const char *key __rte_unused, } } +int +bond_ethdev_parse_slave_agg_mode_kvarg(const char *key __rte_unused, + const char *value, void *extra_args) +{ + uint8_t *agg_mode; + + if (value == NULL || extra_args == NULL) + return -1; + + agg_mode = extra_args; + + errno = 0; + if (strncmp(value, "stable", 6) == 0) + *agg_mode = AGG_STABLE; + + if (strncmp(value, "bandwidth", 9) == 0) + *agg_mode = AGG_BANDWIDTH; + + if (strncmp(value, "count", 5) == 0) + *agg_mode = AGG_COUNT; + + switch (*agg_mode) { + case AGG_STABLE: + case AGG_BANDWIDTH: + case AGG_COUNT: + return 0; + default: + RTE_BOND_LOG(ERR, "Invalid agg mode value stable/bandwidth/count"); + return -1; + } +} + int bond_ethdev_parse_socket_id_kvarg(const char *key __rte_unused, const char *value, void *extra_args) diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c index 383e27ccf3..8f9a860844 100644 --- a/drivers/net/bonding/rte_eth_bond_pmd.c +++ b/drivers/net/bonding/rte_eth_bond_pmd.c @@ -2822,7 +2822,7 @@ bond_probe(struct rte_vdev_device *dev) const char *name; struct bond_dev_private *internals; struct rte_kvargs *kvlist; - uint8_t bonding_mode, socket_id; + uint8_t bonding_mode, socket_id/*, agg_mode*/; int arg_count, port_id; if (!dev) @@ -2949,6 +2949,7 @@ bond_ethdev_configure(struct rte_eth_dev *dev) struct rte_kvargs *kvlist = internals->kvlist; int arg_count; uint8_t port_id = dev - rte_eth_devices; + uint8_t agg_mode; static const uint8_t default_rss_key[40] = { 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 0x41, 0x67, 0x25, 0x3D, @@ -3036,6 +3037,21 @@ bond_ethdev_configure(struct rte_eth_dev *dev) 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); + } + if (internals->mode == BONDING_MODE_8023AD) + if (agg_mode != 0) + rte_eth_bond_8023ad_agg_selection_set(port_id, + agg_mode); + } + /* Parse/add slave ports to bonded device */ if (rte_kvargs_count(kvlist, PMD_BOND_SLAVE_PORT_KVARG) > 0) { struct bond_ethdev_slave_ports slave_ports; @@ -3199,6 +3215,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_bonding, "primary= " "mode=[0-6] " "xmit_policy=[l2 | l23 | l34] " + "agg_mode=[count | stable | bandwidth] " "socket_id= " "mac= " "lsc_poll_period_ms= " diff --git a/drivers/net/bonding/rte_eth_bond_private.h b/drivers/net/bonding/rte_eth_bond_private.h index 8fbf4bf683..1fe6ff880f 100644 --- a/drivers/net/bonding/rte_eth_bond_private.h +++ b/drivers/net/bonding/rte_eth_bond_private.h @@ -45,6 +45,7 @@ #define PMD_BOND_SLAVE_PORT_KVARG ("slave") #define PMD_BOND_PRIMARY_SLAVE_KVARG ("primary") #define PMD_BOND_MODE_KVARG ("mode") +#define PMD_BOND_AGG_MODE_KVARG ("agg_mode") #define PMD_BOND_XMIT_POLICY_KVARG ("xmit_policy") #define PMD_BOND_SOCKET_ID_KVARG ("socket_id") #define PMD_BOND_MAC_ADDR_KVARG ("mac") @@ -268,6 +269,10 @@ int bond_ethdev_parse_slave_mode_kvarg(const char *key, const char *value, void *extra_args); +int +bond_ethdev_parse_slave_agg_mode_kvarg(const char *key __rte_unused, + const char *value, void *extra_args); + int bond_ethdev_parse_socket_id_kvarg(const char *key, const char *value, void *extra_args); diff --git a/drivers/net/bonding/rte_eth_bond_version.map b/drivers/net/bonding/rte_eth_bond_version.map index 719dd4d819..0f4e847dae 100644 --- a/drivers/net/bonding/rte_eth_bond_version.map +++ b/drivers/net/bonding/rte_eth_bond_version.map @@ -49,5 +49,10 @@ DPDK_17.08 { rte_eth_bond_8023ad_dedicated_queues_enable; rte_eth_bond_8023ad_dedicated_queues_disable; + rte_eth_bond_8023ad_agg_selection_get; + rte_eth_bond_8023ad_agg_selection_set; + rte_eth_bond_8023ad_conf_get; + rte_eth_bond_8023ad_setup; + } DPDK_16.07; -- 2.20.1