Skip to content

Commit 95302c3

Browse files
committed
Merge tag 'mlx5e-updates-2018-12-11' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux
Saeed Mahameed says: ==================== mlx5e-updates-2018-12-11 From Eli Britstein, Patches 1-10 adds remote mirroring support. Patches 1-4 refactor encap related code as pre-steps for using per destination encapsulation properties. Patches 5-7 use extended destination feature for single/multi destination scenarios that have a single encap destination. Patches 8-10 enable multiple encap destinations for a TC flow. From, Daniel Jurgens, Patch 11, Use CQE padding for Ethernet CQs, PPC showed up to a 24% improvement in small packet throughput From Eyal Davidovich, patches 12-14, FW monitor counter support FW monitor counters feature came to solve the delayed reporting of FW stats in the atomic get_stats64 ndo, since we can't access the FW at that stage, this feature will enable immediate FW stats updates in the driver via fw events on specific stats updates. Patch 12, cleanup to avoid querying a FW counter when it is not supported Patch 13, Monitor counters FW commands support Patch 14, Use monitor counters in ethernet netdevice to update FW stats reported in the atomic get_stats64 ndo. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 43d4b29 + 5c7e8bb commit 95302c3

File tree

14 files changed

+393
-91
lines changed

14 files changed

+393
-91
lines changed

drivers/net/ethernet/mellanox/mlx5/core/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
2222
#
2323
mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
2424
en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o \
25-
en_selftest.o en/port.o
25+
en_selftest.o en/port.o en/monitor_stats.o
2626

2727
#
2828
# Netdev extra

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,8 @@ struct mlx5e_priv {
685685
struct work_struct set_rx_mode_work;
686686
struct work_struct tx_timeout_work;
687687
struct work_struct update_stats_work;
688+
struct work_struct monitor_counters_work;
689+
struct mlx5_nb monitor_counters_nb;
688690

689691
struct mlx5_core_dev *mdev;
690692
struct net_device *netdev;
@@ -940,6 +942,7 @@ int mlx5e_create_tises(struct mlx5e_priv *priv);
940942
void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv);
941943
int mlx5e_close(struct net_device *netdev);
942944
int mlx5e_open(struct net_device *netdev);
945+
void mlx5e_update_ndo_stats(struct mlx5e_priv *priv);
943946

