Skip to content

Commit d375db4

Browse files
PatrisiousHaddadrleon
authored andcommitted
RDMA/mlx5: Add optional counters for RDMA_TX/RX_packets/bytes
Add the following optional counters: rdma_tx_packets,rdma_rx_bytes,rdma_rx_packets,rdma_tx_bytes. Which counts all RDMA packets/bytes sent and received per link. Note that since each direction packet and byte counter are shared, the counter is only reset when both counters of that direction are removed. But from user-perspective each can be enabled/disabled separately. The counters can be enabled using: sudo rdma stat set link rocep8s0f0/1 optional-counters rdma_tx_packets And can be seen using: rdma stat -j show link rocep8s0f0/1 Signed-off-by: Patrisious Haddad <phaddad@nvidia.com> Reviewed-by: Mark Bloch <mbloch@nvidia.com> Link: https://patch.msgid.link/9f2753ad636f21704416df64b47395c8991d1123.1741875070.git.leon@kernel.org Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent 1d6a9e7 commit d375db4

4 files changed

Lines changed: 133 additions & 7 deletions

File tree

drivers/infiniband/hw/mlx5/counters.c

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ static const struct mlx5_ib_counter rdmatx_cnp_op_cnts[] = {
140140
INIT_OP_COUNTER(cc_tx_cnp_pkts, CC_TX_CNP_PKTS),
141141
};
142142

143+
static const struct mlx5_ib_counter packets_op_cnts[] = {
144+
INIT_OP_COUNTER(rdma_tx_packets, RDMA_TX_PACKETS),
145+
INIT_OP_COUNTER(rdma_tx_bytes, RDMA_TX_BYTES),
146+
INIT_OP_COUNTER(rdma_rx_packets, RDMA_RX_PACKETS),
147+
INIT_OP_COUNTER(rdma_rx_bytes, RDMA_RX_BYTES),
148+
};
149+
143150
static int mlx5_ib_read_counters(struct ib_counters *counters,
144151
struct ib_counters_read_attr *read_attr,
145152
struct uverbs_attr_bundle *attrs)
@@ -427,14 +434,23 @@ static int do_get_hw_stats(struct ib_device *ibdev,
427434
return num_counters;
428435
}
429436

437+
static bool is_rdma_bytes_counter(u32 type)
438+
{
439+
if (type == MLX5_IB_OPCOUNTER_RDMA_TX_BYTES ||
440+
type == MLX5_IB_OPCOUNTER_RDMA_RX_BYTES)
441+
return true;
442+
443+
return false;
444+
}
445+
430446
static int do_get_op_stat(struct ib_device *ibdev,
431447
struct rdma_hw_stats *stats,
432448
u32 port_num, int index)
433449
{
434450
struct mlx5_ib_dev *dev = to_mdev(ibdev);
435451
const struct mlx5_ib_counters *cnts;
436452
const struct mlx5_ib_op_fc *opfcs;
437-
u64 packets = 0, bytes;
453+
u64 packets, bytes;
438454
u32 type;
439455
int ret;
440456

@@ -453,8 +469,11 @@ static int do_get_op_stat(struct ib_device *ibdev,
453469
if (ret)
454470
return ret;
455471

472+
if (is_rdma_bytes_counter(type))
473+
stats->value[index] = bytes;
474+
else
475+
stats->value[index] = packets;
456476
out:
457-
stats->value[index] = packets;
458477
return index;
459478
}
460479

@@ -677,6 +696,12 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
677696
descs[j].priv = &rdmatx_cnp_op_cnts[i].type;
678697
}
679698
}
699+
700+
for (i = 0; i < ARRAY_SIZE(packets_op_cnts); i++, j++) {
701+
descs[j].name = packets_op_cnts[i].name;
702+
descs[j].flags |= IB_STAT_FLAG_OPTIONAL;
703+
descs[j].priv = &packets_op_cnts[i].type;
704+
}
680705
}
681706

682707

@@ -727,6 +752,8 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
727752

728753
num_op_counters = ARRAY_SIZE(basic_op_cnts);
729754

755+
num_op_counters += ARRAY_SIZE(packets_op_cnts);
756+
730757
if (MLX5_CAP_FLOWTABLE(dev->mdev,
731758
ft_field_support_2_nic_receive_rdma.bth_opcode))
732759
num_op_counters += ARRAY_SIZE(rdmarx_cnp_op_cnts);
@@ -756,10 +783,47 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
756783
return -ENOMEM;
757784
}
758785

