}
/**
- * 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;
}
/**
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);
" 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;
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,
++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 = {
.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),