Skip to content

Commit ec327f7

Browse files
Inbar Karmydavem330
authored andcommitted
net/mlx4_en: Do not allocate redundant TX queues when TC is disabled
Currently the number of TX queues that are allocated doesn't depend on the number of TCs, the module always loads with max num of UP per channel. In order to prevent the allocation of unnecessary memory, the module will load with minimum number of UPs per channel, and the user will be able to control the number of TX queues per channel by changing the number of TC to 8 using the tc command. The variable num_up will hold the information about the current number of UPs. Due to the change, needed to remove the lines that set the value of UP to be different than zero in the func "mlx4_en_select_queue", since now the num of TX queues that are allocated is only one per channel in default. In order not to force the UP to be zero in case of only one TC, added a condition before forcing it in the func "mlx4_en_fill_qp_context". Tested: After the module is loaded with minimum number of UP per channel, to increase num of TCs to 8, use: tc qdisc add dev ens8 root mqprio num_tc 8 In order to decrease the number of TCs to minimum number of UP per channel, use: tc qdisc del dev ens8 root Signed-off-by: Inbar Karmy <[email protected]> Signed-off-by: Tariq Toukan <[email protected]> Cc: Tarick Bedeir <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f21ad61 commit ec327f7

File tree

7 files changed

+65
-16
lines changed

7 files changed

+65
-16
lines changed

drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ static u8 mlx4_en_dcbnl_set_state(struct net_device *dev, u8 state)
238238
priv->flags &= ~MLX4_EN_FLAG_DCB_ENABLED;
239239
}
240240

241-
if (mlx4_en_setup_tc(dev, num_tcs))
241+
if (mlx4_en_alloc_tx_queue_per_tc(dev, num_tcs))
242242
return 1;
243243

244244
return 0;
@@ -303,7 +303,7 @@ static int mlx4_en_ets_validate(struct mlx4_en_priv *priv, struct ieee_ets *ets)
303303
int has_ets_tc = 0;
304304

305305
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
306-
if (ets->prio_tc[i] >= priv->prof->num_up) {
306+
if (ets->prio_tc[i] >= MLX4_EN_NUM_UP_HIGH) {
307307
en_err(priv, "Bad priority in UP <=> TC mapping. TC: %d, UP: %d\n",
308308
i, ets->prio_tc[i]);
309309
return -EINVAL;
@@ -472,7 +472,7 @@ static u8 mlx4_en_dcbnl_setdcbx(struct net_device *dev, u8 mode)
472472
goto err;
473473
if (mlx4_en_dcbnl_ieee_setpfc(dev, &pfc))
474474
goto err;
475-
if (mlx4_en_setup_tc(dev, 0))
475+
if (mlx4_en_alloc_tx_queue_per_tc(dev, 0))
476476
goto err;
477477
}
478478

drivers/net/ethernet/mellanox/mlx4/en_ethtool.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,7 @@ static int mlx4_en_set_channels(struct net_device *dev,
17641764
int port_up = 0;
17651765
int xdp_count;
17661766
int err = 0;
1767+
u8 up;
17671768

17681769
if (!channel->tx_count || !channel->rx_count)
17691770
return -EINVAL;
@@ -1801,11 +1802,11 @@ static int mlx4_en_set_channels(struct net_device *dev,
18011802

18021803
mlx4_en_safe_replace_resources(priv, tmp);
18031804

1804-
netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]);
18051805
netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
18061806

1807-
if (netdev_get_num_tc(dev))
1808-
mlx4_en_setup_tc(dev, priv->prof->num_up);
1807+
up = (priv->prof->num_up == MLX4_EN_NUM_UP_LOW) ?
1808+
0 : priv->prof->num_up;
1809+
mlx4_en_setup_tc(dev, up);
18091810

18101811
en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num[TX]);
18111812
en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num);

drivers/net/ethernet/mellanox/mlx4/en_main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
169169
params->prof[i].tx_ppp = pfctx;
170170
params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
171171
params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
172-
params->prof[i].num_up = MLX4_EN_NUM_UP_HIGH;
172+
params->prof[i].num_up = MLX4_EN_NUM_UP_LOW;
173+
params->prof[i].num_tx_rings_p_up = params->num_tx_rings_p_up;
173174
params->prof[i].tx_ring_num[TX] = params->num_tx_rings_p_up *
174175
params->prof[i].num_up;
175176
params->prof[i].rss_rings = 0;

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ int mlx4_en_setup_tc(struct net_device *dev, u8 up)
6464
return -EINVAL;
6565

6666
netdev_set_num_tc(dev, up);
67-
67+
netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]);
6868
/* Partition Tx queues evenly amongst UP's */
6969
for (i = 0; i < up; i++) {
7070
netdev_set_tc_queue(dev, i, priv->num_tx_rings_p_up, offset);
@@ -86,16 +86,63 @@ int mlx4_en_setup_tc(struct net_device *dev, u8 up)
8686
return 0;
8787
}
8888

