Skip to content

Commit 67f8b1d

Browse files
Tariq Toukandavem330
authored andcommitted
net/mlx4_en: Refactor the XDP forwarding rings scheme
Separately manage the two types of TX rings: regular ones, and XDP. Upon an XDP set, do not borrow regular TX rings and convert them into XDP ones, but allocate new ones, unless we hit the max number of rings. Which means that in systems with smaller #cores we will not consume the current TX rings for XDP, while we are still in the num TX limit. XDP TX rings counters are not shown in ethtool statistics. Instead, XDP counters will be added to the respective RX rings in a downstream patch. This has no performance implications. Signed-off-by: Tariq Toukan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ccc109b commit 67f8b1d

File tree

8 files changed

+293
-205
lines changed

8 files changed

+293
-205
lines changed

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,7 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
127127
/* For TX we use the same irq per
128128
ring we assigned for the RX */
129129
struct mlx4_en_cq *rx_cq;
130-
int xdp_index;
131-
132-
/* The xdp tx irq must align with the rx ring that forwards to
133-
* it, so reindex these from 0. This should only happen when
134-
* tx_ring_num is not a multiple of rx_ring_num.
135-
*/
136-
xdp_index = (priv->xdp_ring_num - priv->tx_ring_num) + cq_idx;
137-
if (xdp_index >= 0)
138-
cq_idx = xdp_index;
130+
139131
cq_idx = cq_idx % priv->rx_ring_num;
140132
rx_cq = priv->rx_cq[cq_idx];
141133
cq->vector = rx_cq->vector;

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

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,19 @@
4949

