Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfc5d839 authored by Mark Bloch's avatar Mark Bloch Committed by Jason Gunthorpe
Browse files

RDMA/mlx5: Attach a DEVX counter via raw flow creation



Allow a user to attach a DEVX counter via mlx5 raw flow creation. In order
to attach a counter we introduce a new attribute:

MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX

A counter can be attached to multiple flow steering rules.

Signed-off-by: default avatarMark Bloch <markb@mellanox.com>
Reviewed-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 67810e8c
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -107,6 +107,21 @@ bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type)
	}
}

bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id)
{
	struct devx_obj *devx_obj = obj;
	u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);

	if (opcode == MLX5_CMD_OP_DEALLOC_FLOW_COUNTER) {
		*counter_id = MLX5_GET(dealloc_flow_counter_in,
				       devx_obj->dinbox,
				       flow_counter_id);
		return true;
	}

	return false;
}

/*
 * As the obj_id in the firmware is not globally unique the object type
 * must be considered upon checking for a valid object id.
+16 −1
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
		uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_CREATE_FLOW_HANDLE);
	struct mlx5_ib_dev *dev = to_mdev(uobj->context->device);
	int len, ret, i;
	u32 counter_id = 0;

	if (!capable(CAP_NET_RAW))
		return -EPERM;
@@ -128,6 +129,15 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
		dest_type = MLX5_FLOW_DESTINATION_TYPE_PORT;
	}

	len = uverbs_attr_get_uobjs_arr(attrs,
		MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX, &arr_flow_actions);
	if (len) {
		devx_obj = arr_flow_actions[0]->object;

		if (!mlx5_ib_devx_is_flow_counter(devx_obj, &counter_id))
			return -EINVAL;
		flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
	}
	if (dev->rep)
		return -ENOTSUPP;

@@ -164,6 +174,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
	}

	flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher, &flow_act,
					       counter_id,
					       cmd_in, inlen,
					       dest_id, dest_type);
	if (IS_ERR(flow_handler)) {
@@ -524,6 +535,10 @@ DECLARE_UVERBS_NAMED_METHOD(
			     UA_OPTIONAL),
	UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_TAG,
			   UVERBS_ATTR_TYPE(u32),
			   UA_OPTIONAL),
	UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
			     MLX5_IB_OBJECT_DEVX_OBJ,
			     UVERBS_ACCESS_READ, 1, 1,
			     UA_OPTIONAL));

DECLARE_UVERBS_NAMED_METHOD_DESTROY(
+20 −9
Original line number Diff line number Diff line
@@ -3713,7 +3713,8 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev,
		      struct mlx5_flow_destination *dst,
		      struct mlx5_ib_flow_matcher  *fs_matcher,
		      struct mlx5_flow_act *flow_act,
		      void *cmd_in, int inlen)
		      void *cmd_in, int inlen,
		      int dst_num)
{
	struct mlx5_ib_flow_handler *handler;
	struct mlx5_flow_spec *spec;
@@ -3735,7 +3736,7 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev,
	spec->match_criteria_enable = fs_matcher->match_criteria_enable;

	handler->rule = mlx5_add_flow_rules(ft, spec,
					    flow_act, dst, 1);
					    flow_act, dst, dst_num);

	if (IS_ERR(handler->rule)) {
		err = PTR_ERR(handler->rule);
@@ -3798,12 +3799,14 @@ struct mlx5_ib_flow_handler *
mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
			struct mlx5_ib_flow_matcher *fs_matcher,
			struct mlx5_flow_act *flow_act,
			u32 counter_id,
			void *cmd_in, int inlen, int dest_id,
			int dest_type)
{
	struct mlx5_flow_destination *dst;
	struct mlx5_ib_flow_prio *ft_prio;
	struct mlx5_ib_flow_handler *handler;
	int dst_num = 0;
	bool mcast;
	int err;

@@ -3813,7 +3816,7 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
	if (fs_matcher->priority > MLX5_IB_FLOW_LAST_PRIO)
		return ERR_PTR(-ENOMEM);

	dst = kzalloc(sizeof(*dst), GFP_KERNEL);
	dst = kzalloc(sizeof(*dst) * 2, GFP_KERNEL);
	if (!dst)
		return ERR_PTR(-ENOMEM);

@@ -3827,20 +3830,28 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
	}

	if (dest_type == MLX5_FLOW_DESTINATION_TYPE_TIR) {
		dst->type = dest_type;
		dst->tir_num = dest_id;
		dst[dst_num].type = dest_type;
		dst[dst_num].tir_num = dest_id;
		flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
	} else if (dest_type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE) {
		dst->type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM;
		dst->ft_num = dest_id;
		dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM;
		dst[dst_num].ft_num = dest_id;
		flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
	} else {
		dst->type = MLX5_FLOW_DESTINATION_TYPE_PORT;
		dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_PORT;
		flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
	}

	dst_num++;

	if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
		dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
		dst[dst_num].counter_id = counter_id;
		dst_num++;
	}

	handler = _create_raw_flow_rule(dev, ft_prio, dst, fs_matcher, flow_act,
					cmd_in, inlen);
					cmd_in, inlen, dst_num);

	if (IS_ERR(handler)) {
		err = PTR_ERR(handler);
+4 −2
Original line number Diff line number Diff line
@@ -1266,9 +1266,11 @@ extern const struct uapi_definition mlx5_ib_devx_defs[];
extern const struct uapi_definition mlx5_ib_flow_defs[];
struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add(
	struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
	struct mlx5_flow_act *flow_act, void *cmd_in, int inlen,
	int dest_id, int dest_type);
	struct mlx5_flow_act *flow_act, u32 counter_id,
	void *cmd_in, int inlen, int dest_id, int dest_type);
bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type);
bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id);
int mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root);
void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction);
#else
static inline int
+1 −0
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@ enum mlx5_ib_create_flow_attrs {
	MLX5_IB_ATTR_CREATE_FLOW_MATCHER,
	MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS,
	MLX5_IB_ATTR_CREATE_FLOW_TAG,
	MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
};

enum mlx5_ib_destoy_flow_attrs {