89+
int mlx4_en_alloc_tx_queue_per_tc(struct net_device *dev, u8 tc)
90+
{
91+
struct mlx4_en_priv *priv = netdev_priv(dev);
92+
struct mlx4_en_dev *mdev = priv->mdev;
93+
struct mlx4_en_port_profile new_prof;
94+
struct mlx4_en_priv *tmp;
95+
int port_up = 0;
96+
int err = 0;
97+
98+
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
99+
if (!tmp)
100+
return -ENOMEM;
101+
102+
mutex_lock(&mdev->state_lock);
103+
memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
104+
new_prof.num_up = (tc == 0) ? MLX4_EN_NUM_UP_LOW :
105+
MLX4_EN_NUM_UP_HIGH;
106+
new_prof.tx_ring_num[TX] = new_prof.num_tx_rings_p_up *
107+
new_prof.num_up;
108+
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
109+
if (err)
110+
goto out;
111+
112+
if (priv->port_up) {
113+
port_up = 1;
114+
mlx4_en_stop_port(dev, 1);
115+
}
116+
117+
mlx4_en_safe_replace_resources(priv, tmp);
118+
if (port_up) {
119+
err = mlx4_en_start_port(dev);
120+
if (err) {
121+
en_err(priv, "Failed starting port for setup TC\n");
122+
goto out;
123+
}
124+
}
125+
126+
err = mlx4_en_setup_tc(dev, tc);
127+
out:
128+
mutex_unlock(&mdev->state_lock);
129+
kfree(tmp);
130+
return err;
131+
}
132+
89133
static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle,
90134
u32 chain_index, __be16 proto,
91135
struct tc_to_netdev *tc)
92136
{
93137
if (tc->type != TC_SETUP_MQPRIO)
94138
return -EINVAL;
95139

140+
if (tc->mqprio->num_tc && tc->mqprio->num_tc != MLX4_EN_NUM_UP_HIGH)
141+
return -EINVAL;
142+
96143
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
97144

98-
return mlx4_en_setup_tc(dev, tc->mqprio->num_tc);
145+
return mlx4_en_alloc_tx_queue_per_tc(dev, tc->mqprio->num_tc);
99146
}
100147

101148
#ifdef CONFIG_RFS_ACCEL
@@ -2144,7 +2191,7 @@ static int mlx4_en_copy_priv(struct mlx4_en_priv *dst,
21442191

21452192
memcpy(&dst->hwtstamp_config, &prof->hwtstamp_config,
21462193
sizeof(dst->hwtstamp_config));
2147-
dst->num_tx_rings_p_up = src->mdev->profile.num_tx_rings_p_up;
2194+
dst->num_tx_rings_p_up = prof->num_tx_rings_p_up;
21482195
dst->rx_ring_num = prof->rx_ring_num;
21492196
dst->flags = prof->flags;
21502197
dst->mdev = src->mdev;
@@ -2197,6 +2244,7 @@ static void mlx4_en_update_priv(struct mlx4_en_priv *dst,
21972244
dst->tx_ring[t] = src->tx_ring[t];
21982245
dst->tx_cq[t] = src->tx_cq[t];
21992246
}
2247+
dst->num_tx_rings_p_up = src->num_tx_rings_p_up;
22002248
dst->rx_ring_num = src->rx_ring_num;
22012249
memcpy(dst->prof, src->prof, sizeof(struct mlx4_en_port_profile));
22022250
}

drivers/net/ethernet/mellanox/mlx4/en_resources.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
6363
context->local_qpn = cpu_to_be32(qpn);
6464
context->pri_path.ackto = 1 & 0x07;
6565
context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6;
66-
if (user_prio >= 0) {
66+
/* force user priority per tx ring */
67+
if (user_prio >= 0 && priv->prof->num_up == MLX4_EN_NUM_UP_HIGH) {
6768
context->pri_path.sched_queue |= user_prio << 3;
6869
context->pri_path.feup = MLX4_FEUP_FORCE_ETH_UP;
6970
}

drivers/net/ethernet/mellanox/mlx4/en_tx.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -691,15 +691,11 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
691691
{
692692
struct mlx4_en_priv *priv = netdev_priv(dev);
693693
u16 rings_p_up = priv->num_tx_rings_p_up;
694-
u8 up = 0;
695694

696695
if (netdev_get_num_tc(dev))
697696
return skb_tx_hash(dev, skb);
698697

699-
if (skb_vlan_tag_present(skb))
700-
up = skb_vlan_tag_get(skb) >> VLAN_PRIO_SHIFT;
701-
702-
return fallback(dev, skb) % rings_p_up + up * rings_p_up;
698+
return fallback(dev, skb) % rings_p_up;
703699
}
704700

705701
static void mlx4_bf_copy(void __iomem *dst, const void *src,

drivers/net/ethernet/mellanox/mlx4/mlx4_en.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
#define MLX4_EN_SMALL_PKT_SIZE 64
116116
#define MLX4_EN_MIN_TX_RING_P_UP 1
117117
#define MLX4_EN_MAX_TX_RING_P_UP 32
118+
#define MLX4_EN_NUM_UP_LOW 1
118119
#define MLX4_EN_NUM_UP_HIGH 8
119120
#define MLX4_EN_DEF_RX_RING_SIZE 1024
120121
#define MLX4_EN_DEF_TX_RING_SIZE MLX4_EN_DEF_RX_RING_SIZE
@@ -762,6 +763,7 @@ extern const struct dcbnl_rtnl_ops mlx4_en_dcbnl_pfc_ops;
762763
#endif
763764

764765
int mlx4_en_setup_tc(struct net_device *dev, u8 up);
766+
int mlx4_en_alloc_tx_queue_per_tc(struct net_device *dev, u8 tc);
765767

766768
#ifdef CONFIG_RFS_ACCEL
767769
void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv);

0 commit comments

Comments
 (0)