net/mlx5e: Fix wrong max num channels indication
No XSK support in the enhanced IPoIB driver and representors.
Add a profile property to specify this, and enhance the logic
that calculates the max number of channels to take it into
account.
Fixes: db05815b36
("net/mlx5e: Add XSK zero-copy support")
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
This commit is contained in:
Родитель
7a32f2962c
Коммит
694826e366
|
@ -159,7 +159,7 @@ do { \
|
|||
enum mlx5e_rq_group {
|
||||
MLX5E_RQ_GROUP_REGULAR,
|
||||
MLX5E_RQ_GROUP_XSK,
|
||||
MLX5E_NUM_RQ_GROUPS /* Keep last. */
|
||||
#define MLX5E_NUM_RQ_GROUPS(g) (1 + MLX5E_RQ_GROUP_##g)
|
||||
};
|
||||
|
||||
static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
|
||||
|
@ -182,14 +182,6 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
|
|||
min_t(int, mlx5_comp_vectors_count(mdev), MLX5E_MAX_NUM_CHANNELS);
|
||||
}
|
||||
|
||||
/* Use this function to get max num channels after netdev was created */
|
||||
static inline int mlx5e_get_netdev_max_channels(struct net_device *netdev)
|
||||
{
|
||||
return min_t(unsigned int,
|
||||
netdev->num_rx_queues / MLX5E_NUM_RQ_GROUPS,
|
||||
netdev->num_tx_queues);
|
||||
}
|
||||
|
||||
struct mlx5e_tx_wqe {
|
||||
struct mlx5_wqe_ctrl_seg ctrl;
|
||||
struct mlx5_wqe_eth_seg eth;
|
||||
|
@ -830,6 +822,7 @@ struct mlx5e_priv {
|
|||
struct net_device *netdev;
|
||||
struct mlx5e_stats stats;
|
||||
struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS];
|
||||
u16 max_nch;
|
||||
u8 max_opened_tc;
|
||||
struct hwtstamp_config tstamp;
|
||||
u16 q_counter;
|
||||
|
@ -871,6 +864,7 @@ struct mlx5e_profile {
|
|||
mlx5e_fp_handle_rx_cqe handle_rx_cqe_mpwqe;
|
||||
} rx_handlers;
|
||||
int max_tc;
|
||||
u8 rq_groups;
|
||||
};
|
||||
|
||||
void mlx5e_build_ptys2ethtool_map(void);
|
||||
|
|
|
@ -66,9 +66,10 @@ static inline void mlx5e_qid_get_ch_and_group(struct mlx5e_params *params,
|
|||
*group = qid / nch;
|
||||
}
|
||||
|
||||
static inline bool mlx5e_qid_validate(struct mlx5e_params *params, u64 qid)
|
||||
static inline bool mlx5e_qid_validate(const struct mlx5e_profile *profile,
|
||||
struct mlx5e_params *params, u64 qid)
|
||||
{
|
||||
return qid < params->num_channels * MLX5E_NUM_RQ_GROUPS;
|
||||
return qid < params->num_channels * profile->rq_groups;
|
||||
}
|
||||
|
||||
/* Parameter calculations */
|
||||
|
|
|
@ -391,7 +391,7 @@ void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
|
|||
{
|
||||
mutex_lock(&priv->state_lock);
|
||||
|
||||
ch->max_combined = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
ch->max_combined = priv->max_nch;
|
||||
ch->combined_count = priv->channels.params.num_channels;
|
||||
if (priv->xsk.refcnt) {
|
||||
/* The upper half are XSK queues. */
|
||||
|
|
|
@ -611,7 +611,8 @@ static int validate_flow(struct mlx5e_priv *priv,
|
|||
return -ENOSPC;
|
||||
|
||||
if (fs->ring_cookie != RX_CLS_FLOW_DISC)
|
||||
if (!mlx5e_qid_validate(&priv->channels.params, fs->ring_cookie))
|
||||
if (!mlx5e_qid_validate(priv->profile, &priv->channels.params,
|
||||
fs->ring_cookie))
|
||||
return -EINVAL;
|
||||
|
||||
switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
|
||||
|
|
|
@ -1677,10 +1677,10 @@ static int mlx5e_open_sqs(struct mlx5e_channel *c,
|
|||
struct mlx5e_channel_param *cparam)
|
||||
{
|
||||
struct mlx5e_priv *priv = c->priv;
|
||||
int err, tc, max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
int err, tc;
|
||||
|
||||
for (tc = 0; tc < params->num_tc; tc++) {
|
||||
int txq_ix = c->ix + tc * max_nch;
|
||||
int txq_ix = c->ix + tc * priv->max_nch;
|
||||
|
||||
err = mlx5e_open_txqsq(c, c->priv->tisn[tc], txq_ix,
|
||||
params, &cparam->sq, &c->sq[tc], tc);
|
||||
|
@ -2438,11 +2438,10 @@ int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv)
|
|||
|
||||
int mlx5e_create_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
|
||||
{
|
||||
const int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
int err;
|
||||
int ix;
|
||||
|
||||
for (ix = 0; ix < max_nch; ix++) {
|
||||
for (ix = 0; ix < priv->max_nch; ix++) {
|
||||
err = mlx5e_create_rqt(priv, 1 /*size */, &tirs[ix].rqt);
|
||||
if (unlikely(err))
|
||||
goto err_destroy_rqts;
|
||||
|
@ -2460,10 +2459,9 @@ err_destroy_rqts:
|
|||
|
||||
void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
|
||||
{
|
||||
const int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < max_nch; i++)
|
||||
for (i = 0; i < priv->max_nch; i++)
|
||||
mlx5e_destroy_rqt(priv, &tirs[i].rqt);
|
||||
}
|
||||
|
||||
|
@ -2557,7 +2555,7 @@ static void mlx5e_redirect_rqts(struct mlx5e_priv *priv,
|
|||
mlx5e_redirect_rqt(priv, rqtn, MLX5E_INDIR_RQT_SIZE, rrp);
|
||||
}
|
||||
|
||||
for (ix = 0; ix < mlx5e_get_netdev_max_channels(priv->netdev); ix++) {
|
||||
for (ix = 0; ix < priv->max_nch; ix++) {
|
||||
struct mlx5e_redirect_rqt_param direct_rrp = {
|
||||
.is_rss = false,
|
||||
{
|
||||
|
@ -2758,7 +2756,7 @@ static int mlx5e_modify_tirs_lro(struct mlx5e_priv *priv)
|
|||
goto free_in;
|
||||
}
|
||||
|
||||
for (ix = 0; ix < mlx5e_get_netdev_max_channels(priv->netdev); ix++) {
|
||||
for (ix = 0; ix < priv->max_nch; ix++) {
|
||||
err = mlx5_core_modify_tir(mdev, priv->direct_tir[ix].tirn,
|
||||
in, inlen);
|
||||
if (err)
|
||||
|
@ -2858,12 +2856,11 @@ static void mlx5e_netdev_set_tcs(struct net_device *netdev)
|
|||
|
||||
static void mlx5e_build_tc2txq_maps(struct mlx5e_priv *priv)
|
||||
{
|
||||
int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
int i, tc;
|
||||
|
||||
for (i = 0; i < max_nch; i++)
|
||||
for (i = 0; i < priv->max_nch; i++)
|
||||
for (tc = 0; tc < priv->profile->max_tc; tc++)
|
||||
priv->channel_tc2txq[i][tc] = i + tc * max_nch;
|
||||
priv->channel_tc2txq[i][tc] = i + tc * priv->max_nch;
|
||||
}
|
||||
|
||||
static void mlx5e_build_tx2sq_maps(struct mlx5e_priv *priv)
|
||||
|
@ -2884,7 +2881,7 @@ static void mlx5e_build_tx2sq_maps(struct mlx5e_priv *priv)
|
|||
void mlx5e_activate_priv_channels(struct mlx5e_priv *priv)
|
||||
{
|
||||
int num_txqs = priv->channels.num * priv->channels.params.num_tc;
|
||||
int num_rxqs = priv->channels.num * MLX5E_NUM_RQ_GROUPS;
|
||||
int num_rxqs = priv->channels.num * priv->profile->rq_groups;
|
||||
struct net_device *netdev = priv->netdev;
|
||||
|
||||
mlx5e_netdev_set_tcs(netdev);
|
||||
|
@ -3306,7 +3303,6 @@ err_destroy_inner_tirs:
|
|||
|
||||
int mlx5e_create_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
|
||||
{
|
||||
const int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
struct mlx5e_tir *tir;
|
||||
void *tirc;
|
||||
int inlen;
|
||||
|
@ -3319,7 +3315,7 @@ int mlx5e_create_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
|
|||
if (!in)
|
||||
return -ENOMEM;
|
||||
|
||||
for (ix = 0; ix < max_nch; ix++) {
|
||||
for (ix = 0; ix < priv->max_nch; ix++) {
|
||||
memset(in, 0, inlen);
|
||||
tir = &tirs[ix];
|
||||
tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
|
||||
|
@ -3358,10 +3354,9 @@ void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc)
|
|||
|
||||
void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
|
||||
{
|
||||
const int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < max_nch; i++)
|
||||
for (i = 0; i < priv->max_nch; i++)
|
||||
mlx5e_destroy_tir(priv->mdev, &tirs[i]);
|
||||
}
|
||||
|
||||
|
@ -3487,7 +3482,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mlx5e_get_netdev_max_channels(priv->netdev); i++) {
|
||||
for (i = 0; i < priv->max_nch; i++) {
|
||||
struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i];
|
||||
struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq;
|
||||
struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
|
||||
|
@ -4960,8 +4955,7 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
|
|||
return err;
|
||||
|
||||
mlx5e_build_nic_params(mdev, &priv->xsk, rss, &priv->channels.params,
|
||||
mlx5e_get_netdev_max_channels(netdev),
|
||||
netdev->mtu);
|
||||
priv->max_nch, netdev->mtu);
|
||||
|
||||
mlx5e_timestamp_init(priv);
|
||||
|
||||
|
@ -5164,6 +5158,7 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
|
|||
.rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe,
|
||||
.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
|
||||
.max_tc = MLX5E_MAX_NUM_TC,
|
||||
.rq_groups = MLX5E_NUM_RQ_GROUPS(XSK),
|
||||
};
|
||||
|
||||
/* mlx5e generic netdev management API (move to en_common.c) */
|
||||
|
@ -5181,6 +5176,7 @@ int mlx5e_netdev_init(struct net_device *netdev,
|
|||
priv->profile = profile;
|
||||
priv->ppriv = ppriv;
|
||||
priv->msglevel = MLX5E_MSG_LEVEL;
|
||||
priv->max_nch = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
|
||||
priv->max_opened_tc = 1;
|
||||
|
||||
mutex_init(&priv->state_lock);
|
||||
|
@ -5218,7 +5214,7 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
|
|||
|
||||
netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv),
|
||||
nch * profile->max_tc,
|
||||
nch * MLX5E_NUM_RQ_GROUPS);
|
||||
nch * profile->rq_groups);
|
||||
if (!netdev) {
|
||||
mlx5_core_err(mdev, "alloc_etherdev_mqs() failed\n");
|
||||
return NULL;
|
||||
|
|
|
@ -1702,6 +1702,7 @@ static const struct mlx5e_profile mlx5e_rep_profile = {
|
|||
.rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe_rep,
|
||||
.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
|
||||
.max_tc = 1,
|
||||
.rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
|
||||
};
|
||||
|
||||
static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
|
||||
|
@ -1719,6 +1720,7 @@ static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
|
|||
.rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe_rep,
|
||||
.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
|
||||
.max_tc = MLX5E_MAX_NUM_TC,
|
||||
.rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
|
||||
};
|
||||
|
||||
static bool
|
||||
|
|
|
@ -172,7 +172,7 @@ static void mlx5e_grp_sw_update_stats(struct mlx5e_priv *priv)
|
|||
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
for (i = 0; i < mlx5e_get_netdev_max_channels(priv->netdev); i++) {
|
||||
for (i = 0; i < priv->max_nch; i++) {
|
||||
struct mlx5e_channel_stats *channel_stats =
|
||||
&priv->channel_stats[i];
|
||||
struct mlx5e_xdpsq_stats *xdpsq_red_stats = &channel_stats->xdpsq;
|
||||
|
@ -1395,7 +1395,7 @@ static const struct counter_desc ch_stats_desc[] = {
|
|||
|
||||
static int mlx5e_grp_channels_get_num_stats(struct mlx5e_priv *priv)
|
||||
{
|
||||
int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
int max_nch = priv->max_nch;
|
||||
|
||||
return (NUM_RQ_STATS * max_nch) +
|
||||
(NUM_CH_STATS * max_nch) +
|
||||
|
@ -1409,8 +1409,8 @@ static int mlx5e_grp_channels_get_num_stats(struct mlx5e_priv *priv)
|
|||
static int mlx5e_grp_channels_fill_strings(struct mlx5e_priv *priv, u8 *data,
|
||||
int idx)
|
||||
{
|
||||
int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
bool is_xsk = priv->xsk.ever_used;
|
||||
int max_nch = priv->max_nch;
|
||||
int i, j, tc;
|
||||
|
||||
for (i = 0; i < max_nch; i++)
|
||||
|
@ -1452,8 +1452,8 @@ static int mlx5e_grp_channels_fill_strings(struct mlx5e_priv *priv, u8 *data,
|
|||
static int mlx5e_grp_channels_fill_stats(struct mlx5e_priv *priv, u64 *data,
|
||||
int idx)
|
||||
{
|
||||
int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
bool is_xsk = priv->xsk.ever_used;
|
||||
int max_nch = priv->max_nch;
|
||||
int i, j, tc;
|
||||
|
||||
for (i = 0; i < max_nch; i++)
|
||||
|
|
|
@ -88,8 +88,7 @@ int mlx5i_init(struct mlx5_core_dev *mdev,
|
|||
netdev->mtu = netdev->max_mtu;
|
||||
|
||||
mlx5e_build_nic_params(mdev, NULL, &priv->rss_params, &priv->channels.params,
|
||||
mlx5e_get_netdev_max_channels(netdev),
|
||||
netdev->mtu);
|
||||
priv->max_nch, netdev->mtu);
|
||||
mlx5i_build_nic_params(mdev, &priv->channels.params);
|
||||
|
||||
mlx5e_timestamp_init(priv);
|
||||
|
@ -118,11 +117,10 @@ void mlx5i_cleanup(struct mlx5e_priv *priv)
|
|||
|
||||
static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv)
|
||||
{
|
||||
int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
|
||||
struct mlx5e_sw_stats s = { 0 };
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < max_nch; i++) {
|
||||
for (i = 0; i < priv->max_nch; i++) {
|
||||
struct mlx5e_channel_stats *channel_stats;
|
||||
struct mlx5e_rq_stats *rq_stats;
|
||||
|
||||
|
@ -436,6 +434,7 @@ static const struct mlx5e_profile mlx5i_nic_profile = {
|
|||
.rx_handlers.handle_rx_cqe = mlx5i_handle_rx_cqe,
|
||||
.rx_handlers.handle_rx_cqe_mpwqe = NULL, /* Not supported */
|
||||
.max_tc = MLX5I_MAX_NUM_TC,
|
||||
.rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
|
||||
};
|
||||
|
||||
/* mlx5i netdev NDos */
|
||||
|
|
|
@ -355,6 +355,7 @@ static const struct mlx5e_profile mlx5i_pkey_nic_profile = {
|
|||
.rx_handlers.handle_rx_cqe = mlx5i_handle_rx_cqe,
|
||||
.rx_handlers.handle_rx_cqe_mpwqe = NULL, /* Not supported */
|
||||
.max_tc = MLX5I_MAX_NUM_TC,
|
||||
.rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
|
||||
};
|
||||
|
||||
const struct mlx5e_profile *mlx5i_pkey_get_profile(void)
|
||||
|
|
Загрузка…
Ссылка в новой задаче