mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 19:07:52 +00:00
net/mlx4_en: Optimized single ring steering
Avoid touching RX QP RSS context when loading with only one RX ring, to allow optimized A0 RX steering. Enable by: - loading mlx4_core with module param: log_num_mgm_entry_size = -6. - then: ethtool -L <interface> rx 1 Performance tests: Tested on ConnectX3Pro, Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz XDP_DROP packet rate: ------------------------------------- | Before | After | Gain | IPv4 | 20.5 Mpps | 28.1 Mpps | 37% | IPv6 | 18.4 Mpps | 28.1 Mpps | 53% | ------------------------------------- Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: Tariq Toukan <tariqt@mellanox.com> Cc: kernel-team@fb.com Cc: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
cf97050d54
commit
4931c6ef04
5 changed files with 50 additions and 22 deletions
|
@ -125,9 +125,9 @@ void mlx4_en_update_loopback_state(struct net_device *dev,
|
||||||
priv->flags |= MLX4_EN_FLAG_ENABLE_HW_LOOPBACK;
|
priv->flags |= MLX4_EN_FLAG_ENABLE_HW_LOOPBACK;
|
||||||
|
|
||||||
mutex_lock(&priv->mdev->state_lock);
|
mutex_lock(&priv->mdev->state_lock);
|
||||||
if (priv->mdev->dev->caps.flags2 &
|
if ((priv->mdev->dev->caps.flags2 &
|
||||||
MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB &&
|
MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB) &&
|
||||||
priv->rss_map.indir_qp.qpn) {
|
priv->rss_map.indir_qp && priv->rss_map.indir_qp->qpn) {
|
||||||
int i;
|
int i;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int loopback = !!(features & NETIF_F_LOOPBACK);
|
int loopback = !!(features & NETIF_F_LOOPBACK);
|
||||||
|
|
|
@ -596,6 +596,8 @@ static int mlx4_en_get_qp(struct mlx4_en_priv *priv)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
en_info(priv, "Steering Mode %d\n", dev->caps.steering_mode);
|
||||||
|
|
||||||
if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) {
|
if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) {
|
||||||
int base_qpn = mlx4_get_base_qpn(dev, priv->port);
|
int base_qpn = mlx4_get_base_qpn(dev, priv->port);
|
||||||
*qpn = base_qpn + index;
|
*qpn = base_qpn + index;
|
||||||
|
@ -1010,7 +1012,7 @@ static void mlx4_en_do_multicast(struct mlx4_en_priv *priv,
|
||||||
memcpy(&mc_list[10], mclist->addr, ETH_ALEN);
|
memcpy(&mc_list[10], mclist->addr, ETH_ALEN);
|
||||||
mc_list[5] = priv->port;
|
mc_list[5] = priv->port;
|
||||||
err = mlx4_multicast_detach(mdev->dev,
|
err = mlx4_multicast_detach(mdev->dev,
|
||||||
&priv->rss_map.indir_qp,
|
priv->rss_map.indir_qp,
|
||||||
mc_list,
|
mc_list,
|
||||||
MLX4_PROT_ETH,
|
MLX4_PROT_ETH,
|
||||||
mclist->reg_id);
|
mclist->reg_id);
|
||||||
|
@ -1032,7 +1034,7 @@ static void mlx4_en_do_multicast(struct mlx4_en_priv *priv,
|
||||||
/* needed for B0 steering support */
|
/* needed for B0 steering support */
|
||||||
mc_list[5] = priv->port;
|
mc_list[5] = priv->port;
|
||||||
err = mlx4_multicast_attach(mdev->dev,
|
err = mlx4_multicast_attach(mdev->dev,
|
||||||
&priv->rss_map.indir_qp,
|
priv->rss_map.indir_qp,
|
||||||
mc_list,
|
mc_list,
|
||||||
priv->port, 0,
|
priv->port, 0,
|
||||||
MLX4_PROT_ETH,
|
MLX4_PROT_ETH,
|
||||||
|
@ -1742,7 +1744,7 @@ int mlx4_en_start_port(struct net_device *dev)
|
||||||
/* Attach rx QP to bradcast address */
|
/* Attach rx QP to bradcast address */
|
||||||
eth_broadcast_addr(&mc_list[10]);
|
eth_broadcast_addr(&mc_list[10]);
|
||||||
mc_list[5] = priv->port; /* needed for B0 steering support */
|
mc_list[5] = priv->port; /* needed for B0 steering support */
|
||||||
if (mlx4_multicast_attach(mdev->dev, &priv->rss_map.indir_qp, mc_list,
|
if (mlx4_multicast_attach(mdev->dev, priv->rss_map.indir_qp, mc_list,
|
||||||
priv->port, 0, MLX4_PROT_ETH,
|
priv->port, 0, MLX4_PROT_ETH,
|
||||||
&priv->broadcast_id))
|
&priv->broadcast_id))
|
||||||
mlx4_warn(mdev, "Failed Attaching Broadcast\n");
|
mlx4_warn(mdev, "Failed Attaching Broadcast\n");
|
||||||
|
@ -1866,12 +1868,12 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
|
||||||
/* Detach All multicasts */
|
/* Detach All multicasts */
|
||||||
eth_broadcast_addr(&mc_list[10]);
|
eth_broadcast_addr(&mc_list[10]);
|
||||||
mc_list[5] = priv->port; /* needed for B0 steering support */
|
mc_list[5] = priv->port; /* needed for B0 steering support */
|
||||||
mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list,
|
mlx4_multicast_detach(mdev->dev, priv->rss_map.indir_qp, mc_list,
|
||||||
MLX4_PROT_ETH, priv->broadcast_id);
|
MLX4_PROT_ETH, priv->broadcast_id);
|
||||||
list_for_each_entry(mclist, &priv->curr_list, list) {
|
list_for_each_entry(mclist, &priv->curr_list, list) {
|
||||||
memcpy(&mc_list[10], mclist->addr, ETH_ALEN);
|
memcpy(&mc_list[10], mclist->addr, ETH_ALEN);
|
||||||
mc_list[5] = priv->port;
|
mc_list[5] = priv->port;
|
||||||
mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp,
|
mlx4_multicast_detach(mdev->dev, priv->rss_map.indir_qp,
|
||||||
mc_list, MLX4_PROT_ETH, mclist->reg_id);
|
mc_list, MLX4_PROT_ETH, mclist->reg_id);
|
||||||
if (mclist->tunnel_reg_id)
|
if (mclist->tunnel_reg_id)
|
||||||
mlx4_flow_detach(mdev->dev, mclist->tunnel_reg_id);
|
mlx4_flow_detach(mdev->dev, mclist->tunnel_reg_id);
|
||||||
|
|
|
@ -1099,11 +1099,14 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
|
||||||
int i, qpn;
|
int i, qpn;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int good_qps = 0;
|
int good_qps = 0;
|
||||||
|
u8 flags;
|
||||||
|
|
||||||
en_dbg(DRV, priv, "Configuring rss steering\n");
|
en_dbg(DRV, priv, "Configuring rss steering\n");
|
||||||
|
|
||||||
|
flags = priv->rx_ring_num == 1 ? MLX4_RESERVE_A0_QP : 0;
|
||||||
err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num,
|
err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num,
|
||||||
priv->rx_ring_num,
|
priv->rx_ring_num,
|
||||||
&rss_map->base_qpn, 0);
|
&rss_map->base_qpn, flags);
|
||||||
if (err) {
|
if (err) {
|
||||||
en_err(priv, "Failed reserving %d qps\n", priv->rx_ring_num);
|
en_err(priv, "Failed reserving %d qps\n", priv->rx_ring_num);
|
||||||
return err;
|
return err;
|
||||||
|
@ -1120,13 +1123,28 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
|
||||||
++good_qps;
|
++good_qps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->rx_ring_num == 1) {
|
||||||
|
rss_map->indir_qp = &rss_map->qps[0];
|
||||||
|
priv->base_qpn = rss_map->indir_qp->qpn;
|
||||||
|
en_info(priv, "Optimized Non-RSS steering\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rss_map->indir_qp = kzalloc(sizeof(*rss_map->indir_qp), GFP_KERNEL);
|
||||||
|
if (!rss_map->indir_qp) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto rss_err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure RSS indirection qp */
|
/* Configure RSS indirection qp */
|
||||||
err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, &rss_map->indir_qp, GFP_KERNEL);
|
err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, rss_map->indir_qp,
|
||||||
|
GFP_KERNEL);
|
||||||
if (err) {
|
if (err) {
|
||||||
en_err(priv, "Failed to allocate RSS indirection QP\n");
|
en_err(priv, "Failed to allocate RSS indirection QP\n");
|
||||||
goto rss_err;
|
goto rss_err;
|
||||||
}
|
}
|
||||||
rss_map->indir_qp.event = mlx4_en_sqp_event;
|
|
||||||
|
rss_map->indir_qp->event = mlx4_en_sqp_event;
|
||||||
mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
|
mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
|
||||||
priv->rx_ring[0]->cqn, -1, &context);
|
priv->rx_ring[0]->cqn, -1, &context);
|
||||||
|
|
||||||
|
@ -1164,8 +1182,9 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto indir_err;
|
goto indir_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
|
err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
|
||||||
&rss_map->indir_qp, &rss_map->indir_state);
|
rss_map->indir_qp, &rss_map->indir_state);
|
||||||
if (err)
|
if (err)
|
||||||
goto indir_err;
|
goto indir_err;
|
||||||
|
|
||||||
|
@ -1173,9 +1192,11 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
|
||||||
|
|
||||||
indir_err:
|
indir_err:
|
||||||
mlx4_qp_modify(mdev->dev, NULL, rss_map->indir_state,
|
mlx4_qp_modify(mdev->dev, NULL, rss_map->indir_state,
|
||||||
MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->indir_qp);
|
MLX4_QP_STATE_RST, NULL, 0, 0, rss_map->indir_qp);
|
||||||
mlx4_qp_remove(mdev->dev, &rss_map->indir_qp);
|
mlx4_qp_remove(mdev->dev, rss_map->indir_qp);
|
||||||
mlx4_qp_free(mdev->dev, &rss_map->indir_qp);
|
mlx4_qp_free(mdev->dev, rss_map->indir_qp);
|
||||||
|
kfree(rss_map->indir_qp);
|
||||||
|
rss_map->indir_qp = NULL;
|
||||||
rss_err:
|
rss_err:
|
||||||
for (i = 0; i < good_qps; i++) {
|
for (i = 0; i < good_qps; i++) {
|
||||||
mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
|
mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
|
||||||
|
@ -1193,10 +1214,15 @@ void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv)
|
||||||
struct mlx4_en_rss_map *rss_map = &priv->rss_map;
|
struct mlx4_en_rss_map *rss_map = &priv->rss_map;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (priv->rx_ring_num > 1) {
|
||||||
mlx4_qp_modify(mdev->dev, NULL, rss_map->indir_state,
|
mlx4_qp_modify(mdev->dev, NULL, rss_map->indir_state,
|
||||||
MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->indir_qp);
|
MLX4_QP_STATE_RST, NULL, 0, 0,
|
||||||
mlx4_qp_remove(mdev->dev, &rss_map->indir_qp);
|
rss_map->indir_qp);
|
||||||
mlx4_qp_free(mdev->dev, &rss_map->indir_qp);
|
mlx4_qp_remove(mdev->dev, rss_map->indir_qp);
|
||||||
|
mlx4_qp_free(mdev->dev, rss_map->indir_qp);
|
||||||
|
kfree(rss_map->indir_qp);
|
||||||
|
rss_map->indir_qp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < priv->rx_ring_num; i++) {
|
for (i = 0; i < priv->rx_ring_num; i++) {
|
||||||
mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
|
mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
|
||||||
|
|
|
@ -2356,7 +2356,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
||||||
MLX4_A0_STEERING_TABLE_SIZE;
|
MLX4_A0_STEERING_TABLE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mlx4_dbg(dev, "DMFS high rate steer mode is: %s\n",
|
mlx4_info(dev, "DMFS high rate steer mode is: %s\n",
|
||||||
dmfs_high_rate_steering_mode_str(
|
dmfs_high_rate_steering_mode_str(
|
||||||
dev->caps.dmfs_high_steer_mode));
|
dev->caps.dmfs_high_steer_mode));
|
||||||
}
|
}
|
||||||
|
|
|
@ -431,7 +431,7 @@ struct mlx4_en_rss_map {
|
||||||
int base_qpn;
|
int base_qpn;
|
||||||
struct mlx4_qp qps[MAX_RX_RINGS];
|
struct mlx4_qp qps[MAX_RX_RINGS];
|
||||||
enum mlx4_qp_state state[MAX_RX_RINGS];
|
enum mlx4_qp_state state[MAX_RX_RINGS];
|
||||||
struct mlx4_qp indir_qp;
|
struct mlx4_qp *indir_qp;
|
||||||
enum mlx4_qp_state indir_state;
|
enum mlx4_qp_state indir_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue