Skip to content

Commit 445a25f

Browse files
Binary-Eaterkuba-moo
authored andcommitted
net/mlx5e: Support updating coalescing configuration without resetting channels
When CQE mode or DIM state is changed, gracefully reconfigure channels to handle new configuration. Previously, would create new channels that would reflect the changes rather than update the original channels. Co-developed-by: Nabil S. Alramli <dev@nalramli.com> Signed-off-by: Nabil S. Alramli <dev@nalramli.com> Co-developed-by: Joe Damato <jdamato@fastly.com> Signed-off-by: Joe Damato <jdamato@fastly.com> Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://lore.kernel.org/r/20240419080445.417574-5-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent a5e89a3 commit 445a25f

File tree

12 files changed

+460
-169
lines changed

12 files changed

+460
-169
lines changed

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ struct mlx5e_params {
320320
bool scatter_fcs_en;
321321
bool rx_dim_enabled;
322322
bool tx_dim_enabled;
323+
bool rx_moder_use_cqe_mode;
324+
bool tx_moder_use_cqe_mode;
323325
u32 pflags;
324326
struct bpf_prog *xdp_prog;
325327
struct mlx5e_xsk *xsk;
@@ -797,6 +799,10 @@ struct mlx5e_channel {
797799
int cpu;
798800
/* Sync between icosq recovery and XSK enable/disable. */
799801
struct mutex icosq_recovery_lock;
802+
803+
/* coalescing configuration */
804+
struct dim_cq_moder rx_cq_moder;
805+
struct dim_cq_moder tx_cq_moder;
800806
};
801807

802808
struct mlx5e_ptp;
@@ -1040,6 +1046,11 @@ void mlx5e_close_rq(struct mlx5e_rq *rq);
10401046
int mlx5e_create_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param, u16 q_counter);
10411047
void mlx5e_destroy_rq(struct mlx5e_rq *rq);
10421048

1049+
bool mlx5e_reset_rx_moderation(struct dim_cq_moder *cq_moder, u8 cq_period_mode,
1050+
bool dim_enabled);
1051+
bool mlx5e_reset_rx_channels_moderation(struct mlx5e_channels *chs, u8 cq_period_mode,
1052+
bool dim_enabled, bool keep_dim_state);
1053+
10431054
struct mlx5e_sq_param;
10441055
int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,
10451056
struct mlx5e_sq_param *param, struct xsk_buff_pool *xsk_pool,
@@ -1060,6 +1071,10 @@ int mlx5e_open_cq(struct mlx5_core_dev *mdev, struct dim_cq_moder moder,
10601071
struct mlx5e_cq_param *param, struct mlx5e_create_cq_param *ccp,
10611072
struct mlx5e_cq *cq);
10621073
void mlx5e_close_cq(struct mlx5e_cq *cq);
1074+
int mlx5e_modify_cq_period_mode(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
1075+
u8 cq_period_mode);
1076+
int mlx5e_modify_cq_moderation(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
1077+
u16 cq_period, u16 cq_max_count, u8 cq_period_mode);
10631078

