Skip to content

Commit ec60c45

Browse files
Tariq ToukanSaeed Mahameed
authored andcommitted
net/mlx5e: Support MQPRIO channel mode
Add support for MQPRIO channel mode, in which a partition to TCs is defined over the channels. We allow partitions with contiguous queue indices, with no holes within. We do not allow modification to the num of channels while this MQPRIO mode is active. Signed-off-by: Tariq Toukan <[email protected]> Reviewed-by: Maxim Mikityanskiy <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 21ecfcb commit ec60c45

File tree

3 files changed

+102
-8
lines changed

3 files changed

+102
-8
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct page_pool;
7272
#define MLX5E_SW2HW_MTU(params, swmtu) ((swmtu) + ((params)->hard_mtu))
7373

7474
#define MLX5E_MAX_NUM_TC 8
75+
#define MLX5E_MAX_NUM_MQPRIO_CH_TC TC_QOPT_MAX_QUEUE
7576

7677
#define MLX5_RX_HEADROOM NET_SKB_PAD
7778
#define MLX5_SKB_FRAG_SZ(len) (SKB_DATA_ALIGN(len) + \

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,16 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
467467
goto out;
468468
}
469469

470+
/* Don't allow changing the number of channels if MQPRIO mode channel offload is active,
471+
* because it defines a partition over the channels queues.
472+
*/
473+
if (cur_params->mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
474+
err = -EINVAL;
475+
netdev_err(priv->netdev, "%s: MQPRIO mode channel offload is active, cannot change the number of channels\n",
476+
__func__);
477+
goto out;
478+
}
479+
470480
new_params = *cur_params;
471481
new_params.num_channels = count;
472482

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

Lines changed: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,7 +2263,8 @@ void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv)
22632263
ETH_MAX_MTU);
22642264
}
22652265

2266-
static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc)
2266+
static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc,
2267+
struct tc_mqprio_qopt_offload *mqprio)
22672268
{
22682269
int tc, err;
22692270

@@ -2278,11 +2279,16 @@ static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc)
22782279
return err;
22792280
}
22802281

2281-
/* Map netdev TCs to offset 0
2282-
* We have our own UP to TXQ mapping for QoS
2283-
*/
2284-
for (tc = 0; tc < ntc; tc++)
2285-
netdev_set_tc_queue(netdev, tc, nch, 0);
2282+
for (tc = 0; tc < ntc; tc++) {
2283+
u16 count, offset;
2284+
2285+
/* For DCB mode, map netdev TCs to offset 0
2286+
* We have our own UP to TXQ mapping for QoS
2287+
*/
2288+
count = mqprio ? mqprio->qopt.count[tc] : nch;
2289+
offset = mqprio ? mqprio->qopt.offset[tc] : 0;
2290+
netdev_set_tc_queue(netdev, tc, count, offset);
2291+
}
22862292

22872293
return 0;
22882294
}
@@ -2321,7 +2327,7 @@ static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv)
23212327
ntc = mlx5e_get_dcb_num_tc(&priv->channels.params);
23222328
num_rxqs = nch * priv->profile->rq_groups;
23232329

2324-
err = mlx5e_netdev_set_tcs(netdev, nch, ntc);
2330+
err = mlx5e_netdev_set_tcs(netdev, nch, ntc, NULL);
23252331
if (err)
23262332
goto err_out;
23272333
err = mlx5e_update_tx_netdev_queues(priv);
@@ -2344,7 +2350,7 @@ static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv)
23442350
WARN_ON_ONCE(netif_set_real_num_tx_queues(netdev, old_num_txqs));
23452351

23462352
err_tcs:
2347-
mlx5e_netdev_set_tcs(netdev, old_num_txqs / old_ntc, old_ntc);
2353+
mlx5e_netdev_set_tcs(netdev, old_num_txqs / old_ntc, old_ntc, NULL);
23482354
err_out:
23492355
return err;
23502356
}
@@ -2879,6 +2885,81 @@ static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv,
28792885
return err;
28802886
}
28812887

2888+
static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv,
2889+
struct tc_mqprio_qopt_offload *mqprio)
2890+
{
2891+
struct net_device *netdev = priv->netdev;
2892+
int agg_count = 0;
2893+
int i;
2894+
2895+
if (mqprio->qopt.offset[0] != 0 || mqprio->qopt.num_tc < 1 ||
2896+
mqprio->qopt.num_tc > MLX5E_MAX_NUM_MQPRIO_CH_TC)
2897+
return -EINVAL;
2898+
2899+
for (i = 0; i < mqprio->qopt.num_tc; i++) {
2900+
if (!mqprio->qopt.count[i]) {
2901+
netdev_err(netdev, "Zero size for queue-group (%d) is not supported\n", i);
2902+
return -EINVAL;
2903+
}
2904+
if (mqprio->min_rate[i]) {
2905+
netdev_err(netdev, "Min tx rate is not supported\n");
2906+
return -EINVAL;
2907+
}
2908+
if (mqprio->max_rate[i]) {
2909+
netdev_err(netdev, "Max tx rate is not supported\n");
2910+
return -EINVAL;
2911+
}
2912+
2913+
if (mqprio->qopt.offset[i] != agg_count) {
2914+
netdev_err(netdev, "Discontinuous queues config is not supported\n");
2915+
return -EINVAL;
2916+
}
2917+
agg_count += mqprio->qopt.count[i];
2918+
}
2919+
2920+
if (priv->channels.params.num_channels < agg_count) {
2921+
netdev_err(netdev, "Num of queues (%d) exceeds available (%d)\n",
2922+
agg_count, priv->channels.params.num_channels);
2923+
return -EINVAL;
2924+
}
2925+
2926+
return 0;
2927+
}
2928+
2929+
static int mlx5e_mqprio_channel_set_tcs_ctx(struct mlx5e_priv *priv, void *ctx)
2930+
{
2931+
struct tc_mqprio_qopt_offload *mqprio = (struct tc_mqprio_qopt_offload *)ctx;
2932+
struct net_device *netdev = priv->netdev;
2933+
u8 num_tc;
2934+
2935+
if (priv->channels.params.mqprio.mode != TC_MQPRIO_MODE_CHANNEL)
2936+
return -EINVAL;
2937+
2938+
num_tc = priv->channels.params.mqprio.num_tc;
2939+
mlx5e_netdev_set_tcs(netdev, 0, num_tc, mqprio);
2940+
2941+
return 0;
2942+
}
2943+
2944+
static int mlx5e_setup_tc_mqprio_channel(struct mlx5e_priv *priv,
2945+
struct tc_mqprio_qopt_offload *mqprio)
2946+
{
2947+
struct mlx5e_params new_params;
2948+
int err;
2949+
2950+
err = mlx5e_mqprio_channel_validate(priv, mqprio);
2951+
if (err)
2952+
return err;
2953+
2954+
new_params = priv->channels.params;
2955+
new_params.mqprio.mode = TC_MQPRIO_MODE_CHANNEL;
2956+
new_params.mqprio.num_tc = mqprio->qopt.num_tc;
2957+
err = mlx5e_safe_switch_params(priv, &new_params,
2958+
mlx5e_mqprio_channel_set_tcs_ctx, mqprio, true);
2959+
2960+
return err;
2961+
}
2962+
28822963
static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
28832964
struct tc_mqprio_qopt_offload *mqprio)
28842965
{
@@ -2891,6 +2972,8 @@ static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
28912972
switch (mqprio->mode) {
28922973
case TC_MQPRIO_MODE_DCB:
28932974
return mlx5e_setup_tc_mqprio_dcb(priv, &mqprio->qopt);
2975+
case TC_MQPRIO_MODE_CHANNEL:
2976+
return mlx5e_setup_tc_mqprio_channel(priv, mqprio);
28942977
default:
28952978
return -EOPNOTSUPP;
28962979
}

0 commit comments

Comments
 (0)