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
4747 return err;
4848 }
4949
50−int 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−
6150 int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
6251 void *out, int out_size)
6352 {
drivers/infiniband/hw/mlx5/cmd.h+0−2
@@ -37,8 +37,6 @@ · 36 unmodified lines
3737 #include <linux/mlx5/driver.h>
3838
3939 int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey);
40−int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev,
41− bool reset, void *out, int out_size);
4240 int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
4341 void *out, int out_size);
4442 int 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
37373737 return ret;
37383738 }
37393739
3740−static 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−
3763−free:
3764− kvfree(out);
3765− return ret;
3766−}
3767−
37683740 static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
37693741 struct rdma_hw_stats *stats,
37703742 u8 port_num, int index)
@@ -3782,7 +3754,12 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, · 11 unmodified lines
37823754 num_counters = port->cnts.num_q_counters;
37833755
37843756 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);
37863763 if (ret)
37873764 return ret;
37883765 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
137137 }
138138 EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag);
139139
140+static 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+
140151 static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev)
141152 {
142153 return dev->priv.lag;
@@ -633,3 +644,48 @@ bool mlx5_lag_intf_add(struct mlx5_interface *intf, struct mlx5_priv *priv) · 490 unmodified lines
633644 /* If bonded, we do not add an IB device for PF1. */
634645 return false;
635646 }
647+
648+int 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+
686+unlock:
687+ mutex_unlock(&lag_mutex);
688+ kvfree(out);
689+ return ret;
690+}
691+EXPORT_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
11641164 int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev);
11651165 bool mlx5_lag_is_active(struct mlx5_core_dev *dev);
11661166 struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev);
1167+int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
1168+ u64 *values,
1169+ int num_counters,
1170+ size_t *offsets);
11671171 struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev);
11681172 void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up);
11691173