Commit 6fda078d authored by Oz Shlomo's avatar Oz Shlomo Committed by Saeed Mahameed
Browse files

net/mlx5e: TC, add support for meter mtu offload



Initialize the meter object with the TC police mtu parameter.
Use the hardware range destination to compare the pkt len to the mtu setting.
Assign the range destination hit/miss ft to the police conform/exceed
attributes.

Signed-off-by: default avatarOz Shlomo <ozsh@nvidia.com>
Reviewed-by: default avatarRoi Dayan <roid@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent d5671325
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@

#include "act.h"
#include "en/tc_priv.h"
#include "fs_core.h"

static bool police_act_validate_control(enum flow_action_id act_id,
					struct netlink_ext_ack *extack)
@@ -71,6 +72,8 @@ fill_meter_params_from_act(const struct flow_action_entry *act,
		params->mode = MLX5_RATE_LIMIT_PPS;
		params->rate = act->police.rate_pkt_ps;
		params->burst = act->police.burst_pkt;
	} else if (act->police.mtu) {
		params->mtu = act->police.mtu;
	} else {
		return -EOPNOTSUPP;
	}
@@ -84,14 +87,25 @@ tc_act_parse_police(struct mlx5e_tc_act_parse_state *parse_state,
		    struct mlx5e_priv *priv,
		    struct mlx5_flow_attr *attr)
{
	enum mlx5_flow_namespace_type ns =  mlx5e_get_flow_namespace(parse_state->flow);
	struct mlx5e_flow_meter_params *params = &attr->meter_attr.params;
	int err;

	err = fill_meter_params_from_act(act, &attr->meter_attr.params);
	err = fill_meter_params_from_act(act, params);
	if (err)
		return err;

	if (params->mtu) {
		if (!(mlx5_fs_get_capabilities(priv->mdev, ns) &
		      MLX5_FLOW_STEERING_CAP_MATCH_RANGES))
			return -EOPNOTSUPP;

		attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
		attr->flags |= MLX5_ATTR_FLAG_MTU;
	} else {
		attr->action |= MLX5_FLOW_CONTEXT_ACTION_EXECUTE_ASO;
		attr->exe_aso_type = MLX5_EXE_ASO_FLOW_METER;
	}

	return 0;
}
+12 −3
Original line number Diff line number Diff line
@@ -241,7 +241,7 @@ mlx5e_flow_meter_destroy_aso_obj(struct mlx5_core_dev *mdev, u32 obj_id)
}

static struct mlx5e_flow_meter_handle *
__mlx5e_flow_meter_alloc(struct mlx5e_flow_meters *flow_meters)
__mlx5e_flow_meter_alloc(struct mlx5e_flow_meters *flow_meters, bool alloc_aso)
{
	struct mlx5_core_dev *mdev = flow_meters->mdev;
	struct mlx5e_flow_meter_aso_obj *meters_obj;
@@ -268,6 +268,9 @@ __mlx5e_flow_meter_alloc(struct mlx5e_flow_meters *flow_meters)
	}
	meter->act_counter = counter;

	if (!alloc_aso)
		goto no_aso;

	meters_obj = list_first_entry_or_null(&flow_meters->partial_list,
					      struct mlx5e_flow_meter_aso_obj,
					      entry);
@@ -300,11 +303,12 @@ __mlx5e_flow_meter_alloc(struct mlx5e_flow_meters *flow_meters)
	}

	bitmap_set(meters_obj->meters_map, pos, 1);
	meter->flow_meters = flow_meters;
	meter->meters_obj = meters_obj;
	meter->obj_id = meters_obj->base_id + pos / 2;
	meter->idx = pos % 2;

no_aso:
	meter->flow_meters = flow_meters;
	mlx5_core_dbg(mdev, "flow meter allocated, obj_id=0x%x, index=%d\n",
		      meter->obj_id, meter->idx);

