net/mlx5: handle a single RSS hash key for all protocols
authorNélio Laranjeiro <nelio.laranjeiro@6wind.com>
Mon, 9 Oct 2017 14:44:56 +0000 (16:44 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 12 Oct 2017 00:36:58 +0000 (01:36 +0100)
Since RSS configuration can also be used by flow API, there is no more
necessity to keep a list of RSS configurable for each protocol.

Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Acked-by: Yongseok Koh <yskoh@mellanox.com>
drivers/net/mlx5/mlx5.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_ethdev.c
drivers/net/mlx5/mlx5_rss.c
drivers/net/mlx5/mlx5_rxq.c

index c818cf8..46c89c6 100644 (file)
@@ -225,11 +225,8 @@ mlx5_dev_close(struct rte_eth_dev *dev)
                claim_zero(ibv_close_device(priv->ctx));
        } else
                assert(priv->ctx == NULL);
-       if (priv->rss_conf != NULL) {
-               for (i = 0; (i != hash_rxq_init_n); ++i)
-                       rte_free((*priv->rss_conf)[i]);
-               rte_free(priv->rss_conf);
-       }
+       if (priv->rss_conf.rss_key != NULL)
+               rte_free(priv->rss_conf.rss_key);
        if (priv->reta_idx != NULL)
                rte_free(priv->reta_idx);
        priv_socket_uninit(priv);
@@ -816,19 +813,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                                priv->txq_inline = MLX5_WQE_SIZE_MAX -
                                                   MLX5_WQE_SIZE;
                }
