X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_rss.c;h=9e12b51fee50e3f28e98d83385c302fb53c13b8f;hb=e940646b20fa;hp=2dc58e56b5cf77ada7d7eb52055ca075c5a4cf62;hpb=2f97422e7759d83061fd04876c2110cf2655a604;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_rss.c b/drivers/net/mlx5/mlx5_rss.c index 2dc58e56b5..9e12b51fee 100644 --- a/drivers/net/mlx5/mlx5_rss.c +++ b/drivers/net/mlx5/mlx5_rss.c @@ -40,129 +40,251 @@ /* Verbs header. */ /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ #ifdef PEDANTIC -#pragma GCC diagnostic ignored "-pedantic" +#pragma GCC diagnostic ignored "-Wpedantic" #endif #include #ifdef PEDANTIC -#pragma GCC diagnostic error "-pedantic" +#pragma GCC diagnostic error "-Wpedantic" #endif -/* DPDK headers don't like -pedantic. */ -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-pedantic" -#endif #include -#include -#ifdef PEDANTIC -#pragma GCC diagnostic error "-pedantic" -#endif +#include #include "mlx5.h" +#include "mlx5_defs.h" #include "mlx5_rxtx.h" /** - * Register a RSS key. + * DPDK callback to update the RSS hash configuration. + * + * @param dev + * Pointer to Ethernet device structure. + * @param[in] rss_conf + * RSS configuration data. + * + * @return + * 0 on success, negative errno value on failure. + */ +int +mlx5_rss_hash_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + struct priv *priv = dev->data->dev_private; + int ret = 0; + + priv_lock(priv); + if (rss_conf->rss_hf & MLX5_RSS_HF_MASK) { + ret = -EINVAL; + goto out; + } + if (rss_conf->rss_key && rss_conf->rss_key_len) { + priv->rss_conf.rss_key = rte_realloc(priv->rss_conf.rss_key, + rss_conf->rss_key_len, 0); + if (!priv->rss_conf.rss_key) { + ret = -ENOMEM; + goto out; + } + memcpy(priv->rss_conf.rss_key, rss_conf->rss_key, + rss_conf->rss_key_len); + priv->rss_conf.rss_key_len = rss_conf->rss_key_len; + } + priv->rss_conf.rss_hf = rss_conf->rss_hf; +out: + priv_unlock(priv); + return ret; +} + +/** + * DPDK callback to get the RSS hash configuration. + * + * @param dev + * Pointer to Ethernet device structure. + * @param[in, out] rss_conf + * RSS configuration data. + * + * @return + * 0 on success, negative errno value on failure. + */ +int +mlx5_rss_hash_conf_get(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + struct priv *priv = dev->data->dev_private; + + if (!rss_conf) + return -EINVAL; + priv_lock(priv); + if (rss_conf->rss_key && + (rss_conf->rss_key_len >= priv->rss_conf.rss_key_len)) { + memcpy(rss_conf->rss_key, priv->rss_conf.rss_key, + priv->rss_conf.rss_key_len); + } + rss_conf->rss_key_len = priv->rss_conf.rss_key_len; + rss_conf->rss_hf = priv->rss_conf.rss_hf; + priv_unlock(priv); + return 0; +} + +/** + * Allocate/reallocate RETA index table. * * @param priv * Pointer to private structure. - * @param key - * Hash key to register. - * @param key_len - * Hash key length in bytes. + * @praram reta_size + * The size of the array to allocate. * * @return * 0 on success, errno value on failure. */ int -rss_hash_rss_conf_new_key(struct priv *priv, const uint8_t *key, - unsigned int key_len) +priv_rss_reta_index_resize(struct priv *priv, unsigned int reta_size) { - struct rte_eth_rss_conf *rss_conf; + void *mem; + unsigned int old_size = priv->reta_idx_n; - rss_conf = rte_realloc(priv->rss_conf, - (sizeof(*rss_conf) + key_len), - 0); - if (!rss_conf) + if (priv->reta_idx_n == reta_size) + return 0; + + mem = rte_realloc(priv->reta_idx, + reta_size * sizeof((*priv->reta_idx)[0]), 0); + if (!mem) return ENOMEM; - rss_conf->rss_key = (void *)(rss_conf + 1); - rss_conf->rss_key_len = key_len; - memcpy(rss_conf->rss_key, key, key_len); - priv->rss_conf = rss_conf; + priv->reta_idx = mem; + priv->reta_idx_n = reta_size; + + if (old_size < reta_size) + memset(&(*priv->reta_idx)[old_size], 0, + (reta_size - old_size) * + sizeof((*priv->reta_idx)[0])); return 0; } /** - * DPDK callback to update the RSS hash configuration. + * Query RETA table. + * + * @param priv + * Pointer to private structure. + * @param[in, out] reta_conf + * Pointer to the first RETA configuration structure. + * @param reta_size + * Number of entries. + * + * @return + * 0 on success, errno value on failure. + */ +static int +priv_dev_rss_reta_query(struct priv *priv, + struct rte_eth_rss_reta_entry64 *reta_conf, + unsigned int reta_size) +{ + unsigned int idx; + unsigned int i; + + if (!reta_size || reta_size > priv->reta_idx_n) + return EINVAL; + /* Fill each entry of the table even if its bit is not set. */ + for (idx = 0, i = 0; (i != reta_size); ++i) { + idx = i / RTE_RETA_GROUP_SIZE; + reta_conf[idx].reta[i % RTE_RETA_GROUP_SIZE] = + (*priv->reta_idx)[i]; + } + return 0; +} + +/** + * Update RETA table. + * + * @param priv + * Pointer to private structure. + * @param[in] reta_conf + * Pointer to the first RETA configuration structure. + * @param reta_size + * Number of entries. + * + * @return + * 0 on success, errno value on failure. + */ +static int +priv_dev_rss_reta_update(struct priv *priv, + struct rte_eth_rss_reta_entry64 *reta_conf, + unsigned int reta_size) +{ + unsigned int idx; + unsigned int i; + unsigned int pos; + int ret; + + if (!reta_size) + return EINVAL; + ret = priv_rss_reta_index_resize(priv, reta_size); + if (ret) + return ret; + + for (idx = 0, i = 0; (i != reta_size); ++i) { + idx = i / RTE_RETA_GROUP_SIZE; + pos = i % RTE_RETA_GROUP_SIZE; + if (((reta_conf[idx].mask >> i) & 0x1) == 0) + continue; + assert(reta_conf[idx].reta[pos] < priv->rxqs_n); + (*priv->reta_idx)[i] = reta_conf[idx].reta[pos]; + } + return 0; +} + +/** + * DPDK callback to get the RETA indirection table. * * @param dev * Pointer to Ethernet device structure. - * @param[in] rss_conf - * RSS configuration data. + * @param reta_conf + * Pointer to RETA configuration structure array. + * @param reta_size + * Size of the RETA table. * * @return * 0 on success, negative errno value on failure. */ int -mlx5_rss_hash_update(struct rte_eth_dev *dev, - struct rte_eth_rss_conf *rss_conf) +mlx5_dev_rss_reta_query(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) { + int ret; struct priv *priv = dev->data->dev_private; - int err = 0; priv_lock(priv); - - assert(priv->rss_conf != NULL); - - /* Apply configuration. */ - if (rss_conf->rss_key) - err = rss_hash_rss_conf_new_key(priv, - rss_conf->rss_key, - rss_conf->rss_key_len); - else - err = rss_hash_rss_conf_new_key(priv, - rss_hash_default_key, - rss_hash_default_key_len); - - /* Store the configuration set into port configure. - * This will enable/disable hash RX queues associated to the protocols - * enabled/disabled by this update. */ - priv->dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = - rss_conf->rss_hf; + ret = priv_dev_rss_reta_query(priv, reta_conf, reta_size); priv_unlock(priv); - assert(err >= 0); - return -err; + return -ret; } /** - * DPDK callback to get the RSS hash configuration. + * DPDK callback to update the RETA indirection table. * * @param dev * Pointer to Ethernet device structure. - * @param[in, out] rss_conf - * RSS configuration data. + * @param reta_conf + * Pointer to RETA configuration structure array. + * @param reta_size + * Size of the RETA table. * * @return * 0 on success, negative errno value on failure. */ int -mlx5_rss_hash_conf_get(struct rte_eth_dev *dev, - struct rte_eth_rss_conf *rss_conf) +mlx5_dev_rss_reta_update(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) { + int ret; struct priv *priv = dev->data->dev_private; priv_lock(priv); - - assert(priv->rss_conf != NULL); - - if (rss_conf->rss_key && - rss_conf->rss_key_len >= priv->rss_conf->rss_key_len) - memcpy(rss_conf->rss_key, - priv->rss_conf->rss_key, - priv->rss_conf->rss_key_len); - rss_conf->rss_key_len = priv->rss_conf->rss_key_len; - /* FIXME: rss_hf should be more specific. */ - rss_conf->rss_hf = ETH_RSS_PROTO_MASK; - + ret = priv_dev_rss_reta_update(priv, reta_conf, reta_size); priv_unlock(priv); - return 0; + if (dev->data->dev_started) { + mlx5_dev_stop(dev); + mlx5_dev_start(dev); + } + return -ret; }