Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 770f8225 authored by Martin KaFai Lau's avatar Martin KaFai Lau Committed by David S. Miller
Browse files

mlx4: xdp_prog becomes inactive after ethtool '-L' or '-G'



After calling mlx4_en_try_alloc_resources (e.g. by changing the
number of rx-queues with ethtool -L), the existing xdp_prog becomes
inactive.

The bug is that the xdp_prog ptr has not been carried over from
the old rx-queues to the new rx-queues

Fixes: 47a38e15 ("net/mlx4_en: add support for fast rx drop bpf program")
Cc: Brenden Blanco <bblanco@plumgrid.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Cc: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
Reviewed-by: default avatarTariq Toukan <tariqt@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f32b20e8
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -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,
	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;


+23 −4
Original line number Original line Diff line number Diff line
@@ -2186,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);


@@ -2202,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;
}
}


@@ -2751,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);
@@ -3495,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;


+2 −1
Original line number Original line Diff line number Diff line
@@ -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);