786+
/*
787+
* Checks if the given flow counter type should be sharing the same flow counter
788+
* with another type and if it should, checks if that other type flow counter
789+
* was already created, if both conditions are met return true and the counter
790+
* else return false.
791+
*/
792+
static bool mlx5r_is_opfc_shared_and_in_use(struct mlx5_ib_op_fc *opfcs,
793+
u32 type,
794+
struct mlx5_ib_op_fc **opfc)
795+
{
796+
u32 shared_fc_type;
797+
798+
switch (type) {
799+
case MLX5_IB_OPCOUNTER_RDMA_TX_PACKETS:
800+
shared_fc_type = MLX5_IB_OPCOUNTER_RDMA_TX_BYTES;
801+
break;
802+
case MLX5_IB_OPCOUNTER_RDMA_TX_BYTES:
803+
shared_fc_type = MLX5_IB_OPCOUNTER_RDMA_TX_PACKETS;
804+
break;
805+
case MLX5_IB_OPCOUNTER_RDMA_RX_PACKETS:
806+
shared_fc_type = MLX5_IB_OPCOUNTER_RDMA_RX_BYTES;
807+
break;
808+
case MLX5_IB_OPCOUNTER_RDMA_RX_BYTES:
809+
shared_fc_type = MLX5_IB_OPCOUNTER_RDMA_RX_PACKETS;
810+
break;
811+
default:
812+
return false;
813+
}
814+
815+
*opfc = &opfcs[shared_fc_type];
816+
if (!(*opfc)->fc)
817+
return false;
818+
819+
return true;
820+
}
821+
759822
static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
760823
{
761824
u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
762825
int num_cnt_ports = dev->num_ports;
826+
struct mlx5_ib_op_fc *in_use_opfc;
763827
int i, j;
764828

765829
if (is_mdev_switchdev_mode(dev->mdev))
@@ -781,11 +845,16 @@ static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
781845
if (!dev->port[i].cnts.opfcs[j].fc)
782846
continue;
783847

848+
if (mlx5r_is_opfc_shared_and_in_use(
849+
dev->port[i].cnts.opfcs, j, &in_use_opfc))
850+
goto skip;
851+
784852
if (IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS))
785853
mlx5_ib_fs_remove_op_fc(dev,
786854
&dev->port[i].cnts.opfcs[j], j);
787855
mlx5_fc_destroy(dev->mdev,
788856
dev->port[i].cnts.opfcs[j].fc);
857+
skip:
789858
dev->port[i].cnts.opfcs[j].fc = NULL;
790859
}
791860
}
@@ -979,8 +1048,8 @@ static int mlx5_ib_modify_stat(struct ib_device *device, u32 port,
9791048
unsigned int index, bool enable)
9801049
{
9811050
struct mlx5_ib_dev *dev = to_mdev(device);
1051+
struct mlx5_ib_op_fc *opfc, *in_use_opfc;
9821052
struct mlx5_ib_counters *cnts;
983-
struct mlx5_ib_op_fc *opfc;
9841053
u32 num_hw_counters, type;
9851054
int ret;
9861055

@@ -1004,6 +1073,13 @@ static int mlx5_ib_modify_stat(struct ib_device *device, u32 port,
10041073
if (opfc->fc)
10051074
return -EEXIST;
10061075

1076+
if (mlx5r_is_opfc_shared_and_in_use(cnts->opfcs, type,
1077+
&in_use_opfc)) {
1078+
opfc->fc = in_use_opfc->fc;
1079+
opfc->rule[0] = in_use_opfc->rule[0];
1080+
return 0;
1081+
}
1082+
10071083
opfc->fc = mlx5_fc_create(dev->mdev, false);
10081084
if (IS_ERR(opfc->fc))
10091085
return PTR_ERR(opfc->fc);
@@ -1019,8 +1095,12 @@ static int mlx5_ib_modify_stat(struct ib_device *device, u32 port,
10191095
if (!opfc->fc)
10201096
return -EINVAL;
10211097

1098+
if (mlx5r_is_opfc_shared_and_in_use(cnts->opfcs, type, &in_use_opfc))
1099+
goto out;
1100+
10221101
mlx5_ib_fs_remove_op_fc(dev, opfc, type);
10231102
mlx5_fc_destroy(dev->mdev, opfc->fc);
1103+
out:
10241104
opfc->fc = NULL;
10251105
return 0;
10261106
}

drivers/infiniband/hw/mlx5/fs.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,10 +802,12 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
802802
enum {
803803
RDMA_RX_ECN_OPCOUNTER_PRIO,
804804
RDMA_RX_CNP_OPCOUNTER_PRIO,
805+
RDMA_RX_PKTS_BYTES_OPCOUNTER_PRIO,
805806
};
806807

807808
enum {
808809
RDMA_TX_CNP_OPCOUNTER_PRIO,
810+
RDMA_TX_PKTS_BYTES_OPCOUNTER_PRIO,
809811
};
810812

811813
static int set_vhca_port_spec(struct mlx5_ib_dev *dev, u32 port_num,
@@ -869,6 +871,29 @@ static int set_cnp_spec(struct mlx5_ib_dev *dev, u32 port_num,
869871
return 0;
870872
}
871873

874+
/* Returns the prio we should use for the given optional counter type,
875+
* whereas for bytes type we use the packet type, since they share the same
876+
* resources.
877+
*/
878+
static struct mlx5_ib_flow_prio *get_opfc_prio(struct mlx5_ib_dev *dev,
879+
u32 type)
880+
{
881+
u32 prio_type;
882+
883+
switch (type) {
884+
case MLX5_IB_OPCOUNTER_RDMA_TX_BYTES:
885+
prio_type = MLX5_IB_OPCOUNTER_RDMA_TX_PACKETS;
886+
break;
887+
case MLX5_IB_OPCOUNTER_RDMA_RX_BYTES:
888+
prio_type = MLX5_IB_OPCOUNTER_RDMA_RX_PACKETS;
889+
break;
890+
default:
891+
prio_type = type;
892+
}
893+
894+
return &dev->flow_db->opfcs[prio_type];
895+
}
896+
872897
int mlx5_ib_fs_add_op_fc(struct mlx5_ib_dev *dev, u32 port_num,
873898
struct mlx5_ib_op_fc *opfc,
874899
enum mlx5_ib_optional_counter_type type)
@@ -923,6 +948,20 @@ int mlx5_ib_fs_add_op_fc(struct mlx5_ib_dev *dev, u32 port_num,
923948
priority = RDMA_TX_CNP_OPCOUNTER_PRIO;
924949
break;
925950

951+
case MLX5_IB_OPCOUNTER_RDMA_TX_PACKETS:
952+
case MLX5_IB_OPCOUNTER_RDMA_TX_BYTES:
953+
spec_num = 1;
954+
fn_type = MLX5_FLOW_NAMESPACE_RDMA_TX_COUNTERS;
955+
priority = RDMA_TX_PKTS_BYTES_OPCOUNTER_PRIO;
956+
break;
957+
958+
case MLX5_IB_OPCOUNTER_RDMA_RX_PACKETS:
959+
case MLX5_IB_OPCOUNTER_RDMA_RX_BYTES:
960+
spec_num = 1;
961+
fn_type = MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS;
962+
priority = RDMA_RX_PKTS_BYTES_OPCOUNTER_PRIO;
963+
break;
964+
926965
default:
927966
err = -EOPNOTSUPP;
928967
goto free;
@@ -934,7 +973,7 @@ int mlx5_ib_fs_add_op_fc(struct mlx5_ib_dev *dev, u32 port_num,
934973
goto free;
935974
}
936975

937-
prio = &dev->flow_db->opfcs[type];
976+
prio = get_opfc_prio(dev, type);
938977
if (!prio->flow_table) {
939978
prio = _get_prio(dev, ns, prio, priority,
940979
dev->num_ports * MAX_OPFC_RULES, 1, 0, 0);
@@ -976,11 +1015,14 @@ void mlx5_ib_fs_remove_op_fc(struct mlx5_ib_dev *dev,
9761015
struct mlx5_ib_op_fc *opfc,
9771016
enum mlx5_ib_optional_counter_type type)
9781017
{
1018+
struct mlx5_ib_flow_prio *prio;
9791019
int i;
9801020

1021+
prio = get_opfc_prio(dev, type);
1022+
9811023
for (i = 0; i < MAX_OPFC_RULES && opfc->rule[i]; i++) {
9821024
mlx5_del_flow_rules(opfc->rule[i]);
983-
put_flow_table(dev, &dev->flow_db->opfcs[type], true);
1025+
put_flow_table(dev, prio, true);
9841026
}
9851027
}
9861028

drivers/infiniband/hw/mlx5/mlx5_ib.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ enum mlx5_ib_optional_counter_type {
294294
MLX5_IB_OPCOUNTER_CC_RX_CE_PKTS,
295295
MLX5_IB_OPCOUNTER_CC_RX_CNP_PKTS,
296296
MLX5_IB_OPCOUNTER_CC_TX_CNP_PKTS,
297+
MLX5_IB_OPCOUNTER_RDMA_TX_PACKETS,
298+
MLX5_IB_OPCOUNTER_RDMA_TX_BYTES,
299+
MLX5_IB_OPCOUNTER_RDMA_RX_PACKETS,
300+
MLX5_IB_OPCOUNTER_RDMA_RX_BYTES,
297301

298302
MLX5_IB_OPCOUNTER_MAX,
299303
};

include/linux/mlx5/device.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,8 +1532,8 @@ static inline u16 mlx5_to_sw_pkey_sz(int pkey_sz)
15321532
return MLX5_MIN_PKEY_TABLE_SIZE << pkey_sz;
15331533
}
15341534

1535-
#define MLX5_RDMA_RX_NUM_COUNTERS_PRIOS 2
1536-
#define MLX5_RDMA_TX_NUM_COUNTERS_PRIOS 1
1535+
#define MLX5_RDMA_RX_NUM_COUNTERS_PRIOS 3
1536+
#define MLX5_RDMA_TX_NUM_COUNTERS_PRIOS 2
15371537
#define MLX5_BY_PASS_NUM_REGULAR_PRIOS 16
15381538
#define MLX5_BY_PASS_NUM_DONT_TRAP_PRIOS 16
15391539
#define MLX5_BY_PASS_NUM_MULTICAST_PRIOS 1

0 commit comments

Comments
 (0)