@@ -332,6 +336,9 @@ __mlx5e_flow_meter_free(struct mlx5e_flow_meter_handle *meter)
	mlx5_fc_destroy(mdev, meter->act_counter);
	mlx5_fc_destroy(mdev, meter->drop_counter);

	if (meter->params.mtu)
		goto out_no_aso;

	meters_obj = meter->meters_obj;
	pos = (meter->obj_id - meters_obj->base_id) * 2 + meter->idx;
	bitmap_clear(meters_obj->meters_map, pos, 1);
@@ -345,6 +352,7 @@ __mlx5e_flow_meter_free(struct mlx5e_flow_meter_handle *meter)
		list_add(&meters_obj->entry, &flow_meters->partial_list);
	}

out_no_aso:
	mlx5_core_dbg(mdev, "flow meter freed, obj_id=0x%x, index=%d\n",
		      meter->obj_id, meter->idx);
	kfree(meter);
@@ -409,12 +417,13 @@ mlx5e_tc_meter_alloc(struct mlx5e_flow_meters *flow_meters,
{
	struct mlx5e_flow_meter_handle *meter;

	meter = __mlx5e_flow_meter_alloc(flow_meters);
	meter = __mlx5e_flow_meter_alloc(flow_meters, !params->mtu);
	if (IS_ERR(meter))
		return meter;

	hash_add(flow_meters->hashtbl, &meter->hlist, params->index);
	meter->params.index = params->index;
	meter->params.mtu = params->mtu;
	meter->refcnt++;

	return meter;
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ struct mlx5e_flow_meter_params {
	u32 index;
	u64 rate;
	u64 burst;
	u32 mtu;
};

struct mlx5e_flow_meter_handle {
+12 −0
Original line number Diff line number Diff line
@@ -43,6 +43,18 @@ mlx5e_post_meter_get_ft(struct mlx5e_post_meter_priv *post_meter)
	return post_meter->rate_steering_table.ft;
}

struct mlx5_flow_table *
mlx5e_post_meter_get_mtu_true_ft(struct mlx5e_post_meter_priv *post_meter)
{
	return post_meter->mtu_tables.green_table.ft;
}

struct mlx5_flow_table *
mlx5e_post_meter_get_mtu_false_ft(struct mlx5e_post_meter_priv *post_meter)
{
	return post_meter->mtu_tables.red_table.ft;
}

static struct mlx5_flow_table *
mlx5e_post_meter_table_create(struct mlx5e_priv *priv,
			      enum mlx5_flow_namespace_type ns_type)
+24 −0
Original line number Diff line number Diff line
@@ -19,9 +19,17 @@ enum mlx5e_post_meter_type {
	MLX5E_POST_METER_MTU
};

#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)

struct mlx5_flow_table *
mlx5e_post_meter_get_ft(struct mlx5e_post_meter_priv *post_meter);

struct mlx5_flow_table *
mlx5e_post_meter_get_mtu_true_ft(struct mlx5e_post_meter_priv *post_meter);

struct mlx5_flow_table *
mlx5e_post_meter_get_mtu_false_ft(struct mlx5e_post_meter_priv *post_meter);

struct mlx5e_post_meter_priv *
mlx5e_post_meter_init(struct mlx5e_priv *priv,
		      enum mlx5_flow_namespace_type ns_type,
@@ -35,4 +43,20 @@ mlx5e_post_meter_init(struct mlx5e_priv *priv,
void
mlx5e_post_meter_cleanup(struct mlx5_eswitch *esw, struct mlx5e_post_meter_priv *post_meter);

#else /* CONFIG_MLX5_CLS_ACT */

static inline struct mlx5_flow_table *
mlx5e_post_meter_get_mtu_true_ft(struct mlx5e_post_meter_priv *post_meter)
{
	return NULL;
}

static inline struct mlx5_flow_table *
mlx5e_post_meter_get_mtu_false_ft(struct mlx5e_post_meter_priv *post_meter)
{
	return NULL;
}

#endif

#endif /* __MLX5_EN_POST_METER_H__ */
Loading