]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net/mlx5: fs, add counter object to flow destination
authorMoshe Shemesh <moshe@nvidia.com>
Thu, 19 Dec 2024 17:58:33 +0000 (19:58 +0200)
committerJakub Kicinski <kuba@kernel.org>
Mon, 23 Dec 2024 18:34:45 +0000 (10:34 -0800)
Currently mlx5_flow_destination includes counter_id which is assigned in
case we use flow counter on the flow steering rule. However, counter_id
is not enough data in case of using HW Steering. Thus, have mlx5_fc
object as part of mlx5_flow_destination instead of counter_id and assign
it where needed.

In case counter_id is received from user space, create a local counter
object to represent it.

Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20241219175841.1094544-4-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
15 files changed:
drivers/infiniband/hw/mlx5/fs.c
drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
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_core.c
drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c
drivers/net/ethernet/mellanox/mlx5/core/steering/sws/fs_dr.c
drivers/vdpa/mlx5/net/mlx5_vnet.c
include/linux/mlx5/fs.h

index 520034acf73aac388ae7f66851fb990ea6adec72..162814ae8cb4ef9310167abe904fe6b303d7eaed 100644 (file)
@@ -943,7 +943,7 @@ int mlx5_ib_fs_add_op_fc(struct mlx5_ib_dev *dev, u32 port_num,
        }
 
        dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dst.counter_id = mlx5_fc_id(opfc->fc);
+       dst.counter = opfc->fc;
 
        flow_act.action =
                MLX5_FLOW_CONTEXT_ACTION_COUNT | MLX5_FLOW_CONTEXT_ACTION_ALLOW;
@@ -1113,8 +1113,8 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
                handler->ibcounters = flow_act.counters;
                dest_arr[dest_num].type =
                        MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-               dest_arr[dest_num].counter_id =
-                       mlx5_fc_id(mcounters->hw_cntrs_hndl);
+               dest_arr[dest_num].counter =
+                       mcounters->hw_cntrs_hndl;
                dest_num++;
        }
 
@@ -1603,7 +1603,7 @@ static bool raw_fs_is_multicast(struct mlx5_ib_flow_matcher *fs_matcher,
 static struct mlx5_ib_flow_handler *raw_fs_rule_add(
        struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
        struct mlx5_flow_context *flow_context, struct mlx5_flow_act *flow_act,
-       u32 counter_id, void *cmd_in, int inlen, int dest_id, int dest_type)
+       struct mlx5_fc *counter, void *cmd_in, int inlen, int dest_id, int dest_type)
 {
        struct mlx5_flow_destination *dst;
        struct mlx5_ib_flow_prio *ft_prio;
@@ -1652,8 +1652,12 @@ static struct mlx5_ib_flow_handler *raw_fs_rule_add(
        }
 
        if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
+               if (WARN_ON(!counter)) {
+                       err = -EINVAL;
+                       goto unlock;
+               }
                dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-               dst[dst_num].counter_id = counter_id;
+               dst[dst_num].counter = counter;
                dst_num++;
        }
 
@@ -1878,7 +1882,8 @@ static int get_dests(struct uverbs_attr_bundle *attrs,
        return 0;
 }
 
