Commit b8335829 authored by Vlad Dogaru's avatar Vlad Dogaru Committed by Jakub Kicinski
Browse files

net/mlx5: HWS, make sure the uplink is the last destination



When there are more than one destinations, we create a FW flow
table and provide it with all the destinations. FW requires to
have wire as the last destination in the list (if it exists),
otherwise the operation fails with FW syndrome.

This patch fixes the destination array action creation: if it
contains a wire destination, it is moved to the end.

Fixes: 504e536d ("net/mlx5: HWS, added actions handling")
Signed-off-by: default avatarVlad Dogaru <vdogaru@nvidia.com>
Reviewed-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Signed-off-by: default avatarMark Bloch <mbloch@nvidia.com>
Link: https://patch.msgid.link/20250610151514.1094735-7-mbloch@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent b5e3c76f
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -1370,8 +1370,8 @@ mlx5hws_action_create_dest_array(struct mlx5hws_context *ctx,
	struct mlx5hws_cmd_set_fte_attr fte_attr = {0};
	struct mlx5hws_cmd_forward_tbl *fw_island;
	struct mlx5hws_action *action;
	u32 i /*, packet_reformat_id*/;
	int ret;
	int ret, last_dest_idx = -1;
	u32 i;

	if (num_dest <= 1) {
		mlx5hws_err(ctx, "Action must have multiple dests\n");
@@ -1401,11 +1401,8 @@ mlx5hws_action_create_dest_array(struct mlx5hws_context *ctx,
			dest_list[i].destination_id = dests[i].dest->dest_obj.obj_id;
			fte_attr.action_flags |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
			fte_attr.ignore_flow_level = ignore_flow_level;
			/* ToDo: In SW steering we have a handling of 'go to WIRE'
			 * destination here by upper layer setting 'is_wire_ft' flag
			 * if the destination is wire.
			 * This is because uplink should be last dest in the list.
			 */
			if (dests[i].is_wire_ft)
				last_dest_idx = i;
			break;
		case MLX5HWS_ACTION_TYP_VPORT:
			dest_list[i].destination_type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
@@ -1429,6 +1426,9 @@ mlx5hws_action_create_dest_array(struct mlx5hws_context *ctx,
		}
	}

	if (last_dest_idx != -1)
		swap(dest_list[last_dest_idx], dest_list[num_dest - 1]);

	fte_attr.dests_num = num_dest;
	fte_attr.dests = dest_list;

+3 −0
Original line number Diff line number Diff line
@@ -966,6 +966,9 @@ static int mlx5_fs_fte_get_hws_actions(struct mlx5_flow_root_namespace *ns,
			switch (attr->type) {
			case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE:
				dest_action = mlx5_fs_get_dest_action_ft(fs_ctx, dst);
				if (dst->dest_attr.ft->flags &
				    MLX5_FLOW_TABLE_UPLINK_VPORT)
					dest_actions[num_dest_actions].is_wire_ft = true;
				break;
			case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM:
				dest_action = mlx5_fs_get_dest_action_table_num(fs_ctx,
+1 −0
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ struct mlx5hws_action_dest_attr {
	struct mlx5hws_action *dest;
	/* Optional reformat action */
	struct mlx5hws_action *reformat;
	bool is_wire_ft;
};

/**