net/mlx5: Increase the maximum flow counters supported
authorRabie Loulou <rabiel@mellanox.com>
Sun, 9 Jul 2017 10:39:30 +0000 (13:39 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Mon, 7 Aug 2017 07:47:07 +0000 (10:47 +0300)
Read new NIC capability field which represnts 16 MSBs of the max flow
counters number supported (max_flow_counter_31_16).

Backward compatibility with older firmware is preserved, the modified
driver reads max_flow_counter_31_16 as 0 from the older firmware and
uses up to 64K counters.

Changed flow counter id from 16 bits to 32 bits. Backward compatibility
with older firmware is preserved as we kept the 16 LSBs of the counter
id in place and added 16 MSBs from reserved field.

Changed the background bulk reading of flow counters to work in chunks
of at most 32K counters, to make sure we don't attempt to allocate very
large buffers.

Signed-off-by: Rabie Loulou <rabiel@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
include/linux/mlx5/mlx5_ifc.h

index 95b64025ce36f74681a69cc8812dc8fa6da79261..e7c186b585796d1726d242331e1e92f6c6e4a195 100644 (file)
@@ -433,6 +433,8 @@ static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
        struct mlx5_flow_table *fdb = NULL;
        int esw_size, err = 0;
        u32 flags = 0;
+       u32 max_flow_counter = (MLX5_CAP_GEN(dev, max_flow_counter_31_16) << 16) |
+                               MLX5_CAP_GEN(dev, max_flow_counter_15_0);
 
        root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_FDB);
        if (!root_ns) {
@@ -443,9 +445,9 @@ static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
 
        esw_debug(dev, "Create offloads FDB table, min (max esw size(2^%d), max counters(%d)*groups(%d))\n",
                  MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size),
-                 MLX5_CAP_GEN(dev, max_flow_counter), ESW_OFFLOADS_NUM_GROUPS);
+                 max_flow_counter, ESW_OFFLOADS_NUM_GROUPS);
 
-       esw_size = min_t(int, MLX5_CAP_GEN(dev, max_flow_counter) * ESW_OFFLOADS_NUM_GROUPS,
+       esw_size = min_t(int, max_flow_counter * ESW_OFFLOADS_NUM_GROUPS,
                         1 << MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size));
 
        if (esw->offloads.encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE)
index e750f07793b829de4b0383f93770f301e20eb196..16b32f31d691c6c8768819a36758543a7df59009 100644 (file)
@@ -359,7 +359,7 @@ int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev,
        return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
-int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u16 *id)
+int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u32 *id)
 {
        u32 in[MLX5_ST_SZ_DW(alloc_flow_counter_in)]   = {0};
        u32 out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {0};
@@ -374,7 +374,7 @@ int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u16 *id)
        return err;
 }
 
-int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u16 id)
+int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u32 id)
 {
        u32 in[MLX5_ST_SZ_DW(dealloc_flow_counter_in)]   = {0};
        u32 out[MLX5_ST_SZ_DW(dealloc_flow_counter_out)] = {0};
@@ -385,7 +385,7 @@ int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u16 id)
        return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
-int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u16 id,
+int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u32 id,
                      u64 *packets, u64 *bytes)
 {
        u32 out[MLX5_ST_SZ_BYTES(query_flow_counter_out) +
@@ -409,14 +409,14 @@ int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u16 id,
 }
 
 struct mlx5_cmd_fc_bulk {
-       u16 id;
+       u32 id;
        int num;
        int outlen;
        u32 out[0];
 };
 
 struct mlx5_cmd_fc_bulk *
-mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev, u16 id, int num)
+mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev, u32 id, int num)
 {
        struct mlx5_cmd_fc_bulk *b;
        int outlen =
@@ -453,7 +453,7 @@ mlx5_cmd_fc_bulk_query(struct mlx5_core_dev *dev, struct mlx5_cmd_fc_bulk *b)
 }
 
 void mlx5_cmd_fc_bulk_get(struct mlx5_core_dev *dev,
-                         struct mlx5_cmd_fc_bulk *b, u16 id,
+                         struct mlx5_cmd_fc_bulk *b, u32 id,
                          u64 *packets, u64 *bytes)
 {
        int index = id - b->id;
index 0f98a7cf4877d8103ef03989e15d05eda570fdb2..c6d7bdf255b6b94e6b80d3b312d3f65480c09892 100644 (file)
@@ -74,20 +74,20 @@ int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
                            struct mlx5_flow_table *ft,
                            u32 underlay_qpn);
 
-int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u16 *id);
-int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u16 id);
-int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u16 id,
+int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u32 *id);
+int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u32 id);
+int mlx5_cmd_fc_query(struct mlx5_core_dev *dev, u32 id,
                      u64 *packets, u64 *bytes);
 
 struct mlx5_cmd_fc_bulk;
 
 struct mlx5_cmd_fc_bulk *
-mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev, u16 id, int num);
+mlx5_cmd_fc_bulk_alloc(struct mlx5_core_dev *dev, u32 id, int num);
 void mlx5_cmd_fc_bulk_free(struct mlx5_cmd_fc_bulk *b);
 int
 mlx5_cmd_fc_bulk_query(struct mlx5_core_dev *dev, struct mlx5_cmd_fc_bulk *b);
 void mlx5_cmd_fc_bulk_get(struct mlx5_core_dev *dev,
-                         struct mlx5_cmd_fc_bulk *b, u16 id,
+                         struct mlx5_cmd_fc_bulk *b, u32 id,
                          u64 *packets, u64 *bytes);
 
 #endif
index 990acee6fb091f102e7412c499df8df44eb806db..9fb5a333df522c8f81c1787a85b768763cd2e09a 100644 (file)
@@ -136,7 +136,7 @@ struct mlx5_fc {
        u64 lastpackets;
        u64 lastbytes;
 
-       u16 id;
+       u32 id;
        bool deleted;
        bool aging;
 
index 6507d8acc54d460163717dc9a58a719c6f761671..89d1f865003358fe24c4dc2ed10ddb2f22557b45 100644 (file)
@@ -38,6 +38,8 @@
 #include "fs_cmd.h"
 
 #define MLX5_FC_STATS_PERIOD msecs_to_jiffies(1000)
+/* Max number of counters to query in bulk read is 32K */
+#define MLX5_SW_MAX_COUNTERS_BULK BIT(15)
 
 /* locking scheme:
  *
@@ -90,16 +92,21 @@ static void mlx5_fc_stats_insert(struct rb_root *root, struct mlx5_fc *counter)
        rb_insert_color(&counter->node, root);
 }
 
+/* The function returns the last node that was queried so the caller
+ * function can continue calling it till all counters are queried.
+ */
 static struct rb_node *mlx5_fc_stats_query(struct mlx5_core_dev *dev,
                                           struct mlx5_fc *first,
-                                          u16 last_id)
+                                          u32 last_id)
 {
        struct mlx5_cmd_fc_bulk *b;
        struct rb_node *node = NULL;
-       u16 afirst_id;
+       u32 afirst_id;
        int num;
        int err;
-       int max_bulk = 1 << MLX5_CAP_GEN(dev, log_max_flow_counter_bulk);
+
+       int max_bulk = min_t(int, MLX5_SW_MAX_COUNTERS_BULK,
+                            (1 << MLX5_CAP_GEN(dev, log_max_flow_counter_bulk)));
 
        /* first id must be aligned to 4 when using bulk query */
        afirst_id = first->id & ~0x3;
index f847a3a579139d96010b83e8f3882c9399867967..c99daffc3c3ce816ce83b8cedbc91af21741e17a 100644 (file)
@@ -963,7 +963,7 @@ struct mlx5_ifc_cmd_hca_cap_bits {
        u8         reserved_at_2a0[0x10];
        u8         max_wqe_sz_rq[0x10];
 
-       u8         reserved_at_2c0[0x10];
+       u8         max_flow_counter_31_16[0x10];
        u8         max_wqe_sz_sq_dc[0x10];
 
        u8         reserved_at_2e0[0x7];
@@ -981,7 +981,7 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 
        u8         reserved_at_340[0x8];
        u8         log_max_flow_counter_bulk[0x8];
-       u8         max_flow_counter[0x10];
+       u8         max_flow_counter_15_0[0x10];
 
 
        u8         reserved_at_360[0x3];
@@ -1071,8 +1071,7 @@ struct mlx5_ifc_dest_format_struct_bits {
 };
 
 struct mlx5_ifc_flow_counter_list_bits {
-       u8         reserved_at_0[0x10];
-       u8         flow_counter_id[0x10];
+       u8         flow_counter_id[0x20];
 
        u8         reserved_at_20[0x20];
 };
@@ -4402,8 +4401,7 @@ struct mlx5_ifc_query_flow_counter_in_bits {
        u8         reserved_at_c1[0xf];
        u8         num_of_counters[0x10];
 
-       u8         reserved_at_e0[0x10];
-       u8         flow_counter_id[0x10];
+       u8         flow_counter_id[0x20];
 };
 
 struct mlx5_ifc_query_esw_vport_context_out_bits {
@@ -6271,8 +6269,7 @@ struct mlx5_ifc_dealloc_flow_counter_in_bits {
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
 
-       u8         reserved_at_40[0x10];
-       u8         flow_counter_id[0x10];
+       u8         flow_counter_id[0x20];
 
        u8         reserved_at_60[0x20];
 };
@@ -7097,8 +7094,7 @@ struct mlx5_ifc_alloc_flow_counter_out_bits {
 
        u8         syndrome[0x20];
 
-       u8         reserved_at_40[0x10];
-       u8         flow_counter_id[0x10];
+       u8         flow_counter_id[0x20];
 
        u8         reserved_at_60[0x20];
 };