-static bool is_flow_counter(void *obj, u32 offset, u32 *counter_id)
+static bool
+is_flow_counter(void *obj, u32 offset, u32 *counter_id, u32 *fc_bulk_size)
 {
        struct devx_obj *devx_obj = obj;
        u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
@@ -1888,6 +1893,7 @@ static bool is_flow_counter(void *obj, u32 offset, u32 *counter_id)
                if (offset && offset >= devx_obj->flow_counter_bulk_size)
                        return false;
 
+               *fc_bulk_size = devx_obj->flow_counter_bulk_size;
                *counter_id = MLX5_GET(dealloc_flow_counter_in,
                                       devx_obj->dinbox,
                                       flow_counter_id);
@@ -1904,13 +1910,13 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
 {
        struct mlx5_flow_context flow_context = {.flow_tag =
                MLX5_FS_DEFAULT_FLOW_TAG};
-       u32 *offset_attr, offset = 0, counter_id = 0;
        int dest_id, dest_type = -1, inlen, len, ret, i;
        struct mlx5_ib_flow_handler *flow_handler;
        struct mlx5_ib_flow_matcher *fs_matcher;
        struct ib_uobject **arr_flow_actions;
        struct ib_uflow_resources *uflow_res;
        struct mlx5_flow_act flow_act = {};
+       struct mlx5_fc *counter = NULL;
        struct ib_qp *qp = NULL;
        void *devx_obj, *cmd_in;
        struct ib_uobject *uobj;
@@ -1937,6 +1943,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
        len = uverbs_attr_get_uobjs_arr(attrs,
                MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX, &arr_flow_actions);
        if (len) {
+               u32 *offset_attr, fc_bulk_size, offset = 0, counter_id = 0;
                devx_obj = arr_flow_actions[0]->object;
 
                if (uverbs_attr_is_valid(attrs,
@@ -1956,8 +1963,11 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
                        offset = *offset_attr;
                }
 
-               if (!is_flow_counter(devx_obj, offset, &counter_id))
+               if (!is_flow_counter(devx_obj, offset, &counter_id, &fc_bulk_size))
                        return -EINVAL;
+               counter = mlx5_fc_local_create(counter_id, offset, fc_bulk_size);
+               if (IS_ERR(counter))
+                       return PTR_ERR(counter);
 
                flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
        }
@@ -1968,8 +1978,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
                                    MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE);
 
        uflow_res = flow_resources_alloc(MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS);
-       if (!uflow_res)
-               return -ENOMEM;
+       if (!uflow_res) {
+               ret = -ENOMEM;
+               goto destroy_counter;
+       }
 
        len = uverbs_attr_get_uobjs_arr(attrs,
                MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS, &arr_flow_actions);
@@ -1996,7 +2008,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
 
        flow_handler =
                raw_fs_rule_add(dev, fs_matcher, &flow_context, &flow_act,
-                               counter_id, cmd_in, inlen, dest_id, dest_type);
+                               counter, cmd_in, inlen, dest_id, dest_type);
        if (IS_ERR(flow_handler)) {
                ret = PTR_ERR(flow_handler);
                goto err_out;
@@ -2007,6 +2019,9 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
        return 0;
 err_out:
        ib_uverbs_flow_resources_free(uflow_res);
+destroy_counter:
+       if (counter)
+               mlx5_fc_local_destroy(counter);
        return ret;
 }
 
index 9aed29fa490064b0d184e8515b87211739f9d536..d6e736c1fb246f89929be671822fd157d2ce3132 100644 (file)
@@ -292,7 +292,7 @@ TRACE_EVENT(mlx5_fs_add_rule,
                           if (rule->dest_attr.type &
                               MLX5_FLOW_DESTINATION_TYPE_COUNTER)
                                __entry->counter_id =
-                                       rule->dest_attr.counter_id;
+                                       mlx5_fc_id(rule->dest_attr.counter);
            ),
            TP_printk("rule=%p fte=%p index=%u sw_action=<%s> [dst] %s\n",
                      __entry->rule, __entry->fte, __entry->index,
index e51b03d4c717f1a740d3536fda4d492b3f57f198..687bd95d2c3e2a7a8c79d46b2deb2860d1910780 100644 (file)
@@ -194,7 +194,7 @@ static int rx_add_rule_drop_auth_trailer(struct mlx5e_ipsec_sa_entry *sa_entry,
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
        flow_act.flags = FLOW_ACT_NO_APPEND;
        dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest.counter_id = mlx5_fc_id(flow_counter);
+       dest.counter = flow_counter;
        if (rx == ipsec->rx_esw)
                spec->flow_context.flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK;
 
@@ -223,7 +223,7 @@ static int rx_add_rule_drop_auth_trailer(struct mlx5e_ipsec_sa_entry *sa_entry,
        }
        sa_entry->ipsec_rule.trailer.fc = flow_counter;
 
-       dest.counter_id = mlx5_fc_id(flow_counter);
+       dest.counter = flow_counter;
        MLX5_SET(fte_match_param, spec->match_value, misc_parameters_2.ipsec_syndrome, 2);
        rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
        if (IS_ERR(rule)) {
@@ -275,7 +275,7 @@ static int rx_add_rule_drop_replay(struct mlx5e_ipsec_sa_entry *sa_entry, struct
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
        flow_act.flags = FLOW_ACT_NO_APPEND;
        dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest.counter_id = mlx5_fc_id(flow_counter);
+       dest.counter = flow_counter;
        if (rx == ipsec->rx_esw)
                spec->flow_context.flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK;
 
@@ -348,7 +348,7 @@ static int ipsec_rx_status_drop_all_create(struct mlx5e_ipsec *ipsec,
 
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
        dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest.counter_id = mlx5_fc_id(flow_counter);
+       dest.counter = flow_counter;
        if (rx == ipsec->rx_esw)
                spec->flow_context.flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK;
        rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
@@ -686,7 +686,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
        rx->ft.status = ft;
 
        dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest[1].counter_id = mlx5_fc_id(rx->fc->cnt);
+       dest[1].counter = rx->fc->cnt;
        err = mlx5_ipsec_rx_status_create(ipsec, rx, dest);
        if (err)
                goto err_add;
@@ -873,7 +873,7 @@ static int ipsec_counter_rule_tx(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW |
                          MLX5_FLOW_CONTEXT_ACTION_COUNT;
        dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest.counter_id = mlx5_fc_id(tx->fc->cnt);
+       dest.counter = tx->fc->cnt;
        fte = mlx5_add_flow_rules(tx->ft.status, spec, &flow_act, &dest, 1);
        if (IS_ERR(fte)) {
                err = PTR_ERR(fte);
@@ -1649,7 +1649,7 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
        dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
        dest[0].ft = rx->ft.status;
        dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest[1].counter_id = mlx5_fc_id(counter);
+       dest[1].counter = counter;
        rule = mlx5_add_flow_rules(rx->ft.sa, spec, &flow_act, dest, 2);
        if (IS_ERR(rule)) {
                err = PTR_ERR(rule);
@@ -1762,7 +1762,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
        dest[0].ft = tx->ft.status;
        dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
        dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest[1].counter_id = mlx5_fc_id(counter);
+       dest[1].counter = counter;
        rule = mlx5_add_flow_rules(tx->ft.sa, spec, &flow_act, dest, 2);
        if (IS_ERR(rule)) {
                err = PTR_ERR(rule);
@@ -1835,7 +1835,7 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
                flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_DROP |
                                   MLX5_FLOW_CONTEXT_ACTION_COUNT;
                dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-               dest[dstn].counter_id = mlx5_fc_id(tx->fc->drop);
+               dest[dstn].counter = tx->fc->drop;
                dstn++;
                break;
        default:
@@ -1913,7 +1913,7 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
        case XFRM_POLICY_BLOCK:
                flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
                dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-               dest[dstn].counter_id = mlx5_fc_id(rx->fc->drop);
+               dest[dstn].counter = rx->fc->drop;
                dstn++;
                break;
        default:
index 6b3b1afe8312142e41014585b1bd2d68e9c5f23d..9ba99609999f4f47a36fb5186d917bcd51007110 100644 (file)
@@ -1282,7 +1282,7 @@ mlx5e_add_offloaded_nic_rule(struct mlx5e_priv *priv,
 
        if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
                dest[dest_ix].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-               dest[dest_ix].counter_id = mlx5_fc_id(attr->counter);
+               dest[dest_ix].counter = attr->counter;
                dest_ix++;
        }
 
index 6b4c9ffad95b29db2e8975d9ebd0e8a526cfe2f3..7dd1dc3f77c75f2ec05400f9686048c616748ee1 100644 (file)
@@ -135,7 +135,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
        if (drop_counter) {
                flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
                drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-               drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter);
+               drop_ctr_dst.counter = drop_counter;
                dst = &drop_ctr_dst;
                dest_num++;
        }
index 093ed86a0acd8c2da6697d704c4ec738eb039c7b..1c37098e09ea51422c1148e56ee2a9f76eb3583b 100644 (file)
@@ -260,7 +260,7 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
        if (counter) {
                flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
                drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-               drop_ctr_dst.counter_id = mlx5_fc_id(counter);
+               drop_ctr_dst.counter = counter;
                dst = &drop_ctr_dst;
                dest_num++;
        }
index c5ea1d1d2b035c111ed84b84c0bb4c0a664f742a..5f647358a05ca49698c998f2071d5a34a39a6928 100644 (file)
@@ -570,7 +570,8 @@ mlx5_esw_bridge_egress_table_cleanup(struct mlx5_esw_bridge *bridge)
 
 static struct mlx5_flow_handle *
 mlx5_esw_bridge_ingress_flow_with_esw_create(u16 vport_num, const unsigned char *addr,
-                                            struct mlx5_esw_bridge_vlan *vlan, u32 counter_id,
+                                            struct mlx5_esw_bridge_vlan *vlan,
+                                            struct mlx5_fc *counter,
                                             struct mlx5_esw_bridge *bridge,
                                             struct mlx5_eswitch *esw)
 {
@@ -628,7 +629,7 @@ mlx5_esw_bridge_ingress_flow_with_esw_create(u16 vport_num, const unsigned char
        dests[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
        dests[0].ft = bridge->egress_ft;
        dests[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dests[1].counter_id = counter_id;
+       dests[1].counter = counter;
 
        handle = mlx5_add_flow_rules(br_offloads->ingress_ft, rule_spec, &flow_act, dests,
                                     ARRAY_SIZE(dests));
@@ -639,17 +640,19 @@ mlx5_esw_bridge_ingress_flow_with_esw_create(u16 vport_num, const unsigned char
 
 static struct mlx5_flow_handle *
 mlx5_esw_bridge_ingress_flow_create(u16 vport_num, const unsigned char *addr,
-                                   struct mlx5_esw_bridge_vlan *vlan, u32 counter_id,
+                                   struct mlx5_esw_bridge_vlan *vlan,
+                                   struct mlx5_fc *counter,
                                    struct mlx5_esw_bridge *bridge)
 {
-       return mlx5_esw_bridge_ingress_flow_with_esw_create(vport_num, addr, vlan, counter_id,
+       return mlx5_esw_bridge_ingress_flow_with_esw_create(vport_num, addr, vlan, counter,
                                                            bridge, bridge->br_offloads->esw);
 }
 
 static struct mlx5_flow_handle *
 mlx5_esw_bridge_ingress_flow_peer_create(u16 vport_num, u16 esw_owner_vhca_id,
                                         const unsigned char *addr,
-                                        struct mlx5_esw_bridge_vlan *vlan, u32 counter_id,
+                                        struct mlx5_esw_bridge_vlan *vlan,
+                                        struct mlx5_fc *counter,
                                         struct mlx5_esw_bridge *bridge)
 {
        struct mlx5_devcom_comp_dev *devcom = bridge->br_offloads->esw->devcom, *pos;
@@ -671,7 +674,7 @@ mlx5_esw_bridge_ingress_flow_peer_create(u16 vport_num, u16 esw_owner_vhca_id,
                goto out;
        }
 
-       handle = mlx5_esw_bridge_ingress_flow_with_esw_create(vport_num, addr, vlan, counter_id,
+       handle = mlx5_esw_bridge_ingress_flow_with_esw_create(vport_num, addr, vlan, counter,
                                                              bridge, peer_esw);
 
 out:
@@ -1385,10 +1388,9 @@ mlx5_esw_bridge_fdb_entry_init(struct net_device *dev, u16 vport_num, u16 esw_ow
 
        handle = peer ?
                mlx5_esw_bridge_ingress_flow_peer_create(vport_num, esw_owner_vhca_id,
-                                                        addr, vlan, mlx5_fc_id(counter),
-                                                        bridge) :
+                                                        addr, vlan, counter, bridge) :
                mlx5_esw_bridge_ingress_flow_create(vport_num, addr, vlan,
-                                                   mlx5_fc_id(counter), bridge);
+                                                   counter, bridge);
        if (IS_ERR(handle)) {
                err = PTR_ERR(handle);
                esw_warn(esw->dev, "Failed to create ingress flow(vport=%u,err=%d,peer=%d)\n",
index d5b42b3a19fdf776060e679edb8c714f165e1c4d..8636f0485800da6b4751d1884120df22335207ae 100644 (file)
@@ -724,7 +724,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
 
        if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
                dest[i].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-               dest[i].counter_id = mlx5_fc_id(attr->counter);
+               dest[i].counter = attr->counter;
                i++;
        }
 
index 676005854dad4bfcf86512d19e54cdef760f4e56..6bf0aade69d75c9d38997ecef6da899ccb4b82d2 100644 (file)
@@ -718,7 +718,7 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
                                continue;
 
                        MLX5_SET(flow_counter_list, in_dests, flow_counter_id,
-                                dst->dest_attr.counter_id);
+                                mlx5_fc_id(dst->dest_attr.counter));
                        in_dests += dst_cnt_size;
                        list_size++;
                }
index 2eabfcc247c6ae755e9a0d2211f0dfc322e8b7ba..f781f8f169b9a9916fcc0a136869b4c65ba4be47 100644 (file)
@@ -658,6 +658,7 @@ static void del_sw_hw_rule(struct fs_node *node)
                        BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION) |
                        BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_FLOW_COUNTERS);
                fte->act_dests.action.action &= ~MLX5_FLOW_CONTEXT_ACTION_COUNT;
+               mlx5_fc_local_destroy(rule->dest_attr.counter);
                goto out;
        }
 
index 62d0c689796b975f30de710249bddc4985efde24..7d56deaa460972a8d7bab9999f808e28f58f5061 100644 (file)
 #define MLX5_FC_POOL_MAX_THRESHOLD BIT(18)
 #define MLX5_FC_POOL_USED_BUFF_RATIO 10
 
+enum mlx5_fc_type {
+       MLX5_FC_TYPE_ACQUIRED = 0,
+       MLX5_FC_TYPE_LOCAL,
+};
+
 struct mlx5_fc_cache {
        u64 packets;
        u64 bytes;
@@ -52,6 +57,7 @@ struct mlx5_fc_cache {
 struct mlx5_fc {
        u32 id;
        bool aging;
+       enum mlx5_fc_type type;
        struct mlx5_fc_bulk *bulk;
        struct mlx5_fc_cache cache;
        /* last{packets,bytes} are used for calculating deltas since last reading. */
@@ -186,6 +192,9 @@ static void mlx5_fc_release(struct mlx5_core_dev *dev, struct mlx5_fc *counter)
 {
        struct mlx5_fc_stats *fc_stats = dev->priv.fc_stats;
 
+       if (WARN_ON(counter->type == MLX5_FC_TYPE_LOCAL))
+               return;
+
        if (counter->bulk)
                mlx5_fc_pool_release_counter(&fc_stats->fc_pool, counter);
        else
@@ -536,6 +545,50 @@ static int mlx5_fc_bulk_release_fc(struct mlx5_fc_bulk *bulk, struct mlx5_fc *fc
        return 0;
 }
 
+/**
+ * mlx5_fc_local_create - Allocate mlx5_fc struct for a counter which
+ * was already acquired using its counter id and bulk data.
+ *
+ * @counter_id: counter acquired counter id
+ * @offset: counter offset from bulk base
+ * @bulk_size: counter's bulk size as was allocated
+ *
+ * Return: Pointer to mlx5_fc on success, ERR_PTR otherwise.
+ */
+struct mlx5_fc *
+mlx5_fc_local_create(u32 counter_id, u32 offset, u32 bulk_size)
+{
+       struct mlx5_fc_bulk *fc_bulk;
+       struct mlx5_fc *counter;
+
+       counter = kzalloc(sizeof(*counter), GFP_KERNEL);
+       if (!counter)
+               return ERR_PTR(-ENOMEM);
+       fc_bulk = kzalloc(sizeof(*fc_bulk), GFP_KERNEL);
+       if (!fc_bulk) {
+               kfree(counter);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       counter->type = MLX5_FC_TYPE_LOCAL;
+       counter->id = counter_id;
+       fc_bulk->base_id = counter_id - offset;
+       fc_bulk->bulk_len = bulk_size;
+       counter->bulk = fc_bulk;
+       return counter;
+}
+EXPORT_SYMBOL(mlx5_fc_local_create);
+
+void mlx5_fc_local_destroy(struct mlx5_fc *counter)
+{
+       if (!counter || counter->type != MLX5_FC_TYPE_LOCAL)
+               return;
+
+       kfree(counter->bulk);
+       kfree(counter);
+}
+EXPORT_SYMBOL(mlx5_fc_local_destroy);
+
 /* Flow counters pool API */
 
 static void mlx5_fc_pool_init(struct mlx5_fc_pool *fc_pool, struct mlx5_core_dev *dev)
index 4a078113e292d60a5b301b07acdb62a785974b1f..762d55ba9e513151530cf6339fddcb87811074f0 100644 (file)
@@ -497,7 +497,7 @@ static int macsec_fs_tx_create(struct mlx5_macsec_fs *macsec_fs)
        memset(&dest, 0, sizeof(struct mlx5_flow_destination));
        memset(&flow_act, 0, sizeof(flow_act));
        dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest.counter_id = mlx5_fc_id(tx_tables->check_miss_rule_counter);
+       dest.counter = tx_tables->check_miss_rule_counter;
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
        rule = mlx5_add_flow_rules(tx_tables->ft_check,  NULL, &flow_act, &dest, 1);
        if (IS_ERR(rule)) {
@@ -519,7 +519,7 @@ static int macsec_fs_tx_create(struct mlx5_macsec_fs *macsec_fs)
        flow_act.flags = FLOW_ACT_NO_APPEND;
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW | MLX5_FLOW_CONTEXT_ACTION_COUNT;
        dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest.counter_id = mlx5_fc_id(tx_tables->check_rule_counter);
+       dest.counter = tx_tables->check_rule_counter;
        rule = mlx5_add_flow_rules(tx_tables->ft_check, spec, &flow_act, &dest, 1);
        if (IS_ERR(rule)) {
                err = PTR_ERR(rule);
@@ -1200,7 +1200,7 @@ static int macsec_fs_rx_create_check_decap_rule(struct mlx5_macsec_fs *macsec_fs
        flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT |
                            MLX5_FLOW_CONTEXT_ACTION_COUNT;
        roce_dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       roce_dest[dstn].counter_id = mlx5_fc_id(rx_tables->check_rule_counter);
+       roce_dest[dstn].counter = rx_tables->check_rule_counter;
        rule = mlx5_add_flow_rules(rx_tables->ft_check, spec, flow_act, roce_dest, dstn + 1);
 
        if (IS_ERR(rule)) {
@@ -1592,7 +1592,7 @@ static int macsec_fs_rx_create(struct mlx5_macsec_fs *macsec_fs)
        memset(&flow_act, 0, sizeof(flow_act));
 
        dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-       dest.counter_id = mlx5_fc_id(rx_tables->check_miss_rule_counter);
+       dest.counter = rx_tables->check_miss_rule_counter;
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT;
        rule = mlx5_add_flow_rules(rx_tables->ft_check,  NULL, &flow_act, &dest, 1);
        if (IS_ERR(rule)) {
index 4b349d4005e448eb129b952954d986f302ac0a2b..8007d3f523c94ee4e4fd8e629dc8a26163f9e338 100644 (file)
@@ -521,7 +521,7 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
                                goto free_actions;
                        }
 
-                       id = dst->dest_attr.counter_id;
+                       id = mlx5_fc_id(dst->dest_attr.counter);
                        tmp_action =
                                mlx5dr_action_create_flow_counter(id);
                        if (!tmp_action) {
index 5f581e71e201052da95316969799d1efaed5f50e..36099047560df982b8ed647ac7a2019a2519aafe 100644 (file)
@@ -1952,7 +1952,7 @@ static int mlx5_vdpa_add_mac_vlan_rules(struct mlx5_vdpa_net *ndev, u8 *mac,
                goto out_free;
 
 #if defined(CONFIG_MLX5_VDPA_STEERING_DEBUG)
-       dests[1].counter_id = mlx5_fc_id(node->ucast_counter.counter);
+       dests[1].counter = node->ucast_counter.counter;
 #endif
        node->ucast_rule = mlx5_add_flow_rules(ndev->rxft, spec, &flow_act, dests, NUM_DESTS);
        if (IS_ERR(node->ucast_rule)) {
@@ -1961,7 +1961,7 @@ static int mlx5_vdpa_add_mac_vlan_rules(struct mlx5_vdpa_net *ndev, u8 *mac,
        }
 
 #if defined(CONFIG_MLX5_VDPA_STEERING_DEBUG)
-       dests[1].counter_id = mlx5_fc_id(node->mcast_counter.counter);
+       dests[1].counter = node->mcast_counter.counter;
 #endif
 
        memset(dmac_c, 0, ETH_ALEN);
index 438db888bde0d6b0467ed0a7c2296badbc490bcf..2a69d9d71276d6f4147f01e2207f2e57ed626447 100644 (file)
@@ -163,7 +163,7 @@ struct mlx5_flow_destination {
                u32                     tir_num;
                u32                     ft_num;
                struct mlx5_flow_table  *ft;
-               u32                     counter_id;
+               struct mlx5_fc          *counter;
                struct {
                        u16             num;
                        u16             vhca_id;
@@ -299,6 +299,8 @@ int mlx5_modify_rule_destination(struct mlx5_flow_handle *handler,
 struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging);
 
 void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter);
+struct mlx5_fc *mlx5_fc_local_create(u32 counter_id, u32 offset, u32 bulk_size);
+void mlx5_fc_local_destroy(struct mlx5_fc *counter);
 u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter);
 void mlx5_fc_query_cached(struct mlx5_fc *counter,
                          u64 *bytes, u64 *packets, u64 *lastuse);