-               /* Allocate and register default RSS hash keys. */
-               priv->rss_conf = rte_calloc(__func__, hash_rxq_init_n,
-                                           sizeof((*priv->rss_conf)[0]), 0);
-               if (priv->rss_conf == NULL) {
-                       err = ENOMEM;
-                       goto port_error;
-               }
-               err = rss_hash_rss_conf_new_key(priv,
-                                               rss_hash_default_key,
-                                               rss_hash_default_key_len,
-                                               ETH_RSS_PROTO_MASK);
-               if (err)
-                       goto port_error;
                /* Configure the first MAC address by default. */
                if (priv_get_mac(priv, &mac.addr_bytes)) {
                        ERROR("cannot get MAC address, is mlx5_en loaded?"
@@ -898,10 +882,8 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                continue;
 
 port_error:
-               if (priv) {
-                       rte_free(priv->rss_conf);
+               if (priv)
                        rte_free(priv);
-               }
                if (pd)
                        claim_zero(ibv_dealloc_pd(pd));
                if (ctx)
index e83961f..4718506 100644 (file)
@@ -134,9 +134,7 @@ struct priv {
        /* Hash RX QPs feeding the indirection table. */
        struct hash_rxq (*hash_rxqs)[];
        unsigned int hash_rxqs_n; /* Hash RX QPs array size. */
-       /* RSS configuration array indexed by hash RX queue type. */
-       struct rte_eth_rss_conf *(*rss_conf)[];
-       uint64_t rss_hf; /* RSS DPDK bit field of active RSS. */
+       struct rte_eth_rss_conf rss_conf; /* RSS configuration. */
        struct rte_intr_handle intr_handle; /* Interrupt handler. */
        unsigned int (*reta_idx)[]; /* RETA index table. */
        unsigned int reta_idx_n; /* RETA index size. */
@@ -226,8 +224,6 @@ void mlx5_mac_addr_set(struct rte_eth_dev *, struct ether_addr *);
 
 /* mlx5_rss.c */
 
-int rss_hash_rss_conf_new_key(struct priv *, const uint8_t *, unsigned int,
-                             uint64_t);
 int mlx5_rss_hash_update(struct rte_eth_dev *, struct rte_eth_rss_conf *);
 int mlx5_rss_hash_conf_get(struct rte_eth_dev *, struct rte_eth_rss_conf *);
 int priv_rss_reta_index_resize(struct priv *, unsigned int);
index 318bc9d..9f5b489 100644 (file)
@@ -575,8 +575,29 @@ dev_configure(struct rte_eth_dev *dev)
        unsigned int i;
        unsigned int j;
        unsigned int reta_idx_n;
+       const uint8_t use_app_rss_key =
+               !!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len;
 
-       priv->rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
+       if (use_app_rss_key &&
+           (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
+            rss_hash_default_key_len)) {
+               /* MLX5 RSS only support 40bytes key. */
+               return EINVAL;
+       }
+       priv->rss_conf.rss_key =
+               rte_realloc(priv->rss_conf.rss_key,
+                           rss_hash_default_key_len, 0);
+       if (!priv->rss_conf.rss_key) {
+               ERROR("cannot allocate RSS hash key memory (%u)", rxqs_n);
+               return ENOMEM;
+       }
+       memcpy(priv->rss_conf.rss_key,
+              use_app_rss_key ?
+              dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key :
+              rss_hash_default_key,
+              rss_hash_default_key_len);
+       priv->rss_conf.rss_key_len = rss_hash_default_key_len;
+       priv->rss_conf.rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
        priv->rxqs = (void *)dev->data->rx_queues;
        priv->txqs = (void *)dev->data->tx_queues;
        if (txqs_n != priv->txqs_n) {
@@ -694,9 +715,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
                info->if_index = if_nametoindex(ifname);
        info->reta_size = priv->reta_idx_n ?
                priv->reta_idx_n : priv->ind_table_max_size;
-       info->hash_key_size = ((*priv->rss_conf) ?
-                              (*priv->rss_conf)[0]->rss_key_len :
-                              0);
+       info->hash_key_size = priv->rss_conf.rss_key_len;
        info->speed_capa = priv->link_speed_capa;
        priv_unlock(priv);
 }
index 8942879..ad6d9ab 100644 (file)
 #include "mlx5.h"
 #include "mlx5_rxtx.h"
 
-/**
- * Get a RSS configuration hash key.
- *
- * @param priv
- *   Pointer to private structure.
- * @param rss_hf
- *   RSS hash functions configuration must be retrieved for.
- *
- * @return
- *   Pointer to a RSS configuration structure or NULL if rss_hf cannot
- *   be matched.
- */
-static struct rte_eth_rss_conf *
-rss_hash_get(struct priv *priv, uint64_t rss_hf)
-{
-       unsigned int i;
-
-       for (i = 0; (i != hash_rxq_init_n); ++i) {
-               uint64_t dpdk_rss_hf = hash_rxq_init[i].dpdk_rss_hf;
-
-               if (!(dpdk_rss_hf & rss_hf))
-                       continue;
-               return (*priv->rss_conf)[i];
-       }
-       return NULL;
-}
-
-/**
- * Register a RSS key.
- *
- * @param priv
- *   Pointer to private structure.
- * @param key
- *   Hash key to register.
- * @param key_len
- *   Hash key length in bytes.
- * @param rss_hf
- *   RSS hash functions the provided key applies to.
- *
- * @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, uint64_t rss_hf)
-{
-       unsigned int i;
-
-       for (i = 0; (i != hash_rxq_init_n); ++i) {
-               struct rte_eth_rss_conf *rss_conf;
-               uint64_t dpdk_rss_hf = hash_rxq_init[i].dpdk_rss_hf;
-
-               if (!(dpdk_rss_hf & rss_hf))
-                       continue;
-               rss_conf = rte_realloc((*priv->rss_conf)[i],
-                                      (sizeof(*rss_conf) + key_len),
-                                      0);
-               if (!rss_conf)
-                       return ENOMEM;
-               rss_conf->rss_key = (void *)(rss_conf + 1);
-               rss_conf->rss_key_len = key_len;
-               rss_conf->rss_hf = dpdk_rss_hf;
-               memcpy(rss_conf->rss_key, key, key_len);
-               (*priv->rss_conf)[i] = rss_conf;
-       }
-       return 0;
-}
-
 /**
  * DPDK callback to update the RSS hash configuration.
  *
@@ -137,23 +69,24 @@ mlx5_rss_hash_update(struct rte_eth_dev *dev,
                     struct rte_eth_rss_conf *rss_conf)
 {
        struct priv *priv = dev->data->dev_private;
-       int err = 0;
+       int ret = 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,
-                                               rss_conf->rss_hf);
-       /* Store protocols for which RSS is enabled. */
-       priv->rss_hf = rss_conf->rss_hf;
+       if (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);
-       assert(err >= 0);
-       return -err;
+       return ret;
 }
 
 /**
@@ -172,28 +105,22 @@ mlx5_rss_hash_conf_get(struct rte_eth_dev *dev,
                       struct rte_eth_rss_conf *rss_conf)
 {
        struct priv *priv = dev->data->dev_private;
-       struct rte_eth_rss_conf *priv_rss_conf;
+       int ret = 0;
 
        priv_lock(priv);
-
-       assert(priv->rss_conf != NULL);
-
-       priv_rss_conf = rss_hash_get(priv, rss_conf->rss_hf);
-       if (!priv_rss_conf) {
-               rss_conf->rss_hf = 0;
-               priv_unlock(priv);
-               return -EINVAL;
+       if (!rss_conf->rss_key) {
+               ret = -ENOMEM;
+               goto out;
        }
-       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;
-
+       if (rss_conf->rss_key_len < priv->rss_conf.rss_key_len) {
+               ret = -EINVAL;
+               goto out;
+       }
+       memcpy(rss_conf->rss_key, priv->rss_conf.rss_key,
+              priv->rss_conf.rss_key_len);
+out:
        priv_unlock(priv);
-       return 0;
+       return ret;
 }
 
 /**
index c603d2b..d37dfbb 100644 (file)
@@ -299,7 +299,7 @@ priv_make_ind_table_init(struct priv *priv,
        /* Mandatory to receive frames not handled by normal hash RX queues. */
        unsigned int hash_types_sup = 1 << HASH_RXQ_ETH;
 
-       rss_hf = priv->rss_hf;
+       rss_hf = priv->rss_conf.rss_hf;
        /* Process other protocols only if more than one queue. */
        if (priv->rxqs_n > 1)
                for (i = 0; (i != hash_rxq_init_n); ++i)
@@ -435,8 +435,7 @@ priv_create_hash_rxqs(struct priv *priv)
                struct hash_rxq *hash_rxq = &(*hash_rxqs)[i];
                enum hash_rxq_type type =
                        hash_rxq_type_from_pos(&ind_table_init[j], k);
-               struct rte_eth_rss_conf *priv_rss_conf =
-                       (*priv->rss_conf)[type];
+               struct rte_eth_rss_conf *priv_rss_conf = &priv->rss_conf;
                struct ibv_rx_hash_conf hash_conf = {
                        .rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ,
                        .rx_hash_key_len = (priv_rss_conf ?