944947
void mlx5e_queue_update_stats(struct mlx5e_priv *priv);
945948
int mlx5e_bits_invert(unsigned long a, int size);
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (c) 2018 Mellanox Technologies. */
3+
4+
#include "en.h"
5+
#include "monitor_stats.h"
6+
#include "lib/eq.h"
7+
8+
/* Driver will set the following watch counters list:
9+
* Ppcnt.802_3:
10+
* a_in_range_length_errors Type: 0x0, Counter: 0x0, group_id = N/A
11+
* a_out_of_range_length_field Type: 0x0, Counter: 0x1, group_id = N/A
12+
* a_frame_too_long_errors Type: 0x0, Counter: 0x2, group_id = N/A
13+
* a_frame_check_sequence_errors Type: 0x0, Counter: 0x3, group_id = N/A
14+
* a_alignment_errors Type: 0x0, Counter: 0x4, group_id = N/A
15+
* if_out_discards Type: 0x0, Counter: 0x5, group_id = N/A
16+
* Q_Counters:
17+
* Q[index].rx_out_of_buffer Type: 0x1, Counter: 0x4, group_id = counter_ix
18+
*/
19+
20+
#define NUM_REQ_PPCNT_COUNTER_S1 MLX5_CMD_SET_MONITOR_NUM_PPCNT_COUNTER_SET1
21+
#define NUM_REQ_Q_COUNTERS_S1 MLX5_CMD_SET_MONITOR_NUM_Q_COUNTERS_SET1
22+
23+
int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
24+
{
25+
struct mlx5_core_dev *mdev = priv->mdev;
26+
27+
if (!MLX5_CAP_GEN(mdev, max_num_of_monitor_counters))
28+
return false;
29+
if (MLX5_CAP_PCAM_REG(mdev, ppcnt) &&
30+
MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters) <
31+
NUM_REQ_PPCNT_COUNTER_S1)
32+
return false;
33+
if (MLX5_CAP_GEN(mdev, num_q_monitor_counters) <
34+
NUM_REQ_Q_COUNTERS_S1)
35+
return false;
36+
return true;
37+
}
38+
39+
void mlx5e_monitor_counter_arm(struct mlx5e_priv *priv)
40+
{
41+
u32 in[MLX5_ST_SZ_DW(arm_monitor_counter_in)] = {};
42+
u32 out[MLX5_ST_SZ_DW(arm_monitor_counter_out)] = {};
43+
44+
MLX5_SET(arm_monitor_counter_in, in, opcode,
45+
MLX5_CMD_OP_ARM_MONITOR_COUNTER);
46+
mlx5_cmd_exec(priv->mdev, in, sizeof(in), out, sizeof(out));
47+
}
48+
49+
static void mlx5e_monitor_counters_work(struct work_struct *work)
50+
{
51+
struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
52+
monitor_counters_work);
53+
54+
mutex_lock(&priv->state_lock);
55+
mlx5e_update_ndo_stats(priv);
56+
mutex_unlock(&priv->state_lock);
57+
mlx5e_monitor_counter_arm(priv);
58+
}
59+
60+
static int mlx5e_monitor_event_handler(struct notifier_block *nb,
61+
unsigned long event, void *eqe)
62+
{
63+
struct mlx5e_priv *priv = mlx5_nb_cof(nb, struct mlx5e_priv,
64+
monitor_counters_nb);
65+
queue_work(priv->wq, &priv->monitor_counters_work);
66+
return NOTIFY_OK;
67+
}
68+
69+
void mlx5e_monitor_counter_start(struct mlx5e_priv *priv)
70+
{
71+
MLX5_NB_INIT(&priv->monitor_counters_nb, mlx5e_monitor_event_handler,
72+
MONITOR_COUNTER);
73+
mlx5_eq_notifier_register(priv->mdev, &priv->monitor_counters_nb);
74+
}
75+
76+
static void mlx5e_monitor_counter_stop(struct mlx5e_priv *priv)
77+
{
78+
mlx5_eq_notifier_unregister(priv->mdev, &priv->monitor_counters_nb);
79+
cancel_work_sync(&priv->monitor_counters_work);
80+
}
81+
82+
static int fill_monitor_counter_ppcnt_set1(int cnt, u32 *in)
83+
{
84+
enum mlx5_monitor_counter_ppcnt ppcnt_cnt;
85+
86+
for (ppcnt_cnt = 0;
87+
ppcnt_cnt < NUM_REQ_PPCNT_COUNTER_S1;
88+
ppcnt_cnt++, cnt++) {
89+
MLX5_SET(set_monitor_counter_in, in,
90+
monitor_counter[cnt].type,
91+
MLX5_QUERY_MONITOR_CNT_TYPE_PPCNT);
92+
MLX5_SET(set_monitor_counter_in, in,
93+
monitor_counter[cnt].counter,
94+
ppcnt_cnt);
95+
}
96+
return ppcnt_cnt;
97+
}
98+
99+
static int fill_monitor_counter_q_counter_set1(int cnt, int q_counter, u32 *in)
100+
{
101+
MLX5_SET(set_monitor_counter_in, in,
102+
monitor_counter[cnt].type,
103+
MLX5_QUERY_MONITOR_CNT_TYPE_Q_COUNTER);
104+
MLX5_SET(set_monitor_counter_in, in,
105+
monitor_counter[cnt].counter,
106+
MLX5_QUERY_MONITOR_Q_COUNTER_RX_OUT_OF_BUFFER);
107+
MLX5_SET(set_monitor_counter_in, in,
108+
monitor_counter[cnt].counter_group_id,
109+
q_counter);
110+
return 1;
111+
}
112+
113+
/* check if mlx5e_monitor_counter_supported before calling this function*/
114+
static void mlx5e_set_monitor_counter(struct mlx5e_priv *priv)
115+
{
116+
struct mlx5_core_dev *mdev = priv->mdev;
117+
int max_num_of_counters = MLX5_CAP_GEN(mdev, max_num_of_monitor_counters);
118+
int num_q_counters = MLX5_CAP_GEN(mdev, num_q_monitor_counters);
119+
int num_ppcnt_counters = !MLX5_CAP_PCAM_REG(mdev, ppcnt) ? 0 :
120+
MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters);
121+
u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
122+
u32 out[MLX5_ST_SZ_DW(set_monitor_counter_out)] = {};
123+
int q_counter = priv->q_counter;
124+
int cnt = 0;
125+
126+
if (num_ppcnt_counters >= NUM_REQ_PPCNT_COUNTER_S1 &&
127+
max_num_of_counters >= (NUM_REQ_PPCNT_COUNTER_S1 + cnt))
128+
cnt += fill_monitor_counter_ppcnt_set1(cnt, in);
129+
130+
if (num_q_counters >= NUM_REQ_Q_COUNTERS_S1 &&
131+
max_num_of_counters >= (NUM_REQ_Q_COUNTERS_S1 + cnt) &&
132+
q_counter)
133+
cnt += fill_monitor_counter_q_counter_set1(cnt, q_counter, in);
134+
135+
MLX5_SET(set_monitor_counter_in, in, num_of_counters, cnt);
136+
MLX5_SET(set_monitor_counter_in, in, opcode,
137+
MLX5_CMD_OP_SET_MONITOR_COUNTER);
138+
139+
mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
140+
}
141+
142+
/* check if mlx5e_monitor_counter_supported before calling this function*/
143+
void mlx5e_monitor_counter_init(struct mlx5e_priv *priv)
144+
{
145+
INIT_WORK(&priv->monitor_counters_work, mlx5e_monitor_counters_work);
146+
mlx5e_monitor_counter_start(priv);
147+
mlx5e_set_monitor_counter(priv);
148+
mlx5e_monitor_counter_arm(priv);
149+
queue_work(priv->wq, &priv->update_stats_work);
150+
}
151+
152+
static void mlx5e_monitor_counter_disable(struct mlx5e_priv *priv)
153+
{
154+
u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
155+
u32 out[MLX5_ST_SZ_DW(set_monitor_counter_out)] = {};
156+
157+
MLX5_SET(set_monitor_counter_in, in, num_of_counters, 0);
158+
MLX5_SET(set_monitor_counter_in, in, opcode,
159+
MLX5_CMD_OP_SET_MONITOR_COUNTER);
160+
161+
mlx5_cmd_exec(priv->mdev, in, sizeof(in), out, sizeof(out));
162+
}
163+
164+
/* check if mlx5e_monitor_counter_supported before calling this function*/
165+
void mlx5e_monitor_counter_cleanup(struct mlx5e_priv *priv)
166+
{
167+
mlx5e_monitor_counter_disable(priv);
168+
mlx5e_monitor_counter_stop(priv);
169+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2+
/* Copyright (c) 2018 Mellanox Technologies. */
3+
4+
#ifndef __MLX5_MONITOR_H__
5+
#define __MLX5_MONITOR_H__
6+
7+
int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv);
8+
void mlx5e_monitor_counter_init(struct mlx5e_priv *priv);
9+
void mlx5e_monitor_counter_cleanup(struct mlx5e_priv *priv);
10+
void mlx5e_monitor_counter_arm(struct mlx5e_priv *priv);
11+
12+
#endif /* __MLX5_MONITOR_H__ */

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "en/port.h"
5151
#include "en/xdp.h"
5252
#include "lib/eq.h"
53+
#include "en/monitor_stats.h"
5354

