Skip to content

Commit 55454e9

Browse files
committed
Merge branch 'mlx4-XDP-tx-refactor'
Tariq Toukan says: ==================== mlx4 XDP TX refactor This patchset refactors the XDP forwarding case, so that its dedicated transmit queues are managed in a complete separation from the other regular ones. It also adds ethtool counters for XDP cases. Series generated against net-next commit: 22ca904 genetlink: fix error return code in genl_register_family() Thanks, Tariq. v3: * Exposed per ring counters. v2: * Added ethtool counters. * Rebased, now patch 2 reverts Brenden's fix, as the bug no longer exists: 958b3d3 ("net/mlx4_en: fixup xdp tx irq to match rx") * Updated commit message of patch 2. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents e4ff952 + 15fca2c commit 55454e9

File tree

9 files changed

+366
-229
lines changed

9 files changed

+366
-229
lines changed

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

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv,
6565
cq->buf_size = cq->size * mdev->dev->caps.cqe_size;
6666

6767
cq->ring = ring;
68-
cq->is_tx = mode;
68+
cq->type = mode;
6969
cq->vector = mdev->dev->caps.num_comp_vectors;
7070

7171
/* Allocate HW buffers on provided NUMA node.
@@ -104,7 +104,7 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
104104
*cq->mcq.arm_db = 0;
105105
memset(cq->buf, 0, cq->buf_size);
106106

107-
if (cq->is_tx == RX) {
107+
if (cq->type == RX) {
108108
if (!mlx4_is_eq_vector_valid(mdev->dev, priv->port,
109109
cq->vector)) {
110110
cq->vector = cpumask_first(priv->rx_ring[cq->ring]->affinity_mask);
@@ -127,25 +127,17 @@ 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;
142134
}
143135

144-
if (!cq->is_tx)
136+
if (cq->type == RX)
145137
cq->size = priv->rx_ring[cq->ring]->actual_size;
146138

147-
if ((cq->is_tx && priv->hwtstamp_config.tx_type) ||
148-
(!cq->is_tx && priv->hwtstamp_config.rx_filter))
139+
if ((cq->type != RX && priv->hwtstamp_config.tx_type) ||
140+
(cq->type == RX && priv->hwtstamp_config.rx_filter))
149141
timestamp_en = 1;
150142

151143
err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt,
@@ -154,10 +146,10 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
154146
if (err)
155147
goto free_eq;
156148

157-
cq->mcq.comp = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq;
149+
cq->mcq.comp = cq->type != RX ? mlx4_en_tx_irq : mlx4_en_rx_irq;
158150
cq->mcq.event = mlx4_en_cq_event;
159151

160-
if (cq->is_tx)
152+
if (cq->type != RX)
161153
netif_tx_napi_add(cq->dev, &cq->napi, mlx4_en_poll_tx_cq,
162154
NAPI_POLL_WEIGHT);
163155
else
@@ -181,7 +173,7 @@ void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq)
181173

182174
mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size);
183175
if (mlx4_is_eq_vector_valid(mdev->dev, priv->port, cq->vector) &&
184-
cq->is_tx == RX)
176+
cq->type == RX)
185177
mlx4_release_eq(priv->mdev->dev, cq->vector);
186178
cq->vector = 0;
187179
cq->buf_size = 0;
@@ -193,7 +185,7 @@ void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq)
193185
void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
194186
{
195187
napi_disable(&cq->napi);
196-
if (!cq->is_tx) {
188+
if (cq->type == RX) {
197189
napi_hash_del(&cq->napi);
198190
synchronize_rcu();
199191
}

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

Lines changed: 69 additions & 32 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

@@ -192,6 +195,10 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
192195
"tx_prio_7_packets", "tx_prio_7_bytes",
193196
"tx_novlan_packets", "tx_novlan_bytes",
194197

198+
/* xdp statistics */
199+
"rx_xdp_drop",
200+
"rx_xdp_tx",
201+
"rx_xdp_tx_full",
195202
};
196203

