Commit 95f68e06 authored by Moshe Shemesh's avatar Moshe Shemesh Committed by Jakub Kicinski
Browse files

net/mlx5: fs, add counter object to flow destination



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: default avatarMoshe Shemesh <moshe@nvidia.com>
Reviewed-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: default avatarMark Bloch <mbloch@nvidia.com>
Signed-off-by: default avatarTariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20241219175841.1094544-4-tariqt@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 60d01cc4
Loading
Loading
Loading
Loading
+26 −11
Original line number Diff line number Diff line
@@ -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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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,
+10 −10
Original line number Diff line number Diff line
@@ -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:
+1 −1
Original line number Diff line number Diff line
@@ -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++;
	}

+1 −1
Original line number Diff line number Diff line
@@ -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++;
	}
Loading