Skip to content

Commit

Permalink
net/mlx5e: Prepare for flow meter offload if hardware supports it
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jianbo Liu authored and Saeed Mahameed committed Jul 2, 2022
1 parent c491ded commit 74e6b2a
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
81 changes: 81 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c
Original file line number Diff line number Diff line change
@@ -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);
}
16 changes: 16 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h
Original file line number Diff line number Diff line change
@@ -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__ */
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
25 changes: 25 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 74e6b2a

Please sign in to comment.