5050
static int mlx4_en_moderation_update(struct mlx4_en_priv *priv)
5151
{
52-
int i;
52+
int i, t;
5353
int err = 0;
5454

55-
for (i = 0; i < priv->tx_ring_num; i++) {
56-
priv->tx_cq[i]->moder_cnt = priv->tx_frames;
57-
priv->tx_cq[i]->moder_time = priv->tx_usecs;
58-
if (priv->port_up) {
59-
err = mlx4_en_set_cq_moder(priv, priv->tx_cq[i]);
60-
if (err)
61-
return err;
55+
for (t = 0 ; t < MLX4_EN_NUM_TX_TYPES; t++) {
56+
for (i = 0; i < priv->tx_ring_num[t]; i++) {
57+
priv->tx_cq[t][i]->moder_cnt = priv->tx_frames;
58+
priv->tx_cq[t][i]->moder_time = priv->tx_usecs;
59+
if (priv->port_up) {
60+
err = mlx4_en_set_cq_moder(priv,
61+
priv->tx_cq[t][i]);
62+
if (err)
63+
return err;
64+
}
6265
}
6366
}
6467

@@ -336,7 +339,7 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
336339
switch (sset) {
337340
case ETH_SS_STATS:
338341
return bitmap_iterator_count(&it) +
339-
(priv->tx_ring_num * 2) +
342+
(priv->tx_ring_num[TX] * 2) +
340343
(priv->rx_ring_num * 3);
341344
case ETH_SS_TEST:
342345
return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
@@ -397,9 +400,9 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
397400
if (bitmap_iterator_test(&it))
398401
data[index++] = ((unsigned long *)&priv->pkstats)[i];
399402

400-
for (i = 0; i < priv->tx_ring_num; i++) {
401-
data[index++] = priv->tx_ring[i]->packets;
402-
data[index++] = priv->tx_ring[i]->bytes;
403+
for (i = 0; i < priv->tx_ring_num[TX]; i++) {
404+
data[index++] = priv->tx_ring[TX][i]->packets;
405+
data[index++] = priv->tx_ring[TX][i]->bytes;
403406
}
404407
for (i = 0; i < priv->rx_ring_num; i++) {
405408
data[index++] = priv->rx_ring[i]->packets;
@@ -467,7 +470,7 @@ static void mlx4_en_get_strings(struct net_device *dev,
467470
strcpy(data + (index++) * ETH_GSTRING_LEN,
468471
main_strings[strings]);
469472

470-
for (i = 0; i < priv->tx_ring_num; i++) {
473+
for (i = 0; i < priv->tx_ring_num[TX]; i++) {
471474
sprintf(data + (index++) * ETH_GSTRING_LEN,
472475
"tx%d_packets", i);
473476
sprintf(data + (index++) * ETH_GSTRING_LEN,
@@ -1060,7 +1063,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
10601063

10611064
if (rx_size == (priv->port_up ? priv->rx_ring[0]->actual_size :
10621065
priv->rx_ring[0]->size) &&
1063-
tx_size == priv->tx_ring[0]->size)
1066+
tx_size == priv->tx_ring[TX][0]->size)
10641067
return 0;
10651068

10661069
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
@@ -1105,7 +1108,7 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
11051108
param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
11061109
param->rx_pending = priv->port_up ?
11071110
priv->rx_ring[0]->actual_size : priv->rx_ring[0]->size;
1108-
param->tx_pending = priv->tx_ring[0]->size;
1111+
param->tx_pending = priv->tx_ring[TX][0]->size;
11091112
}
11101113

11111114
static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
@@ -1710,7 +1713,7 @@ static void mlx4_en_get_channels(struct net_device *dev,
17101713
channel->max_tx = MLX4_EN_MAX_TX_RING_P_UP;
17111714

17121715
channel->rx_count = priv->rx_ring_num;
1713-
channel->tx_count = priv->tx_ring_num / MLX4_EN_NUM_UP;
1716+
channel->tx_count = priv->tx_ring_num[TX] / MLX4_EN_NUM_UP;
17141717
}
17151718

17161719
static int mlx4_en_set_channels(struct net_device *dev,
@@ -1721,6 +1724,7 @@ static int mlx4_en_set_channels(struct net_device *dev,
17211724
struct mlx4_en_port_profile new_prof;
17221725
struct mlx4_en_priv *tmp;
17231726
int port_up = 0;
1727+
int xdp_count;
17241728
int err = 0;
17251729

17261730
if (channel->other_count || channel->combined_count ||
@@ -1729,20 +1733,25 @@ static int mlx4_en_set_channels(struct net_device *dev,
17291733
!channel->tx_count || !channel->rx_count)
17301734
return -EINVAL;
17311735

1732-
if (channel->tx_count * MLX4_EN_NUM_UP <= priv->xdp_ring_num) {
1733-
en_err(priv, "Minimum %d tx channels required with XDP on\n",
1734-
priv->xdp_ring_num / MLX4_EN_NUM_UP + 1);
1735-
return -EINVAL;
1736-
}
1737-
17381736
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
17391737
if (!tmp)
17401738
return -ENOMEM;
17411739

17421740
mutex_lock(&mdev->state_lock);
1741+
xdp_count = priv->tx_ring_num[TX_XDP] ? channel->rx_count : 0;
1742+
if (channel->tx_count * MLX4_EN_NUM_UP + xdp_count > MAX_TX_RINGS) {
1743+
err = -EINVAL;
1744+
en_err(priv,
1745+
"Total number of TX and XDP rings (%d) exceeds the maximum supported (%d)\n",
1746+
channel->tx_count * MLX4_EN_NUM_UP + xdp_count,
1747+
MAX_TX_RINGS);
1748+
goto out;
1749+
}
1750+
17431751
memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
17441752
new_prof.num_tx_rings_p_up = channel->tx_count;
1745-
new_prof.tx_ring_num = channel->tx_count * MLX4_EN_NUM_UP;
1753+
new_prof.tx_ring_num[TX] = channel->tx_count * MLX4_EN_NUM_UP;
1754+
new_prof.tx_ring_num[TX_XDP] = xdp_count;
17461755
new_prof.rx_ring_num = channel->rx_count;
17471756

17481757
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
@@ -1756,14 +1765,13 @@ static int mlx4_en_set_channels(struct net_device *dev,
17561765

17571766
mlx4_en_safe_replace_resources(priv, tmp);
17581767

1759-
netif_set_real_num_tx_queues(dev, priv->tx_ring_num -
1760-
priv->xdp_ring_num);
1768+
netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]);
17611769
netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
17621770

17631771
if (dev->num_tc)
17641772
mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP);
17651773

1766-
en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num);
1774+
en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num[TX]);
17671775
en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num);
17681776

17691777
if (port_up) {
@@ -1774,8 +1782,8 @@ static int mlx4_en_set_channels(struct net_device *dev,
17741782

17751783
err = mlx4_en_moderation_update(priv);
17761784
out:
1777-
kfree(tmp);
17781785
mutex_unlock(&mdev->state_lock);
1786+
kfree(tmp);
17791787
return err;
17801788
}
17811789

@@ -1823,11 +1831,15 @@ static int mlx4_en_set_priv_flags(struct net_device *dev, u32 flags)
18231831
int ret = 0;
18241832

18251833
if (bf_enabled_new != bf_enabled_old) {
1834+
int t;
1835+
18261836
if (bf_enabled_new) {
18271837
bool bf_supported = true;
18281838

1829-
for (i = 0; i < priv->tx_ring_num; i++)
1830-
bf_supported &= priv->tx_ring[i]->bf_alloced;
1839+
for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++)
1840+
for (i = 0; i < priv->tx_ring_num[t]; i++)
1841+
bf_supported &=
1842+
priv->tx_ring[t][i]->bf_alloced;
18311843

18321844
if (!bf_supported) {
18331845
en_err(priv, "BlueFlame is not supported\n");
@@ -1839,8 +1851,10 @@ static int mlx4_en_set_priv_flags(struct net_device *dev, u32 flags)
18391851
priv->pflags &= ~MLX4_EN_PRIV_FLAGS_BLUEFLAME;
18401852
}
18411853

1842-
for (i = 0; i < priv->tx_ring_num; i++)
1843-
priv->tx_ring[i]->bf_enabled = bf_enabled_new;
1854+
for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++)
1855+
for (i = 0; i < priv->tx_ring_num[t]; i++)
1856+
priv->tx_ring[t][i]->bf_enabled =
1857+
bf_enabled_new;
18441858

18451859
en_info(priv, "BlueFlame %s\n",
18461860
bf_enabled_new ? "Enabled" : "Disabled");

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ 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].tx_ring_num = params->num_tx_rings_p_up *
172+
params->prof[i].tx_ring_num[TX] = params->num_tx_rings_p_up *
173173
MLX4_EN_NUM_UP;
174174
params->prof[i].rss_rings = 0;
175175
params->prof[i].inline_thold = inline_thold;

0 commit comments

Comments
 (0)