5455
struct mlx5e_rq_param {
5556
u32 rqc[MLX5_ST_SZ_DW(rqc)];
@@ -263,7 +264,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
263264
mlx5e_stats_grps[i].update_stats(priv);
264265
}
265266

266-
static void mlx5e_update_ndo_stats(struct mlx5e_priv *priv)
267+
void mlx5e_update_ndo_stats(struct mlx5e_priv *priv)
267268
{
268269
int i;
269270

@@ -2224,6 +2225,8 @@ static void mlx5e_build_common_cq_param(struct mlx5e_priv *priv,
22242225
void *cqc = param->cqc;
22252226

22262227
MLX5_SET(cqc, cqc, uar_page, priv->mdev->priv.uar->index);
2228+
if (MLX5_CAP_GEN(priv->mdev, cqe_128_always) && cache_line_size() >= 128)
2229+
MLX5_SET(cqc, cqc, cqe_sz, CQE_STRIDE_128_PAD);
22272230
}
22282231

22292232
static void mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
@@ -3457,8 +3460,10 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
34573460
struct mlx5e_vport_stats *vstats = &priv->stats.vport;
34583461
struct mlx5e_pport_stats *pstats = &priv->stats.pport;
34593462

3460-
/* update HW stats in background for next time */
3461-
mlx5e_queue_update_stats(priv);
3463+
if (!mlx5e_monitor_counter_supported(priv)) {
3464+
/* update HW stats in background for next time */
3465+
mlx5e_queue_update_stats(priv);
3466+
}
34623467

34633468
if (mlx5e_is_uplink_rep(priv)) {
34643469
stats->rx_packets = PPORT_802_3_GET(pstats, a_frames_received_ok);
@@ -4899,6 +4904,8 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
48994904
mlx5_lag_add(mdev, netdev);
49004905

49014906
mlx5e_enable_async_events(priv);
4907+
if (mlx5e_monitor_counter_supported(priv))
4908+
mlx5e_monitor_counter_init(priv);
49024909

49034910
if (MLX5_ESWITCH_MANAGER(priv->mdev))
49044911
mlx5e_register_vport_reps(priv);
@@ -4938,6 +4945,9 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
49384945
if (MLX5_ESWITCH_MANAGER(priv->mdev))
49394946
mlx5e_unregister_vport_reps(priv);
49404947

4948+
if (mlx5e_monitor_counter_supported(priv))
4949+
mlx5e_monitor_counter_cleanup(priv);
4950+
49414951
mlx5e_disable_async_events(priv);
49424952
mlx5_lag_remove(mdev);
49434953
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,9 @@ static int mlx5e_grp_802_3_fill_stats(struct mlx5e_priv *priv, u64 *data,
483483
return idx;
484484
}
485485

486+
#define MLX5_BASIC_PPCNT_SUPPORTED(mdev) \
487+
(MLX5_CAP_GEN(mdev, pcam_reg) ? MLX5_CAP_PCAM_REG(mdev, ppcnt) : 1)
488+
486489
static void mlx5e_grp_802_3_update_stats(struct mlx5e_priv *priv)
487490
{
488491
struct mlx5e_pport_stats *pstats = &priv->stats.pport;
@@ -491,6 +494,9 @@ static void mlx5e_grp_802_3_update_stats(struct mlx5e_priv *priv)
491494
int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
492495
void *out;
493496

497+
if (!MLX5_BASIC_PPCNT_SUPPORTED(mdev))
498+
return;
499+
494500
MLX5_SET(ppcnt_reg, in, local_port, 1);
495501
out = pstats->IEEE_802_3_counters;
496502
MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP);
@@ -603,6 +609,9 @@ static void mlx5e_grp_2819_update_stats(struct mlx5e_priv *priv)
603609
int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
604610
void *out;
605611

612+
if (!MLX5_BASIC_PPCNT_SUPPORTED(mdev))
613+
return;
614+
606615
MLX5_SET(ppcnt_reg, in, local_port, 1);
607616
out = pstats->RFC_2819_counters;
608617
MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2819_COUNTERS_GROUP);
@@ -1078,6 +1087,9 @@ static void mlx5e_grp_per_prio_update_stats(struct mlx5e_priv *priv)
10781087
int prio;
10791088
void *out;
10801089

1090+
if (!MLX5_BASIC_PPCNT_SUPPORTED(mdev))
1091+
return;
1092+
10811093
MLX5_SET(ppcnt_reg, in, local_port, 1);
10821094
MLX5_SET(ppcnt_reg, in, grp, MLX5_PER_PRIORITY_COUNTERS_GROUP);
10831095
for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {

0 commit comments

Comments
 (0)