提交 2372bcda 编写于 作者: D David S. Miller

Merge branch 'mlx4-queue-reinit'

Martin KaFai Lau says:

====================
mlx4: Misc bug fixes after reinitializing queues

This patchset fixes misc bugs after reinitializing
queues (e.g. by ethtool -L).

v2:
* Add another fix to mem leak in tx_ring[t] and tx_cq[t]
* In mlx4_en_try_alloc_resources(),
  move all xdp_prog logic after calling mlx4_en_alloc_resources()
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -1099,7 +1099,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev, ...@@ -1099,7 +1099,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile)); memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
new_prof.tx_ring_size = tx_size; new_prof.tx_ring_size = tx_size;
new_prof.rx_ring_size = rx_size; new_prof.rx_ring_size = rx_size;
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof); err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
if (err) if (err)
goto out; goto out;
...@@ -1774,7 +1774,7 @@ static int mlx4_en_set_channels(struct net_device *dev, ...@@ -1774,7 +1774,7 @@ static int mlx4_en_set_channels(struct net_device *dev,
new_prof.tx_ring_num[TX_XDP] = xdp_count; new_prof.tx_ring_num[TX_XDP] = xdp_count;
new_prof.rx_ring_num = channel->rx_count; new_prof.rx_ring_num = channel->rx_count;
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof); err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
if (err) if (err)
goto out; goto out;
......
...@@ -2042,6 +2042,8 @@ static void mlx4_en_free_resources(struct mlx4_en_priv *priv) ...@@ -2042,6 +2042,8 @@ static void mlx4_en_free_resources(struct mlx4_en_priv *priv)
if (priv->tx_cq[t] && priv->tx_cq[t][i]) if (priv->tx_cq[t] && priv->tx_cq[t][i])
mlx4_en_destroy_cq(priv, &priv->tx_cq[t][i]); mlx4_en_destroy_cq(priv, &priv->tx_cq[t][i]);
} }
kfree(priv->tx_ring[t]);
kfree(priv->tx_cq[t]);
} }
for (i = 0; i < priv->rx_ring_num; i++) { for (i = 0; i < priv->rx_ring_num; i++) {
...@@ -2184,9 +2186,11 @@ static void mlx4_en_update_priv(struct mlx4_en_priv *dst, ...@@ -2184,9 +2186,11 @@ static void mlx4_en_update_priv(struct mlx4_en_priv *dst,
int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv, int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
struct mlx4_en_priv *tmp, struct mlx4_en_priv *tmp,
struct mlx4_en_port_profile *prof) struct mlx4_en_port_profile *prof,
bool carry_xdp_prog)
{ {
int t; struct bpf_prog *xdp_prog;
int i, t;
mlx4_en_copy_priv(tmp, priv, prof); mlx4_en_copy_priv(tmp, priv, prof);
...@@ -2200,6 +2204,23 @@ int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv, ...@@ -2200,6 +2204,23 @@ int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
} }
return -ENOMEM; return -ENOMEM;
} }
/* All rx_rings has the same xdp_prog. Pick the first one. */
xdp_prog = rcu_dereference_protected(
priv->rx_ring[0]->xdp_prog,
lockdep_is_held(&priv->mdev->state_lock));
if (xdp_prog && carry_xdp_prog) {
xdp_prog = bpf_prog_add(xdp_prog, tmp->rx_ring_num);
if (IS_ERR(xdp_prog)) {
mlx4_en_free_resources(tmp);
return PTR_ERR(xdp_prog);
}
for (i = 0; i < tmp->rx_ring_num; i++)
rcu_assign_pointer(tmp->rx_ring[i]->xdp_prog,
xdp_prog);
}
return 0; return 0;
} }
...@@ -2214,7 +2235,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev) ...@@ -2214,7 +2235,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
{ {
struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_en_dev *mdev = priv->mdev;
int t;
en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port); en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
...@@ -2248,11 +2268,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev) ...@@ -2248,11 +2268,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
mlx4_en_free_resources(priv); mlx4_en_free_resources(priv);
mutex_unlock(&mdev->state_lock); mutex_unlock(&mdev->state_lock);
for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++) {
kfree(priv->tx_ring[t]);
kfree(priv->tx_cq[t]);
}
free_netdev(dev); free_netdev(dev);
} }
...@@ -2755,7 +2770,7 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog) ...@@ -2755,7 +2770,7 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
en_warn(priv, "Reducing the number of TX rings, to not exceed the max total rings number.\n"); en_warn(priv, "Reducing the number of TX rings, to not exceed the max total rings number.\n");
} }
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof); err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, false);
if (err) { if (err) {
if (prog) if (prog)
bpf_prog_sub(prog, priv->rx_ring_num - 1); bpf_prog_sub(prog, priv->rx_ring_num - 1);
...@@ -3499,7 +3514,7 @@ int mlx4_en_reset_config(struct net_device *dev, ...@@ -3499,7 +3514,7 @@ int mlx4_en_reset_config(struct net_device *dev,
memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile)); memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
memcpy(&new_prof.hwtstamp_config, &ts_config, sizeof(ts_config)); memcpy(&new_prof.hwtstamp_config, &ts_config, sizeof(ts_config));
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof); err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
if (err) if (err)
goto out; goto out;
......
...@@ -679,7 +679,8 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev, ...@@ -679,7 +679,8 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv, int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
struct mlx4_en_priv *tmp, struct mlx4_en_priv *tmp,
struct mlx4_en_port_profile *prof); struct mlx4_en_port_profile *prof,
bool carry_xdp_prog);
void mlx4_en_safe_replace_resources(struct mlx4_en_priv *priv, void mlx4_en_safe_replace_resources(struct mlx4_en_priv *priv,
struct mlx4_en_priv *tmp); struct mlx4_en_priv *tmp);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册