197204
static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
@@ -336,8 +343,8 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
336343
switch (sset) {
337344
case ETH_SS_STATS:
338345
return bitmap_iterator_count(&it) +
339-
(priv->tx_ring_num * 2) +
340-
(priv->rx_ring_num * 3);
346+
(priv->tx_ring_num[TX] * 2) +
347+
(priv->rx_ring_num * (3 + NUM_XDP_STATS));
341348
case ETH_SS_TEST:
342349
return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
343350
& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
@@ -397,14 +404,21 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
397404
if (bitmap_iterator_test(&it))
398405
data[index++] = ((unsigned long *)&priv->pkstats)[i];
399406

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;
407+
for (i = 0; i < NUM_XDP_STATS; i++, bitmap_iterator_inc(&it))
408+
if (bitmap_iterator_test(&it))
409+
data[index++] = ((unsigned long *)&priv->xdp_stats)[i];
410+
411+
for (i = 0; i < priv->tx_ring_num[TX]; i++) {
412+
data[index++] = priv->tx_ring[TX][i]->packets;
413+
data[index++] = priv->tx_ring[TX][i]->bytes;
403414
}
404415
for (i = 0; i < priv->rx_ring_num; i++) {
405416
data[index++] = priv->rx_ring[i]->packets;
406417
data[index++] = priv->rx_ring[i]->bytes;
407418
data[index++] = priv->rx_ring[i]->dropped;
419+
data[index++] = priv->rx_ring[i]->xdp_drop;
420+
data[index++] = priv->rx_ring[i]->xdp_tx;
421+
data[index++] = priv->rx_ring[i]->xdp_tx_full;
408422
}
409423
spin_unlock_bh(&priv->stats_lock);
410424

@@ -467,7 +481,13 @@ static void mlx4_en_get_strings(struct net_device *dev,
467481
strcpy(data + (index++) * ETH_GSTRING_LEN,
468482
main_strings[strings]);
469483

470-
for (i = 0; i < priv->tx_ring_num; i++) {
484+
for (i = 0; i < NUM_XDP_STATS; i++, strings++,
485+
bitmap_iterator_inc(&it))
486+
if (bitmap_iterator_test(&it))
487+
strcpy(data + (index++) * ETH_GSTRING_LEN,
488+
main_strings[strings]);
489+
490+
for (i = 0; i < priv->tx_ring_num[TX]; i++) {
471491
sprintf(data + (index++) * ETH_GSTRING_LEN,
472492
"tx%d_packets", i);
473493
sprintf(data + (index++) * ETH_GSTRING_LEN,
@@ -480,6 +500,12 @@ static void mlx4_en_get_strings(struct net_device *dev,
480500
"rx%d_bytes", i);
481501
sprintf(data + (index++) * ETH_GSTRING_LEN,
482502
"rx%d_dropped", i);
503+
sprintf(data + (index++) * ETH_GSTRING_LEN,
504+
"rx%d_xdp_drop", i);
505+
sprintf(data + (index++) * ETH_GSTRING_LEN,
506+
"rx%d_xdp_tx", i);
507+
sprintf(data + (index++) * ETH_GSTRING_LEN,
508+
"rx%d_xdp_tx_full", i);
483509
}
484510
break;
485511
case ETH_SS_PRIV_FLAGS:
@@ -1060,7 +1086,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
10601086

10611087
if (rx_size == (priv->port_up ? priv->rx_ring[0]->actual_size :
10621088
priv->rx_ring[0]->size) &&
1063-
tx_size == priv->tx_ring[0]->size)
1089+
tx_size == priv->tx_ring[TX][0]->size)
10641090
return 0;
10651091

10661092
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
@@ -1105,7 +1131,7 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
11051131
param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
11061132
param->rx_pending = priv->port_up ?
11071133
priv->rx_ring[0]->actual_size : priv->rx_ring[0]->size;
1108-
param->tx_pending = priv->tx_ring[0]->size;
1134+
param->tx_pending = priv->tx_ring[TX][0]->size;
11091135
}
11101136

11111137
static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
@@ -1710,7 +1736,7 @@ static void mlx4_en_get_channels(struct net_device *dev,
17101736
channel->max_tx = MLX4_EN_MAX_TX_RING_P_UP;
17111737

17121738
channel->rx_count = priv->rx_ring_num;
1713-
channel->tx_count = priv->tx_ring_num / MLX4_EN_NUM_UP;
1739+
channel->tx_count = priv->tx_ring_num[TX] / MLX4_EN_NUM_UP;
17141740
}
17151741

17161742
static int mlx4_en_set_channels(struct net_device *dev,
@@ -1721,6 +1747,7 @@ static int mlx4_en_set_channels(struct net_device *dev,
17211747
struct mlx4_en_port_profile new_prof;
17221748
struct mlx4_en_priv *tmp;
17231749
int port_up = 0;
1750+
int xdp_count;
17241751
int err = 0;
17251752

17261753
if (channel->other_count || channel->combined_count ||
@@ -1729,20 +1756,25 @@ static int mlx4_en_set_channels(struct net_device *dev,
17291756
!channel->tx_count || !channel->rx_count)
17301757
return -EINVAL;
17311758

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-
17381759
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
17391760
if (!tmp)
17401761
return -ENOMEM;
17411762

17421763
mutex_lock(&mdev->state_lock);
1764+
xdp_count = priv->tx_ring_num[TX_XDP] ? channel->rx_count : 0;
1765+
if (channel->tx_count * MLX4_EN_NUM_UP + xdp_count > MAX_TX_RINGS) {
1766+
err = -EINVAL;
1767+
en_err(priv,
1768+
"Total number of TX and XDP rings (%d) exceeds the maximum supported (%d)\n",
1769+
channel->tx_count * MLX4_EN_NUM_UP + xdp_count,
1770+
MAX_TX_RINGS);
1771+
goto out;
1772+
}
1773+
17431774
memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
17441775
new_prof.num_tx_rings_p_up = channel->tx_count;
1745-
new_prof.tx_ring_num = channel->tx_count * MLX4_EN_NUM_UP;
1776+
new_prof.tx_ring_num[TX] = channel->tx_count * MLX4_EN_NUM_UP;
1777+
new_prof.tx_ring_num[TX_XDP] = xdp_count;
17461778
new_prof.rx_ring_num = channel->rx_count;
17471779

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

17571789
mlx4_en_safe_replace_resources(priv, tmp);
17581790

1759-
netif_set_real_num_tx_queues(dev, priv->tx_ring_num -
1760-
priv->xdp_ring_num);
1791+
netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]);
17611792
netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
17621793

17631794
if (dev->num_tc)
17641795
mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP);
17651796

1766-
en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num);
1797+
en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num[TX]);
17671798
en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num);
17681799

