@@ -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+
143150static 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+
430446static 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 ;
456476out :
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+
759822static 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}
0 commit comments