]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net/mlx5e: Prepare for flow meter offload if hardware supports it
authorJianbo Liu <jianbol@nvidia.com>
Wed, 9 Jun 2021 03:11:58 +0000 (03:11 +0000)
committerSaeed Mahameed <saeedm@nvidia.com>
Sat, 2 Jul 2022 18:58:27 +0000 (11:58 -0700)
If flow meter aso object is supported, set the allocated range, and
initialize aso wqe.

The allocated range is indicated by log_meter_aso_granularity in HW
capabilities, and currently is 6.

Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Roi Dayan <roid@nvidia.com>
Reviewed-by: Maor Dickman <maord@nvidia.com>
Reviewed-by: Ariel Levkovich <lariel@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/Makefile
drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c [new file with mode: 0644]
drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h [new file with mode: 0644]
drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h

index a3381354a07d17e08c7844807aa4f781e679c442..1553d94ba3d237829477aa9408bdf89255eb1335 100644 (file)
@@ -45,7 +45,7 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT)     += en_tc.o en/rep/tc.o en/rep/neigh.o \
                                        esw/indir_table.o en/tc_tun_encap.o \
                                        en/tc_tun_vxlan.o en/tc_tun_gre.o en/tc_tun_geneve.o \
                                        en/tc_tun_mplsoudp.o diag/en_tc_tracepoint.o \
-                                       en/tc/post_act.o en/tc/int_port.o
+                                       en/tc/post_act.o en/tc/int_port.o en/tc/meter.o
 
 mlx5_core-$(CONFIG_MLX5_CLS_ACT)     += en/tc/act/act.o en/tc/act/drop.o en/tc/act/trap.o \
                                        en/tc/act/accept.o en/tc/act/mark.o en/tc/act/goto.o \
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c
new file mode 100644 (file)
index 0000000..1643530
--- /dev/null
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+#include "lib/aso.h"
+#include "en/tc/post_act.h"
+#include "meter.h"
+
+struct mlx5e_flow_meters {
+       enum mlx5_flow_namespace_type ns_type;
+       struct mlx5_aso *aso;
+       struct mutex aso_lock; /* Protects aso operations */
+       int log_granularity;
+       u32 pdn;
+
+       struct mlx5_core_dev *mdev;
+       struct mlx5e_post_act *post_act;
+};
+
+struct mlx5e_flow_meters *
+mlx5e_flow_meters_init(struct mlx5e_priv *priv,
+                      enum mlx5_flow_namespace_type ns_type,
+                      struct mlx5e_post_act *post_act)
+{
+       struct mlx5_core_dev *mdev = priv->mdev;
+       struct mlx5e_flow_meters *flow_meters;
+       int err;
+
+       if (!(MLX5_CAP_GEN_64(mdev, general_obj_types) &
+             MLX5_HCA_CAP_GENERAL_OBJECT_TYPES_FLOW_METER_ASO))
+               return ERR_PTR(-EOPNOTSUPP);
+
+       if (IS_ERR_OR_NULL(post_act)) {
+               netdev_dbg(priv->netdev,
+                          "flow meter offload is not supported, post action is missing\n");
+               return ERR_PTR(-EOPNOTSUPP);
+       }
+
+       flow_meters = kzalloc(sizeof(*flow_meters), GFP_KERNEL);
+       if (!flow_meters)
+               return ERR_PTR(-ENOMEM);
+
+       err = mlx5_core_alloc_pd(mdev, &flow_meters->pdn);
+       if (err) {
+               mlx5_core_err(mdev, "Failed to alloc pd for flow meter aso, err=%d\n", err);
+               goto err_out;
+       }
+
+       flow_meters->aso = mlx5_aso_create(mdev, flow_meters->pdn);
+       if (IS_ERR(flow_meters->aso)) {
+               mlx5_core_warn(mdev, "Failed to create aso wqe for flow meter\n");
+               err = PTR_ERR(flow_meters->aso);
+               goto err_sq;
+       }
+
+       flow_meters->ns_type = ns_type;
+       flow_meters->mdev = mdev;
+       flow_meters->post_act = post_act;
+       mutex_init(&flow_meters->aso_lock);
+       flow_meters->log_granularity = min_t(int, 6,
+                                            MLX5_CAP_QOS(mdev, log_meter_aso_max_alloc));
+
+       return flow_meters;
+
+err_sq:
+       mlx5_core_dealloc_pd(mdev, flow_meters->pdn);
+err_out:
+       kfree(flow_meters);
+       return ERR_PTR(err);
+}
+
+void
+mlx5e_flow_meters_cleanup(struct mlx5e_flow_meters *flow_meters)
+{
+       if (IS_ERR_OR_NULL(flow_meters))
+               return;
+
+       mlx5_aso_destroy(flow_meters->aso);
+       mlx5_core_dealloc_pd(flow_meters->mdev, flow_meters->pdn);
+
+       kfree(flow_meters);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h
new file mode 100644 (file)
index 0000000..53dc6c8
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
+
+#ifndef __MLX5_EN_FLOW_METER_H__
+#define __MLX5_EN_FLOW_METER_H__
+
+struct mlx5e_flow_meters;
+
+struct mlx5e_flow_meters *
+mlx5e_flow_meters_init(struct mlx5e_priv *priv,
+                      enum mlx5_flow_namespace_type ns_type,
+                      struct mlx5e_post_act *post_action);
+void
+mlx5e_flow_meters_cleanup(struct mlx5e_flow_meters *flow_meters);
+
+#endif /* __MLX5_EN_FLOW_METER_H__ */
index 3b74a6fd5c43f2dd63d12f05c9bd5e72f82d93c7..bb7a6549cd66e5d733ac7984566cfe04b4b8adad 100644 (file)
@@ -203,6 +203,8 @@ struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow);
 struct mlx5e_tc_int_port_priv *
 mlx5e_get_int_port_priv(struct mlx5e_priv *priv);
 