17691800
if (port_up) {
@@ -1774,8 +1805,8 @@ static int mlx4_en_set_channels(struct net_device *dev,
17741805

17751806
err = mlx4_en_moderation_update(priv);
17761807
out:
1777-
kfree(tmp);
17781808
mutex_unlock(&mdev->state_lock);
1809+
kfree(tmp);
17791810
return err;
17801811
}
17811812

@@ -1823,11 +1854,15 @@ static int mlx4_en_set_priv_flags(struct net_device *dev, u32 flags)
18231854
int ret = 0;
18241855

18251856
if (bf_enabled_new != bf_enabled_old) {
1857+
int t;
1858+
18261859
if (bf_enabled_new) {
18271860
bool bf_supported = true;
18281861

1829-
for (i = 0; i < priv->tx_ring_num; i++)
1830-
bf_supported &= priv->tx_ring[i]->bf_alloced;
1862+
for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++)
1863+
for (i = 0; i < priv->tx_ring_num[t]; i++)
1864+
bf_supported &=
1865+
priv->tx_ring[t][i]->bf_alloced;
18311866

18321867
if (!bf_supported) {
18331868
en_err(priv, "BlueFlame is not supported\n");
@@ -1839,8 +1874,10 @@ static int mlx4_en_set_priv_flags(struct net_device *dev, u32 flags)
18391874
priv->pflags &= ~MLX4_EN_PRIV_FLAGS_BLUEFLAME;
18401875
}
18411876

1842-
for (i = 0; i < priv->tx_ring_num; i++)
1843-
priv->tx_ring[i]->bf_enabled = bf_enabled_new;
1877+
for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++)
1878+
for (i = 0; i < priv->tx_ring_num[t]; i++)
1879+
priv->tx_ring[t][i]->bf_enabled =
1880+
bf_enabled_new;
18441881

18451882
en_info(priv, "BlueFlame %s\n",
18461883
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)