Skip to content

Commit 84a0973

Browse files
Gavi TeitzSaeed Mahameed
authored andcommitted
net/mlx5e: Enable multi-queue and RSS for VF representors
Increased the amount of channels the representors can open to be the amount of CPUs. The default amount opened remains one. Used the standard NIC netdev functions to: * Set RSS params when building the representors' params. * Setup an indirect TIR and RQT for the representors upon initialization. * Create a TTC flow table for the representors' indirect TIR (when creating the TTC table, mlx5e_set_ttc_basic_params() is not called, in order to avoid setting the inner_ttc param, which is not needed). Added ethtool control to the representors for setting and querying the amount of open channels. Additionally, included logic in the representors' ethtool set channels handler which controls a representor's vport rx rule, so that if there is one open channel the rx rule steers traffic to the representor's direct TIR, whereas if there is more than one channel, the rx rule steers traffic to the new TTC flow table. Signed-off-by: Gavi Teitz <[email protected]> Reviewed-by: Or Gerlitz <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent a5355de commit 84a0973

File tree

1 file changed

+129
-11
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+129
-11
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_rep.c

Lines changed: 129 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,90 @@ static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
180180
}
181181
}
182182

183+
static int mlx5e_replace_rep_vport_rx_rule(struct mlx5e_priv *priv,
184+
struct mlx5_flow_destination *dest)
185+
{
186+
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
187+
struct mlx5e_rep_priv *rpriv = priv->ppriv;
188+
struct mlx5_eswitch_rep *rep = rpriv->rep;
189+
struct mlx5_flow_handle *flow_rule;
190+
191+
flow_rule = mlx5_eswitch_create_vport_rx_rule(esw,
192+
rep->vport,
193+
dest);
194+
if (IS_ERR(flow_rule))
195+
return PTR_ERR(flow_rule);
196+
197+
mlx5_del_flow_rules(rpriv->vport_rx_rule);
198+
rpriv->vport_rx_rule = flow_rule;
199+
return 0;
200+
}
201+
202+
static void mlx5e_rep_get_channels(struct net_device *dev,
203+
struct ethtool_channels *ch)
204+
{
205+
struct mlx5e_priv *priv = netdev_priv(dev);
206+
207+
mlx5e_ethtool_get_channels(priv, ch);
208+
}
209+
210+
static int mlx5e_rep_set_channels(struct net_device *dev,
211+
struct ethtool_channels *ch)
212+
{
213+
struct mlx5e_priv *priv = netdev_priv(dev);
214+
u16 curr_channels_amount = priv->channels.params.num_channels;
215+
u32 new_channels_amount = ch->combined_count;
216+
struct mlx5_flow_destination new_dest;
217+
int err = 0;
218+
219+
err = mlx5e_ethtool_set_channels(priv, ch);
220+
if (err)
221+
return err;
222+
223+
if (curr_channels_amount == 1 && new_channels_amount > 1) {
224+
new_dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
225+
new_dest.ft = priv->fs.ttc.ft.t;
226+
} else if (new_channels_amount == 1 && curr_channels_amount > 1) {
227+
new_dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
228+
new_dest.tir_num = priv->direct_tir[0].tirn;
229+
} else {
230+
return 0;
231+
}
232+
233+
err = mlx5e_replace_rep_vport_rx_rule(priv, &new_dest);
234+
if (err) {
235+
netdev_warn(priv->netdev, "Failed to update vport rx rule, when going from (%d) channels to (%d) channels\n",
236+
curr_channels_amount, new_channels_amount);
237+
return err;
238+
}
239+
240+
return 0;
241+
}
242+
243+
static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
244+
{
245+
struct mlx5e_priv *priv = netdev_priv(netdev);
246+
247+
return mlx5e_ethtool_get_rxfh_key_size(priv);
248+
}
249+
250+
static u32 mlx5e_rep_get_rxfh_indir_size(struct net_device *netdev)
251+
{
252+
struct mlx5e_priv *priv = netdev_priv(netdev);
253+
254+
return mlx5e_ethtool_get_rxfh_indir_size(priv);
255+
}
256+
183257
static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
184258
.get_drvinfo = mlx5e_rep_get_drvinfo,
185259
.get_link = ethtool_op_get_link,
186260
.get_strings = mlx5e_rep_get_strings,
187261
.get_sset_count = mlx5e_rep_get_sset_count,
188262
.get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
263+
.get_channels = mlx5e_rep_get_channels,
264+
.set_channels = mlx5e_rep_set_channels,
265+
.get_rxfh_key_size = mlx5e_rep_get_rxfh_key_size,
266+
.get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
189267
};
190268

191269
int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr)
@@ -943,6 +1021,9 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
9431021
params->num_tc = 1;
9441022

9451023
mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
1024+
1025+
/* RSS */
1026+
mlx5e_build_rss_params(params);
9461027
}
9471028