10641079
int mlx5e_open_locked(struct net_device *netdev);
10651080
int mlx5e_close_locked(struct net_device *netdev);
@@ -1118,6 +1133,11 @@ int mlx5e_create_sq_rdy(struct mlx5_core_dev *mdev,
11181133
void mlx5e_tx_err_cqe_work(struct work_struct *recover_work);
11191134
void mlx5e_close_txqsq(struct mlx5e_txqsq *sq);
11201135

1136+
bool mlx5e_reset_tx_moderation(struct dim_cq_moder *cq_moder, u8 cq_period_mode,
1137+
bool dim_enabled);
1138+
bool mlx5e_reset_tx_channels_moderation(struct mlx5e_channels *chs, u8 cq_period_mode,
1139+
bool dim_enabled, bool keep_dim_state);
1140+
11211141
static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev)
11221142
{
11231143
return MLX5_CAP_ETH(mdev, swp) &&

drivers/net/ethernet/mellanox/mlx5/core/en/channels.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "channels.h"
55
#include "en.h"
6+
#include "en/dim.h"
67
#include "en/ptp.h"
78

89
unsigned int mlx5e_channels_get_num(struct mlx5e_channels *chs)
@@ -55,3 +56,85 @@ bool mlx5e_channels_get_ptp_rqn(struct mlx5e_channels *chs, u32 *rqn)
5556
*rqn = c->rq.rqn;
5657
return true;
5758
}
59+
60+
int mlx5e_channels_rx_change_dim(struct mlx5e_channels *chs, bool enable)
61+
{
62+
int i;
63+
64+
for (i = 0; i < chs->num; i++) {
65+
int err = mlx5e_dim_rx_change(&chs->c[i]->rq, enable);
66+
67+
if (err)
68+
return err;
69+
}
70+
71+
return 0;
72+
}
73+
74+
int mlx5e_channels_tx_change_dim(struct mlx5e_channels *chs, bool enable)
75+
{
76+
int i, tc;
77+
78+
for (i = 0; i < chs->num; i++) {
79+
for (tc = 0; tc < mlx5e_get_dcb_num_tc(&chs->params); tc++) {
80+
int err = mlx5e_dim_tx_change(&chs->c[i]->sq[tc], enable);
81+
82+
if (err)
83+
return err;
84+
}
85+
}
86+
87+
return 0;
88+
}
89+
90+
int mlx5e_channels_rx_toggle_dim(struct mlx5e_channels *chs)
91+
{
92+
int i;
93+
94+
for (i = 0; i < chs->num; i++) {
95+
/* If dim is enabled for the channel, reset the dim state so the
96+
* collected statistics will be reset. This is useful for
97+
* supporting legacy interfaces that allow things like changing
98+
* the CQ period mode for all channels without disturbing
99+
* individual channel configurations.
100+
*/
101+
if (chs->c[i]->rq.dim) {
102+
int err;
103+
104+
mlx5e_dim_rx_change(&chs->c[i]->rq, false);
105+
err = mlx5e_dim_rx_change(&chs->c[i]->rq, true);
106+
if (err)
107+
return err;
108+
}
109+
}
110+
111+
return 0;
112+
}
113+
114+
int mlx5e_channels_tx_toggle_dim(struct mlx5e_channels *chs)
115+
{
116+
int i, tc;
117+
118+
for (i = 0; i < chs->num; i++) {
119+
for (tc = 0; tc < mlx5e_get_dcb_num_tc(&chs->params); tc++) {
120+
int err;
121+
122+
/* If dim is enabled for the channel, reset the dim
123+
* state so the collected statistics will be reset. This
124+
* is useful for supporting legacy interfaces that allow
125+
* things like changing the CQ period mode for all
126+
* channels without disturbing individual channel
127+
* configurations.
128+
*/
129+
if (!chs->c[i]->sq[tc].dim)
130+
continue;
131+
132+
mlx5e_dim_tx_change(&chs->c[i]->sq[tc], false);
133+
err = mlx5e_dim_tx_change(&chs->c[i]->sq[tc], true);
134+
if (err)
135+
return err;
136+
}
137+
}
138+
139+
return 0;
140+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,9 @@ void mlx5e_channels_get_regular_rqn(struct mlx5e_channels *chs, unsigned int ix,
1515
void mlx5e_channels_get_xsk_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn,
1616
u32 *vhca_id);
1717
bool mlx5e_channels_get_ptp_rqn(struct mlx5e_channels *chs, u32 *rqn);
18+
int mlx5e_channels_rx_change_dim(struct mlx5e_channels *chs, bool enabled);
19+
int mlx5e_channels_tx_change_dim(struct mlx5e_channels *chs, bool enabled);
20+
int mlx5e_channels_rx_toggle_dim(struct mlx5e_channels *chs);
21+
int mlx5e_channels_tx_toggle_dim(struct mlx5e_channels *chs);
1822

1923
#endif /* __MLX5_EN_CHANNELS_H__ */

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <linux/mlx5/mlx5_ifc.h>
1010

1111
/* Forward declarations */
12+
struct mlx5e_rq;
13+
struct mlx5e_txqsq;
1214
struct work_struct;
1315

1416
/* convert a boolean value for cqe mode to appropriate dim constant
@@ -37,5 +39,7 @@ mlx5e_cq_period_mode(enum dim_cq_period_mode cq_period_mode)
3739

3840
void mlx5e_rx_dim_work(struct work_struct *work);
3941
void mlx5e_tx_dim_work(struct work_struct *work);
42+
int mlx5e_dim_rx_change(struct mlx5e_rq *rq, bool enabled);
43+
int mlx5e_dim_tx_change(struct mlx5e_txqsq *sq, bool enabled);
4044

4145
#endif /* __MLX5_EN_DIM_H__ */

drivers/net/ethernet/mellanox/mlx5/core/en/params.c

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -514,64 +514,6 @@ int mlx5e_validate_params(struct mlx5_core_dev *mdev, struct mlx5e_params *param
514514
return 0;
515515
}
516516

517-
static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode)
518-
{
519-
struct dim_cq_moder moder = {};
520-
521-
moder.cq_period_mode = cq_period_mode;
522-
moder.pkts = MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS;
523-
moder.usec = MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC;
524-
if (cq_period_mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE)
525-
moder.usec = MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC_FROM_CQE;
526-
527-
return moder;
528-
}
529-
530-
static struct dim_cq_moder mlx5e_get_def_rx_moderation(u8 cq_period_mode)
531-
{
532-
struct dim_cq_moder moder = {};
533-
534-
moder.cq_period_mode = cq_period_mode;
535-
moder.pkts = MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS;
536-
moder.usec = MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC;
537-
if (cq_period_mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE)
538-
moder.usec = MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE;
539-
540-
return moder;
541-
}
542-
543-
void mlx5e_reset_tx_moderation(struct mlx5e_params *params, u8 cq_period_mode)
544-
{
545-
if (params->tx_dim_enabled)
546-
params->tx_cq_moderation = net_dim_get_def_tx_moderation(cq_period_mode);
547-
else
548-
params->tx_cq_moderation = mlx5e_get_def_tx_moderation(cq_period_mode);
549-
}
550-
551-
void mlx5e_reset_rx_moderation(struct mlx5e_params *params, u8 cq_period_mode)
552-
{
553-
if (params->rx_dim_enabled)
554-
params->rx_cq_moderation = net_dim_get_def_rx_moderation(cq_period_mode);
555-
else
556-
params->rx_cq_moderation = mlx5e_get_def_rx_moderation(cq_period_mode);
557-
}
558-
559-
void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
560-
{
561-
mlx5e_reset_tx_moderation(params, cq_period_mode);
562-
MLX5E_SET_PFLAG(params, MLX5E_PFLAG_TX_CQE_BASED_MODER,
563-
params->tx_cq_moderation.cq_period_mode ==
564-
DIM_CQ_PERIOD_MODE_START_FROM_CQE);
565-
}
566-
567-
void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
568-
{
569-
mlx5e_reset_rx_moderation(params, cq_period_mode);
570-
MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_BASED_MODER,
571-
params->rx_cq_moderation.cq_period_mode ==
572-
DIM_CQ_PERIOD_MODE_START_FROM_CQE);
573-
}
574-
575517
bool slow_pci_heuristic(struct mlx5_core_dev *mdev)
576518
{
577519
u32 link_speed = 0;

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,6 @@ u8 mlx5e_mpwrq_max_log_rq_pkts(struct mlx5_core_dev *mdev, u8 page_shift,
7777

7878
/* Parameter calculations */
7979

80-
void mlx5e_reset_tx_moderation(struct mlx5e_params *params, u8 cq_period_mode);
81-
void mlx5e_reset_rx_moderation(struct mlx5e_params *params, u8 cq_period_mode);
82-
void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode);
83-
void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode);
84-
8580
bool slow_pci_heuristic(struct mlx5_core_dev *mdev);
8681
int mlx5e_mpwrq_validate_regular(struct mlx5_core_dev *mdev, struct mlx5e_params *params);
8782
int mlx5e_mpwrq_validate_xsk(struct mlx5_core_dev *mdev, struct mlx5e_params *params,

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

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ static void
3737
mlx5e_complete_dim_work(struct dim *dim, struct dim_cq_moder moder,
3838
struct mlx5_core_dev *mdev, struct mlx5_core_cq *mcq)
3939
{
40-
mlx5_core_modify_cq_moderation(mdev, mcq, moder.usec, moder.pkts);
40+
mlx5e_modify_cq_moderation(mdev, mcq, moder.usec, moder.pkts,
41+
mlx5e_cq_period_mode(moder.cq_period_mode));
4142
dim->state = DIM_START_MEASURE;
4243
}
4344

@@ -60,3 +61,89 @@ void mlx5e_tx_dim_work(struct work_struct *work)
6061

6162
mlx5e_complete_dim_work(dim, cur_moder, sq->cq.mdev, &sq->cq.mcq);
6263
}
64+
65+
static struct dim *mlx5e_dim_enable(struct mlx5_core_dev *mdev,
66+
void (*work_fun)(struct work_struct *), int cpu,
67+
u8 cq_period_mode, struct mlx5_core_cq *mcq,
68+
void *queue)
69+
{
70+
struct dim *dim;
71+
int err;
72+
73+
dim = kvzalloc_node(sizeof(*dim), GFP_KERNEL, cpu_to_node(cpu));
74+
if (!dim)
75+
return ERR_PTR(-ENOMEM);
76+
77+
INIT_WORK(&dim->work, work_fun);
78+
79+
dim->mode = cq_period_mode;
80+
dim->priv = queue;
81+
82+
err = mlx5e_modify_cq_period_mode(mdev, mcq, dim->mode);
83+
if (err) {
84+
kvfree(dim);
85+
return ERR_PTR(err);
86+
}
87+
88+
return dim;
89+
}
90+
91+
static void mlx5e_dim_disable(struct dim *dim)
92+
{
93+
cancel_work_sync(&dim->work);
94+
kvfree(dim);
95+
}
96+
97+
int mlx5e_dim_rx_change(struct mlx5e_rq *rq, bool enable)
98+
{
99+
if (enable == !!rq->dim)
100+
return 0;
101+
102+
if (enable) {
103+
struct mlx5e_channel *c = rq->channel;
104+
struct dim *dim;
105+
106+
dim = mlx5e_dim_enable(rq->mdev, mlx5e_rx_dim_work, c->cpu,
107+
c->rx_cq_moder.cq_period_mode, &rq->cq.mcq, rq);
108+
if (IS_ERR(dim))
109+
return PTR_ERR(dim);
110+
111+
rq->dim = dim;
112+
113+
__set_bit(MLX5E_RQ_STATE_DIM, &rq->state);
114+
} else {
115+
__clear_bit(MLX5E_RQ_STATE_DIM, &rq->state);
116+
117+
mlx5e_dim_disable(rq->dim);
118+
rq->dim = NULL;
119+
}
120+
121+
return 0;
122+
}
123+
124+
int mlx5e_dim_tx_change(struct mlx5e_txqsq *sq, bool enable)
125+
{
126+
if (enable == !!sq->dim)
127+
return 0;
128+
129+
if (enable) {
130+
struct mlx5e_channel *c = sq->channel;
131+
struct dim *dim;
132+
133+
dim = mlx5e_dim_enable(sq->mdev, mlx5e_tx_dim_work, c->cpu,
134+
c->tx_cq_moder.cq_period_mode, &sq->cq.mcq, sq);
135+
if (IS_ERR(dim))
136+
return PTR_ERR(dim);
137+
138+
sq->dim = dim;
139+
140+
__set_bit(MLX5E_SQ_STATE_DIM, &sq->state);
141+
} else {
142+
__clear_bit(MLX5E_SQ_STATE_DIM, &sq->state);
143+
144+
mlx5e_dim_disable(sq->dim);
145+
sq->dim = NULL;
146+
}
147+
148+
return 0;
149+
}

0 commit comments

Comments
 (0)