OSDN Git Service

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 95b6402..e7c186b 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 e750f07..16b32f3 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 0f98a7c..c6d7bdf 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 990acee..9fb5a33 100644 (file)
@@ -136,7 +136,7 @@ struct mlx5_fc {
        u64 lastpackets;
        u64 lastbytes;
 
-       u16 id;
+       u32 id;
        bool deleted;
        bool aging;
 
index 6507d8a..89d1f86 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 f847a3a..c99daff 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];
 };