Commit 49e6c938 authored by Carolina Jubran's avatar Carolina Jubran Committed by Jakub Kicinski

net/mlx5e: RSS, Block XOR hash with over 128 channels

When supporting more than 128 channels, the RQT size is
calculated by multiplying the number of channels by 2
and rounding up to the nearest power of 2.

The index of the RQT is derived from the RSS hash
calculations. If XOR8 is used as the RSS hash function,
there are only 256 possible hash results, and therefore,
only 256 indexes can be reached in the RQT.

Block setting the RSS hash function to XOR when the number
of channels exceeds 128.

Fixes: 74a8dada ("net/mlx5e: Preparations for supporting larger number of channels")
Signed-off-by: default avatarCarolina Jubran <cjubran@nvidia.com>
Signed-off-by: default avatarTariq Toukan <tariqt@nvidia.com>
Link: https://lore.kernel.org/r/20240409190820.227554-11-tariqt@nvidia.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 86b0ca5b
...@@ -179,6 +179,13 @@ u32 mlx5e_rqt_size(struct mlx5_core_dev *mdev, unsigned int num_channels) ...@@ -179,6 +179,13 @@ u32 mlx5e_rqt_size(struct mlx5_core_dev *mdev, unsigned int num_channels)
return min_t(u32, rqt_size, max_cap_rqt_size); return min_t(u32, rqt_size, max_cap_rqt_size);
} }
#define MLX5E_MAX_RQT_SIZE_ALLOWED_WITH_XOR8_HASH 256
unsigned int mlx5e_rqt_max_num_channels_allowed_for_xor8(void)
{
return MLX5E_MAX_RQT_SIZE_ALLOWED_WITH_XOR8_HASH / MLX5E_UNIFORM_SPREAD_RQT_FACTOR;
}
void mlx5e_rqt_destroy(struct mlx5e_rqt *rqt) void mlx5e_rqt_destroy(struct mlx5e_rqt *rqt)
{ {
mlx5_core_destroy_rqt(rqt->mdev, rqt->rqtn); mlx5_core_destroy_rqt(rqt->mdev, rqt->rqtn);
......
...@@ -38,6 +38,7 @@ static inline u32 mlx5e_rqt_get_rqtn(struct mlx5e_rqt *rqt) ...@@ -38,6 +38,7 @@ static inline u32 mlx5e_rqt_get_rqtn(struct mlx5e_rqt *rqt)
} }
u32 mlx5e_rqt_size(struct mlx5_core_dev *mdev, unsigned int num_channels); u32 mlx5e_rqt_size(struct mlx5_core_dev *mdev, unsigned int num_channels);
unsigned int mlx5e_rqt_max_num_channels_allowed_for_xor8(void);
int mlx5e_rqt_redirect_direct(struct mlx5e_rqt *rqt, u32 rqn, u32 *vhca_id); int mlx5e_rqt_redirect_direct(struct mlx5e_rqt *rqt, u32 rqn, u32 *vhca_id);
int mlx5e_rqt_redirect_indir(struct mlx5e_rqt *rqt, u32 *rqns, u32 *vhca_ids, int mlx5e_rqt_redirect_indir(struct mlx5e_rqt *rqt, u32 *rqns, u32 *vhca_ids,
unsigned int num_rqns, unsigned int num_rqns,
......
...@@ -451,6 +451,17 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv, ...@@ -451,6 +451,17 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
if (mlx5e_rx_res_get_current_hash(priv->rx_res).hfunc == ETH_RSS_HASH_XOR) {
unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8();
if (count > xor8_max_channels) {
err = -EINVAL;
netdev_err(priv->netdev, "%s: Requested number of channels (%d) exceeds the maximum allowed by the XOR8 RSS hfunc (%d)\n",
__func__, count, xor8_max_channels);
goto out;
}
}
/* If RXFH is configured, changing the channels number is allowed only if /* If RXFH is configured, changing the channels number is allowed only if
* it does not require resizing the RSS table. This is because the previous * it does not require resizing the RSS table. This is because the previous
* configuration may no longer be compatible with the new RSS table. * configuration may no longer be compatible with the new RSS table.
...@@ -1298,17 +1309,30 @@ int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh, ...@@ -1298,17 +1309,30 @@ int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
u32 *rss_context = &rxfh->rss_context; u32 *rss_context = &rxfh->rss_context;
u8 hfunc = rxfh->hfunc; u8 hfunc = rxfh->hfunc;
unsigned int count;
int err; int err;
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
count = priv->channels.params.num_channels;
if (hfunc == ETH_RSS_HASH_XOR) {
unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8();
if (count > xor8_max_channels) {
err = -EINVAL;
netdev_err(priv->netdev, "%s: Cannot set RSS hash function to XOR, current number of channels (%d) exceeds the maximum allowed for XOR8 RSS hfunc (%d)\n",
__func__, count, xor8_max_channels);
goto unlock;
}
}
if (*rss_context && rxfh->rss_delete) { if (*rss_context && rxfh->rss_delete) {
err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context); err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context);
goto unlock; goto unlock;
} }
if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) { if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
unsigned int count = priv->channels.params.num_channels;
err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count); err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count);
if (err) if (err)
goto unlock; goto unlock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment