Skip to content

Commit c9497c9

Browse files
Mohamad Haj YahiaSaeed Mahameed
authored andcommitted
net/mlx5: Add support for setting VF min rate
Add support for SRIOV VF min rate guarantee by using the TSAR BW share weights mechanism. The TSAR BW share vport attribute represents the weight of that vport among the other vports weights which means that the actual vport BW percentage is the same vport weight percentage among the total vports weights sum. Signed-off-by: Mohamad Haj Yahia <mohamad@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
1 parent 264d7bf commit c9497c9

File tree

4 files changed

+104
-13
lines changed

4 files changed

+104
-13
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,11 +3021,8 @@ static int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
30213021
struct mlx5e_priv *priv = netdev_priv(dev);
30223022
struct mlx5_core_dev *mdev = priv->mdev;
30233023

3024-
if (min_tx_rate)
3025-
return -EOPNOTSUPP;
3026-
30273024
return mlx5_eswitch_set_vport_rate(mdev->priv.eswitch, vf + 1,
3028-
max_tx_rate);
3025+
max_tx_rate, min_tx_rate);
30293026
}
30303027

30313028
static int mlx5_vport_link2ifla(u8 esw_link)

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

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,7 @@ static void esw_destroy_tsar(struct mlx5_eswitch *esw)
14151415
}
14161416

14171417
static int esw_vport_enable_qos(struct mlx5_eswitch *esw, int vport_num,
1418-
u32 initial_max_rate)
1418+
u32 initial_max_rate, u32 initial_bw_share)
14191419
{
14201420
u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {0};
14211421
struct mlx5_vport *vport = &esw->vports[vport_num];
@@ -1439,6 +1439,7 @@ static int esw_vport_enable_qos(struct mlx5_eswitch *esw, int vport_num,
14391439
esw->qos.root_tsar_id);
14401440
MLX5_SET(scheduling_context, &sched_ctx, max_average_bw,
14411441
initial_max_rate);
1442+
MLX5_SET(scheduling_context, &sched_ctx, bw_share, initial_bw_share);
14421443

14431444
err = mlx5_create_scheduling_element_cmd(dev,
14441445
SCHEDULING_HIERARCHY_E_SWITCH,
@@ -1473,7 +1474,7 @@ static void esw_vport_disable_qos(struct mlx5_eswitch *esw, int vport_num)
14731474
}
14741475

14751476
static int esw_vport_qos_config(struct mlx5_eswitch *esw, int vport_num,
1476-
u32 max_rate)
1477+
u32 max_rate, u32 bw_share)
14771478
{
14781479
u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {0};
14791480
struct mlx5_vport *vport = &esw->vports[vport_num];
@@ -1497,7 +1498,9 @@ static int esw_vport_qos_config(struct mlx5_eswitch *esw, int vport_num,
14971498
esw->qos.root_tsar_id);
14981499
MLX5_SET(scheduling_context, &sched_ctx, max_average_bw,
14991500
max_rate);
1501+
MLX5_SET(scheduling_context, &sched_ctx, bw_share, bw_share);
15001502
bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW;
1503+
bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_BW_SHARE;
15011504

15021505
err = mlx5_modify_scheduling_element_cmd(dev,
15031506
SCHEDULING_HIERARCHY_E_SWITCH,
@@ -1563,7 +1566,8 @@ static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num,
15631566
esw_apply_vport_conf(esw, vport);
15641567

15651568
/* Attach vport to the eswitch rate limiter */
1566-
if (esw_vport_enable_qos(esw, vport_num, vport->info.max_rate))
1569+
if (esw_vport_enable_qos(esw, vport_num, vport->info.max_rate,
1570+
vport->qos.bw_share))
15671571
esw_warn(esw->dev, "Failed to attach vport %d to eswitch rate limiter", vport_num);
15681572

15691573
/* Sync with current vport context */
@@ -1952,6 +1956,7 @@ int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
19521956
ivi->qos = evport->info.qos;
19531957
ivi->spoofchk = evport->info.spoofchk;
19541958
ivi->trusted = evport->info.trusted;
1959+
ivi->min_tx_rate = evport->info.min_rate;
19551960
ivi->max_tx_rate = evport->info.max_rate;
19561961
mutex_unlock(&esw->state_lock);
19571962

@@ -2046,23 +2051,103 @@ int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw,
20462051
return 0;
20472052
}
20482053

2049-
int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw,
2050-
int vport, u32 max_rate)
2054+
static u32 calculate_vports_min_rate_divider(struct mlx5_eswitch *esw)
20512055
{
2056+
u32 fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share);
20522057
struct mlx5_vport *evport;
2058+
u32 max_guarantee = 0;
2059+
int i;
2060+
2061+
for (i = 0; i <= esw->total_vports; i++) {
2062+
evport = &esw->vports[i];
2063+
if (!evport->enabled || evport->info.min_rate < max_guarantee)
2064+
continue;
2065+
max_guarantee = evport->info.min_rate;
2066+
}
2067+
2068+
return max_t(u32, max_guarantee / fw_max_bw_share, 1);
2069+
}
2070+
2071+
static int normalize_vports_min_rate(struct mlx5_eswitch *esw, u32 divider)
2072+
{
2073+
u32 fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share);
2074+
struct mlx5_vport *evport;
2075+
u32 vport_max_rate;
2076+
u32 vport_min_rate;
2077+
u32 bw_share;
2078+
int err;
2079+
int i;
2080+
2081+
for (i = 0; i <= esw->total_vports; i++) {
2082+
evport = &esw->vports[i];
2083+
if (!evport->enabled)
2084+
continue;
2085+
vport_min_rate = evport->info.min_rate;
2086+
vport_max_rate = evport->info.max_rate;
2087+
bw_share = MLX5_MIN_BW_SHARE;
2088+
2089+
if (vport_min_rate)
2090+
bw_share = MLX5_RATE_TO_BW_SHARE(vport_min_rate,
2091+
divider,
2092+
fw_max_bw_share);
2093+
2094+
if (bw_share == evport->qos.bw_share)
2095+
continue;
2096+
2097+
err = esw_vport_qos_config(esw, i, vport_max_rate,
2098+
bw_share);
2099+
if (!err)
2100+
evport->qos.bw_share = bw_share;
2101+
else
2102+
return err;
2103+
}
2104+
2105+
return 0;
2106+
}
2107+
2108+
int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, int vport,
2109+
u32 max_rate, u32 min_rate)
2110+
{
2111+
u32 fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share);
2112+
bool min_rate_supported = MLX5_CAP_QOS(esw->dev, esw_bw_share) &&
2113+
fw_max_bw_share >= MLX5_MIN_BW_SHARE;
2114+
bool max_rate_supported = MLX5_CAP_QOS(esw->dev, esw_rate_limit);
2115+
struct mlx5_vport *evport;
2116+
u32 previous_min_rate;
2117+
u32 divider;
20532118
int err = 0;
20542119

