History

IB/mlx5: Fix congestion counters in LAG mode

Congestion counters are counted and queried per physical function. When working in LAG mode, CNP packets can be sent or received on both of the functions, thus congestion counters should be aggregated from the two physical functions.

Majd Dibbiny committed 8 years ago

Commit 71a0ff61 parent e3524b25 files · +66 −42Browse files

Unified · Split

5 files
  1. drivers/infiniband/hw/mlx5/cmd.c +0 −11
  2. drivers/infiniband/hw/mlx5/cmd.h +0 −2
  3. drivers/infiniband/hw/mlx5/main.c +6 −29
  4. drivers/net/ethernet/mellanox/mlx5/core/lag.c +56 −0
  5. include/linux/mlx5/driver.h +4 −0
drivers/infiniband/hw/mlx5/cmd.c+0−11
@@ -47,17 +47,6 @@ int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey) · 46 unmodified lines
47 return err;47 return err;
48}48}
49 49
50int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev,
51 bool reset, void *out, int out_size)
52{
53 u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = { };
54
55 MLX5_SET(query_cong_statistics_in, in, opcode,
56 MLX5_CMD_OP_QUERY_CONG_STATISTICS);
57 MLX5_SET(query_cong_statistics_in, in, clear, reset);
58 return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size);
59}
60
61int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,50int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
62 void *out, int out_size)51 void *out, int out_size)
63{52{
drivers/infiniband/hw/mlx5/cmd.h+0−2
@@ -37,8 +37,6 @@ · 36 unmodified lines
37#include <linux/mlx5/driver.h>37#include <linux/mlx5/driver.h>
38 38
39int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey);39int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey);
40int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev,
41 bool reset, void *out, int out_size);
42int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,40int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
43 void *out, int out_size);41 void *out, int out_size);
44int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev,42int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev,
drivers/infiniband/hw/mlx5/main.c+6−29
@@ -3737,34 +3737,6 @@ free: · 3736 unmodified lines
3737 return ret;3737 return ret;
3738}3738}
3739 3739
3740static int mlx5_ib_query_cong_counters(struct mlx5_ib_dev *dev,
3741 struct mlx5_ib_port *port,
3742 struct rdma_hw_stats *stats)
3743{
3744 int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out);
3745 void *out;
3746 int ret, i;
3747 int offset = port->cnts.num_q_counters;
3748
3749 out = kvzalloc(outlen, GFP_KERNEL);
3750 if (!out)
3751 return -ENOMEM;
3752
3753 ret = mlx5_cmd_query_cong_counter(dev->mdev, false, out, outlen);
3754 if (ret)
3755 goto free;
3756
3757 for (i = 0; i < port->cnts.num_cong_counters; i++) {
3758 stats->value[i + offset] =
3759 be64_to_cpup((__be64 *)(out +
3760 port->cnts.offsets[i + offset]));
3761 }
3762
3763free:
3764 kvfree(out);
3765 return ret;
3766}
3767
3768static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,3740static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
3769 struct rdma_hw_stats *stats,3741 struct rdma_hw_stats *stats,
3770 u8 port_num, int index)3742 u8 port_num, int index)
@@ -3782,7 +3754,12 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, · 11 unmodified lines
3782 num_counters = port->cnts.num_q_counters;3754 num_counters = port->cnts.num_q_counters;
3783 3755
3784 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {3756 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
3785 ret = mlx5_ib_query_cong_counters(dev, port, stats);3757 ret = mlx5_lag_query_cong_counters(dev->mdev,
3758 stats->value +
3759 port->cnts.num_q_counters,
3760 port->cnts.num_cong_counters,
3761 port->cnts.offsets +
3762 port->cnts.num_q_counters);
3786 if (ret)3763 if (ret)
3787 return ret;3764 return ret;
3788 num_counters += port->cnts.num_cong_counters;3765 num_counters += port->cnts.num_cong_counters;
drivers/net/ethernet/mellanox/mlx5/core/lag.c+56−0
@@ -137,6 +137,17 @@ int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev) · 136 unmodified lines
137}137}
138EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag);138EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag);
139 139
140static int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev,
141 bool reset, void *out, int out_size)
142{
143 u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = { };
144
145 MLX5_SET(query_cong_statistics_in, in, opcode,
146 MLX5_CMD_OP_QUERY_CONG_STATISTICS);
147 MLX5_SET(query_cong_statistics_in, in, clear, reset);
148 return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size);
149}
150
140static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev)151static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev)
141{152{
142 return dev->priv.lag;153 return dev->priv.lag;
@@ -633,3 +644,48 @@ bool mlx5_lag_intf_add(struct mlx5_interface *intf, struct mlx5_priv *priv) · 490 unmodified lines
633 /* If bonded, we do not add an IB device for PF1. */644 /* If bonded, we do not add an IB device for PF1. */
634 return false;645 return false;
635}646}
647
648int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
649 u64 *values,
650 int num_counters,
651 size_t *offsets)
652{
653 int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out);
654 struct mlx5_core_dev *mdev[MLX5_MAX_PORTS];
655 struct mlx5_lag *ldev;
656 int num_ports;
657 int ret, i, j;
658 void *out;
659
660 out = kvzalloc(outlen, GFP_KERNEL);
661 if (!out)
662 return -ENOMEM;
663
664 memset(values, 0, sizeof(*values) * num_counters);
665
666 mutex_lock(&lag_mutex);
667 ldev = mlx5_lag_dev_get(dev);
668 if (ldev && mlx5_lag_is_bonded(ldev)) {
669 num_ports = MLX5_MAX_PORTS;
670 mdev[0] = ldev->pf[0].dev;
671 mdev[1] = ldev->pf[1].dev;
672 } else {
673 num_ports = 1;
674 mdev[0] = dev;
675 }
676
677 for (i = 0; i < num_ports; ++i) {
678 ret = mlx5_cmd_query_cong_counter(mdev[i], false, out, outlen);
679 if (ret)
680 goto unlock;
681
682 for (j = 0; j < num_counters; ++j)
683 values[j] += be64_to_cpup((__be64 *)(out + offsets[j]));
684 }
685
686unlock:
687 mutex_unlock(&lag_mutex);
688 kvfree(out);
689 return ret;
690}
691EXPORT_SYMBOL(mlx5_lag_query_cong_counters);
include/linux/mlx5/driver.h+4−0
@@ -1164,6 +1164,10 @@ int mlx5_cmd_create_vport_lag(struct mlx5_core_dev *dev); · 1163 unmodified lines
1164int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev);1164int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev);
1165bool mlx5_lag_is_active(struct mlx5_core_dev *dev);1165bool mlx5_lag_is_active(struct mlx5_core_dev *dev);
1166struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev);1166struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev);
1167int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
1168 u64 *values,
1169 int num_counters,
1170 size_t *offsets);
1167struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev);1171struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev);
1168void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up);1172void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up);
1169 1173