+struct mlx5e_flow_meters *mlx5e_get_flow_meters(struct mlx5_core_dev *dev);
+
 void *mlx5e_get_match_headers_value(u32 flags, struct mlx5_flow_spec *spec);
 void *mlx5e_get_match_headers_criteria(u32 flags, struct mlx5_flow_spec *spec);
 
index adf5cc6a7b8ce3d649680e58d149b567e580ccce..dec183ccd4acbc9240aed92f0b3c8fd8529d6fe6 100644 (file)
@@ -62,6 +62,7 @@ struct mlx5_tc_int_port_priv;
 struct mlx5e_rep_bond;
 struct mlx5e_tc_tun_encap;
 struct mlx5e_post_act;
+struct mlx5e_flow_meters;
 
 struct mlx5_rep_uplink_priv {
        /* indirect block callbacks are invoked on bind/unbind events
@@ -97,6 +98,8 @@ struct mlx5_rep_uplink_priv {
 
        /* OVS internal port support */
        struct mlx5e_tc_int_port_priv *int_port_priv;
+
+       struct mlx5e_flow_meters *flow_meters;
 };
 
 struct mlx5e_rep_priv {
index 34bf11cdf90fc6ef7e610ffa45484c8663e60d23..31b59f6b3f4c4511159165fc366fc5f2e0d28a51 100644 (file)
@@ -240,6 +240,30 @@ mlx5e_get_int_port_priv(struct mlx5e_priv *priv)
        return NULL;
 }
 
+struct mlx5e_flow_meters *
+mlx5e_get_flow_meters(struct mlx5_core_dev *dev)
+{
+       struct mlx5_eswitch *esw = dev->priv.eswitch;
+       struct mlx5_rep_uplink_priv *uplink_priv;
+       struct mlx5e_rep_priv *uplink_rpriv;
+       struct mlx5e_priv *priv;
+
+       if (is_mdev_switchdev_mode(dev)) {
+               uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
+               uplink_priv = &uplink_rpriv->uplink_priv;
+               priv = netdev_priv(uplink_rpriv->netdev);
+               if (!uplink_priv->flow_meters)
+                       uplink_priv->flow_meters =
+                               mlx5e_flow_meters_init(priv,
+                                                      MLX5_FLOW_NAMESPACE_FDB,
+                                                      uplink_priv->post_act);
+               if (!IS_ERR(uplink_priv->flow_meters))
+                       return uplink_priv->flow_meters;
+       }
+
+       return NULL;
+}
+
 static struct mlx5_tc_ct_priv *
 get_ct_priv(struct mlx5e_priv *priv)
 {
@@ -4956,6 +4980,7 @@ void mlx5e_tc_esw_cleanup(struct mlx5_rep_uplink_priv *uplink_priv)
        mlx5e_tc_sample_cleanup(uplink_priv->tc_psample);
        mlx5e_tc_int_port_cleanup(uplink_priv->int_port_priv);
        mlx5_tc_ct_clean(uplink_priv->ct_priv);
+       mlx5e_flow_meters_cleanup(uplink_priv->flow_meters);
        mlx5e_tc_post_act_destroy(uplink_priv->post_act);
 }
 
index e2a1250aeca177115b8d21ad386f2665cee5914f..140b01d4d0831e8e6e5672cfb6be750018633a43 100644 (file)
@@ -39,6 +39,7 @@
 #include "en/tc_ct.h"
 #include "en/tc_tun.h"
 #include "en/tc/int_port.h"
+#include "en/tc/meter.h"
 #include "en_rep.h"
 
 #define MLX5E_TC_FLOW_ID_MASK 0x0000ffff