bnx2x: fix restart
[dpdk.git] / drivers / net / mlx5 / mlx5_rxq.c
index 084bf41..37b4efd 100644 (file)
@@ -259,43 +259,29 @@ hash_rxq_flow_attr(const struct hash_rxq *hash_rxq,
 }
 
 /**
- * Return nearest power of two above input value.
- *
- * @param v
- *   Input value.
- *
- * @return
- *   Nearest power of two above input value.
- */
-static unsigned int
-log2above(unsigned int v)
-{
-       unsigned int l;
-       unsigned int r;
-
-       for (l = 0, r = 0; (v >> 1); ++l, v >>= 1)
-               r |= (v & 1);
-       return (l + r);
-}
-
-/**
- * Return the type corresponding to the n'th bit set.
+ * Convert hash type position in indirection table initializer to
+ * hash RX queue type.
  *
  * @param table
- *   The indirection table.
- * @param n
- *   The n'th bit set.
+ *   Indirection table initializer.
+ * @param pos
+ *   Hash type position.
  *
  * @return
- *   The corresponding hash_rxq_type.
+ *   Hash RX queue type.
  */
 static enum hash_rxq_type
-hash_rxq_type_from_n(const struct ind_table_init *table, unsigned int n)
+hash_rxq_type_from_pos(const struct ind_table_init *table, unsigned int pos)
 {
-       assert(n < table->hash_types_n);
-       while (((table->hash_types >> n) & 0x1) == 0)
-               ++n;
-       return n;
+       enum hash_rxq_type type = 0;
+
+       assert(pos < table->hash_types_n);
+       do {
+               if ((table->hash_types & (1 << type)) && (pos-- == 0))
+                       break;
+               ++type;
+       } while (1);
+       return type;
 }
 
 /**
@@ -360,14 +346,7 @@ priv_make_ind_table_init(struct priv *priv,
 int
 priv_create_hash_rxqs(struct priv *priv)
 {
-       /* If the requested number of WQs is not a power of two, use the
-        * maximum indirection table size for better balancing.
-        * The result is always rounded to the next power of two. */
-       unsigned int wqs_n =
-               (1 << log2above((priv->rxqs_n & (priv->rxqs_n - 1)) ?
-                               priv->ind_table_max_size :
-                               priv->rxqs_n));
-       struct ibv_exp_wq *wqs[wqs_n];
+       struct ibv_exp_wq *wqs[priv->reta_idx_n];
        struct ind_table_init ind_table_init[IND_TABLE_INIT_N];
        unsigned int ind_tables_n =
                priv_make_ind_table_init(priv, &ind_table_init);
@@ -393,25 +372,15 @@ priv_create_hash_rxqs(struct priv *priv)
                      " indirection table cannot be created");
                return EINVAL;
        }
-       if ((wqs_n < priv->rxqs_n) || (wqs_n > priv->ind_table_max_size)) {
-               ERROR("cannot handle this many RX queues (%u)", priv->rxqs_n);
-               err = ERANGE;
-               goto error;
-       }
-       if (wqs_n != priv->rxqs_n) {
+       if (priv->rxqs_n & (priv->rxqs_n - 1)) {
                INFO("%u RX queues are configured, consider rounding this"
                     " number to the next power of two for better balancing",
                     priv->rxqs_n);
-               DEBUG("indirection table extended to assume %u WQs", wqs_n);
-       }
-       /* When the number of RX queues is not a power of two, the remaining
-        * table entries are padded with reused WQs and hashes are not spread
-        * uniformly. */
-       for (i = 0, j = 0; (i != wqs_n); ++i) {
-               wqs[i] = (*priv->rxqs)[j]->wq;
-               if (++j == priv->rxqs_n)
-                       j = 0;
+               DEBUG("indirection table extended to assume %u WQs",
+                     priv->reta_idx_n);
        }
+       for (i = 0; (i != priv->reta_idx_n); ++i)
+               wqs[i] = (*priv->rxqs)[(*priv->reta_idx)[i]]->wq;
        /* Get number of hash RX queues to configure. */
        for (i = 0, hash_rxqs_n = 0; (i != ind_tables_n); ++i)
                hash_rxqs_n += ind_table_init[i].hash_types_n;
@@ -436,8 +405,8 @@ priv_create_hash_rxqs(struct priv *priv)
                unsigned int ind_tbl_size = ind_table_init[i].max_size;
                struct ibv_exp_rwq_ind_table *ind_table;
 
-               if (wqs_n < ind_tbl_size)
-                       ind_tbl_size = wqs_n;
+               if (priv->reta_idx_n < ind_tbl_size)
+                       ind_tbl_size = priv->reta_idx_n;
                ind_init_attr.log_ind_tbl_size = log2above(ind_tbl_size);
                errno = 0;
                ind_table = ibv_exp_create_rwq_ind_table(priv->ctx,
@@ -466,7 +435,7 @@ priv_create_hash_rxqs(struct priv *priv)
             ++i) {
                struct hash_rxq *hash_rxq = &(*hash_rxqs)[i];
                enum hash_rxq_type type =
-                       hash_rxq_type_from_n(&ind_table_init[j], k);
+                       hash_rxq_type_from_pos(&ind_table_init[j], k);
                struct rte_eth_rss_conf *priv_rss_conf =
                        (*priv->rss_conf)[type];
                struct ibv_exp_rx_hash_conf hash_conf = {
@@ -490,8 +459,8 @@ priv_create_hash_rxqs(struct priv *priv)
                        .port_num = priv->port,
                };
 
-               DEBUG("using indirection table %u for hash RX queue %u",
-                     j, i);
+               DEBUG("using indirection table %u for hash RX queue %u type %d",
+                     j, i, type);
                *hash_rxq = (struct hash_rxq){
                        .priv = priv,
                        .qp = ibv_exp_create_qp(priv->ctx, &qp_init_attr),