9481029
static void mlx5e_build_rep_netdev(struct net_device *netdev)
@@ -995,14 +1076,36 @@ static void mlx5e_init_rep(struct mlx5_core_dev *mdev,
9951076

9961077
INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
9971078

998-
priv->channels.params.num_channels = profile->max_nch(mdev);
1079+
priv->channels.params.num_channels = 1;
9991080

10001081
mlx5e_build_rep_params(mdev, &priv->channels.params, netdev->mtu);
10011082
mlx5e_build_rep_netdev(netdev);
10021083

10031084
mlx5e_timestamp_init(priv);
10041085
}
10051086

1087+
static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
1088+
{
1089+
struct ttc_params ttc_params = {};
1090+
int tt, err;
1091+
1092+
priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
1093+
MLX5_FLOW_NAMESPACE_KERNEL);
1094+
1095+
/* The inner_ttc in the ttc params is intentionally not set */
1096+
ttc_params.any_tt_tirn = priv->direct_tir[0].tirn;
1097+
mlx5e_set_ttc_ft_params(&ttc_params);
1098+
for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
1099+
ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn;
1100+
1101+
err = mlx5e_create_ttc_table(priv, &ttc_params, &priv->fs.ttc);
1102+
if (err) {
1103+
netdev_err(priv->netdev, "Failed to create rep ttc table, err=%d\n", err);
1104+
return err;
1105+
}
1106+
return 0;
1107+
}
1108+
10061109
static int mlx5e_create_rep_vport_rx_rule(struct mlx5e_priv *priv)
10071110
{
10081111
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
@@ -1035,24 +1138,42 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
10351138
return err;
10361139
}
10371140

1038-
err = mlx5e_create_direct_rqts(priv);
1141+
err = mlx5e_create_indirect_rqt(priv);
10391142
if (err)
10401143
goto err_close_drop_rq;
10411144

1042-
err = mlx5e_create_direct_tirs(priv);
1145+
err = mlx5e_create_direct_rqts(priv);
1146+
if (err)
1147+
goto err_destroy_indirect_rqts;
1148+
1149+
err = mlx5e_create_indirect_tirs(priv, false);
10431150
if (err)
10441151
goto err_destroy_direct_rqts;
10451152

1046-
err = mlx5e_create_rep_vport_rx_rule(priv);
1153+
err = mlx5e_create_direct_tirs(priv);
1154+
if (err)
1155+
goto err_destroy_indirect_tirs;
1156+
1157+
err = mlx5e_create_rep_ttc_table(priv);
10471158
if (err)
10481159
goto err_destroy_direct_tirs;
10491160

1161+
err = mlx5e_create_rep_vport_rx_rule(priv);
1162+
if (err)
1163+
goto err_destroy_ttc_table;
1164+
10501165
return 0;
10511166

1167+
err_destroy_ttc_table:
1168+
mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
10521169
err_destroy_direct_tirs:
10531170
mlx5e_destroy_direct_tirs(priv);
1171+
err_destroy_indirect_tirs:
1172+
mlx5e_destroy_indirect_tirs(priv, false);
10541173
err_destroy_direct_rqts:
10551174
mlx5e_destroy_direct_rqts(priv);
1175+
err_destroy_indirect_rqts:
1176+
mlx5e_destroy_rqt(priv, &priv->indir_rqt);
10561177
err_close_drop_rq:
10571178
mlx5e_close_drop_rq(&priv->drop_rq);
10581179
return err;
@@ -1063,8 +1184,11 @@ static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
10631184
struct mlx5e_rep_priv *rpriv = priv->ppriv;
10641185

10651186
mlx5_del_flow_rules(rpriv->vport_rx_rule);
1187+
mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
10661188
mlx5e_destroy_direct_tirs(priv);
1189+
mlx5e_destroy_indirect_tirs(priv, false);
10671190
mlx5e_destroy_direct_rqts(priv);
1191+
mlx5e_destroy_rqt(priv, &priv->indir_rqt);
10681192
mlx5e_close_drop_rq(&priv->drop_rq);
10691193
}
10701194

@@ -1080,20 +1204,14 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
10801204
return 0;
10811205
}
10821206

1083-
static int mlx5e_get_rep_max_num_channels(struct mlx5_core_dev *mdev)
1084-
{
1085-
#define MLX5E_PORT_REPRESENTOR_NCH 1
1086-
return MLX5E_PORT_REPRESENTOR_NCH;
1087-
}
1088-
10891207
static const struct mlx5e_profile mlx5e_rep_profile = {
10901208
.init = mlx5e_init_rep,
10911209
.init_rx = mlx5e_init_rep_rx,
10921210
.cleanup_rx = mlx5e_cleanup_rep_rx,
10931211
.init_tx = mlx5e_init_rep_tx,
10941212
.cleanup_tx = mlx5e_cleanup_nic_tx,
10951213
.update_stats = mlx5e_rep_update_hw_counters,
1096-
.max_nch = mlx5e_get_rep_max_num_channels,
1214+
.max_nch = mlx5e_get_max_num_channels,
10971215
.update_carrier = NULL,
10981216
.rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe_rep,
10991217
.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,

0 commit comments

Comments
 (0)