20552120
if (!ESW_ALLOWED(esw))
20562121
return -EPERM;
20572122
if (!LEGAL_VPORT(esw, vport))
20582123
return -EINVAL;
2124+
if ((min_rate && !min_rate_supported) || (max_rate && !max_rate_supported))
2125+
return -EOPNOTSUPP;
20592126

20602127
mutex_lock(&esw->state_lock);
20612128
evport = &esw->vports[vport];
2062-
err = esw_vport_qos_config(esw, vport, max_rate);
2129+
2130+
if (min_rate == evport->info.min_rate)
2131+
goto set_max_rate;
2132+
2133+
previous_min_rate = evport->info.min_rate;
2134+
evport->info.min_rate = min_rate;
2135+
divider = calculate_vports_min_rate_divider(esw);
2136+
err = normalize_vports_min_rate(esw, divider);
2137+
if (err) {
2138+
evport->info.min_rate = previous_min_rate;
2139+
goto unlock;
2140+
}
2141+
2142+
set_max_rate:
2143+
if (max_rate == evport->info.max_rate)
2144+
goto unlock;
2145+
2146+
err = esw_vport_qos_config(esw, vport, max_rate, evport->qos.bw_share);
20632147
if (!err)
20642148
evport->info.max_rate = max_rate;
20652149

2150+
unlock:
20662151
mutex_unlock(&esw->state_lock);
20672152
return err;
20682153
}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050

5151
#define FDB_UPLINK_VPORT 0xffff
5252

53+
#define MLX5_MIN_BW_SHARE 1
54+
55+
#define MLX5_RATE_TO_BW_SHARE(rate, divider, limit) \
56+
min_t(u32, max_t(u32, (rate) / (divider), MLX5_MIN_BW_SHARE), limit)
57+
5358
/* L2 -mac address based- hash helpers */
5459
struct l2addr_node {
5560
struct hlist_node hlist;
@@ -116,6 +121,7 @@ struct mlx5_vport_info {
116121
u8 qos;
117122
u64 node_guid;
118123
int link_state;
124+
u32 min_rate;
119125
u32 max_rate;
120126
bool spoofchk;
121127
bool trusted;
@@ -138,6 +144,7 @@ struct mlx5_vport {
138144
struct {
139145
bool enabled;
140146
u32 esw_tsar_ix;
147+
u32 bw_share;
141148
} qos;
142149

143150
bool enabled;
@@ -249,8 +256,8 @@ int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw,
249256
int vport, bool spoofchk);
250257
int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw,
251258
int vport_num, bool setting);
252-
int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw,
253-
int vport, u32 max_rate);
259+
int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, int vport,
260+
u32 max_rate, u32 min_rate);
254261
int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
255262
int vport, struct ifla_vf_info *ivi);
256263
int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,

include/linux/mlx5/mlx5_ifc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,9 @@ struct mlx5_ifc_e_switch_cap_bits {
547547
struct mlx5_ifc_qos_cap_bits {
548548
u8 packet_pacing[0x1];
549549
u8 esw_scheduling[0x1];
550-
u8 reserved_at_2[0x1e];
550+
u8 esw_bw_share[0x1];
551+
u8 esw_rate_limit[0x1];
552+
u8 reserved_at_4[0x1c];
551553

552554
u8 reserved_at_20[0x20];
553555

0 commit comments

Comments
 (0)