aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2017-02-01 01:35:33 -0500
committerDavid S. Miller <davem@davemloft.net>2017-02-02 21:27:05 -0500
commit770f82253dbd7e6892a88018f2f6cd395f48d214 (patch)
tree177c454b09676bb54648883037b2d66c40bbdf74
parentf32b20e89e82c9ff1825fc5c5d69753ff5558ccd (diff)
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: 47a38e155037 ("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: Martin KaFai Lau <kafai@fb.com> Reviewed-by: Tariq Toukan <tariqt@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c27
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h3
3 files changed, 27 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index d5a9372ed84d..9aa422691954 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -1099,7 +1099,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
1099 memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile)); 1099 memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
1100 new_prof.tx_ring_size = tx_size; 1100 new_prof.tx_ring_size = tx_size;
1101 new_prof.rx_ring_size = rx_size; 1101 new_prof.rx_ring_size = rx_size;
1102 err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof); 1102 err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
1103 if (err) 1103 if (err)
1104 goto out; 1104 goto out;
1105 1105
@@ -1774,7 +1774,7 @@ static int mlx4_en_set_channels(struct net_device *dev,
1774 new_prof.tx_ring_num[TX_XDP] = xdp_count; 1774 new_prof.tx_ring_num[TX_XDP] = xdp_count;
1775 new_prof.rx_ring_num = channel->rx_count; 1775 new_prof.rx_ring_num = channel->rx_count;
1776 1776
1777 err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof); 1777 err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
1778 if (err) 1778 if (err)
1779 goto out; 1779 goto out;
1780 1780
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 3abcead208d2..3b4961a8e8e4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2186,9 +2186,11 @@ static void mlx4_en_update_priv(struct mlx4_en_priv *dst,
2186 2186
2187int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv, 2187int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
2188 struct mlx4_en_priv *tmp, 2188 struct mlx4_en_priv *tmp,
2189 struct mlx4_en_port_profile *prof) 2189 struct mlx4_en_port_profile *prof,
2190 bool carry_xdp_prog)
2190{ 2191{
2191 int t; 2192 struct bpf_prog *xdp_prog;
2193 int i, t;
2192 2194
2193 mlx4_en_copy_priv(tmp, priv, prof); 2195 mlx4_en_copy_priv(tmp, priv, prof);
2194 2196
@@ -2202,6 +2204,23 @@ int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
2202 } 2204 }
2203 return -ENOMEM; 2205 return -ENOMEM;
2204 } 2206 }
2207
2208 /* All rx_rings has the same xdp_prog. Pick the first one. */
2209 xdp_prog = rcu_dereference_protected(
2210 priv->rx_ring[0]->xdp_prog,
2211 lockdep_is_held(&priv->mdev->state_lock));
2212
2213 if (xdp_prog && carry_xdp_prog) {
2214 xdp_prog = bpf_prog_add(xdp_prog, tmp->rx_ring_num);
2215 if (IS_ERR(xdp_prog)) {
2216 mlx4_en_free_resources(tmp);
2217 return PTR_ERR(xdp_prog);
2218 }
2219 for (i = 0; i < tmp->rx_ring_num; i++)
2220 rcu_assign_pointer(tmp->rx_ring[i]->xdp_prog,
2221 xdp_prog);
2222 }
2223
2205 return 0; 2224 return 0;
2206} 2225}
2207 2226
@@ -2751,7 +2770,7 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
2751 en_warn(priv, "Reducing the number of TX rings, to not exceed the max total rings number.\n"); 2770 en_warn(priv, "Reducing the number of TX rings, to not exceed the max total rings number.\n");
2752 } 2771 }
2753 2772
2754 err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof); 2773 err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, false);
2755 if (err) { 2774 if (err) {
2756 if (prog) 2775 if (prog)
2757 bpf_prog_sub(prog, priv->rx_ring_num - 1); 2776 bpf_prog_sub(prog, priv->rx_ring_num - 1);
@@ -3495,7 +3514,7 @@ int mlx4_en_reset_config(struct net_device *dev,
3495 memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile)); 3514 memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
3496 memcpy(&new_prof.hwtstamp_config, &ts_config, sizeof(ts_config)); 3515 memcpy(&new_prof.hwtstamp_config, &ts_config, sizeof(ts_config));
3497 3516
3498 err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof); 3517 err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
3499 if (err) 3518 if (err)
3500 goto out; 3519 goto out;
3501 3520
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index ba1c6cd0cc79..cec59bc264c9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -679,7 +679,8 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
679 679
680int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv, 680int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
681 struct mlx4_en_priv *tmp, 681 struct mlx4_en_priv *tmp,
682 struct mlx4_en_port_profile *prof); 682 struct mlx4_en_port_profile *prof,
683 bool carry_xdp_prog);
683void mlx4_en_safe_replace_resources(struct mlx4_en_priv *priv, 684void mlx4_en_safe_replace_resources(struct mlx4_en_priv *priv,
684 struct mlx4_en_priv *tmp); 685 struct mlx4_en_priv *tmp);
685 686