Commit 1bc60524 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Leon Romanovsky says:

====================
This PR is collected from
https://lore.kernel.org/all/cover.1695296682.git.leon@kernel.org

This series from Patrisious extends mlx5 to support IPsec packet offload
in multiport devices (MPV, see [1] for more details).

These devices have single flow steering logic and two netdev interfaces,
which require extra logic to manage IPsec configurations as they performed
on netdevs.

[1] https://lore.kernel.org/linux-rdma/20180104152544.28919-1-leon@kernel.org/

* 'mlx5-next' of https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux:
  net/mlx5: Handle IPsec steering upon master unbind/bind
  net/mlx5: Configure IPsec steering for ingress RoCEv2 MPV traffic
  net/mlx5: Configure IPsec steering for egress RoCEv2 MPV traffic
  net/mlx5: Add create alias flow table function to ipsec roce
  net/mlx5: Implement alias object allow and create functions
  net/mlx5: Add alias flow table bits
  net/mlx5: Store devcom pointer inside IPsec RoCE
  net/mlx5: Register mlx5e priv to devcom in MPV mode
  RDMA/mlx5: Send events from IB driver about device affiliation state
  net/mlx5: Introduce ifc bits for migration in a chunk mode

====================

Link: https://lore.kernel.org/r/20231002083832.19746-1-leon@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 35715ac1 82f9378c
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/mlx5/vport.h>
#include <linux/mlx5/fs.h>
#include <linux/mlx5/eswitch.h>
#include <linux/mlx5/driver.h>
#include <linux/list.h>
#include <rdma/ib_smi.h>
#include <rdma/ib_umem_odp.h>
@@ -3175,6 +3176,13 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,

	lockdep_assert_held(&mlx5_ib_multiport_mutex);

	mlx5_core_mp_event_replay(ibdev->mdev,
				  MLX5_DRIVER_EVENT_AFFILIATION_REMOVED,
				  NULL);
	mlx5_core_mp_event_replay(mpi->mdev,
				  MLX5_DRIVER_EVENT_AFFILIATION_REMOVED,
				  NULL);

	mlx5_ib_cleanup_cong_debugfs(ibdev, port_num);

	spin_lock(&port->mp.mpi_lock);
@@ -3226,6 +3234,7 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,
				    struct mlx5_ib_multiport_info *mpi)
{
	u32 port_num = mlx5_core_native_port_num(mpi->mdev) - 1;
	u64 key;
	int err;

	lockdep_assert_held(&mlx5_ib_multiport_mutex);
@@ -3254,6 +3263,14 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,

	mlx5_ib_init_cong_debugfs(ibdev, port_num);

	key = ibdev->ib_dev.index;
	mlx5_core_mp_event_replay(mpi->mdev,
				  MLX5_DRIVER_EVENT_AFFILIATION_DONE,
				  &key);
	mlx5_core_mp_event_replay(ibdev->mdev,
				  MLX5_DRIVER_EVENT_AFFILIATION_DONE,
				  &key);

	return true;

unbind:
+70 −0
Original line number Diff line number Diff line
@@ -525,6 +525,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
	case MLX5_CMD_OP_SAVE_VHCA_STATE:
	case MLX5_CMD_OP_LOAD_VHCA_STATE:
	case MLX5_CMD_OP_SYNC_CRYPTO:
	case MLX5_CMD_OP_ALLOW_OTHER_VHCA_ACCESS:
		*status = MLX5_DRIVER_STATUS_ABORTED;
		*synd = MLX5_DRIVER_SYND;
		return -ENOLINK;
@@ -728,6 +729,7 @@ const char *mlx5_command_str(int command)
	MLX5_COMMAND_STR_CASE(SAVE_VHCA_STATE);
	MLX5_COMMAND_STR_CASE(LOAD_VHCA_STATE);
	MLX5_COMMAND_STR_CASE(SYNC_CRYPTO);
	MLX5_COMMAND_STR_CASE(ALLOW_OTHER_VHCA_ACCESS);
	default: return "unknown command opcode";
	}
}
@@ -2090,6 +2092,74 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
}
EXPORT_SYMBOL(mlx5_cmd_exec_cb);

int mlx5_cmd_allow_other_vhca_access(struct mlx5_core_dev *dev,
				     struct mlx5_cmd_allow_other_vhca_access_attr *attr)
{
	u32 out[MLX5_ST_SZ_DW(allow_other_vhca_access_out)] = {};
	u32 in[MLX5_ST_SZ_DW(allow_other_vhca_access_in)] = {};
	void *key;

	MLX5_SET(allow_other_vhca_access_in,
		 in, opcode, MLX5_CMD_OP_ALLOW_OTHER_VHCA_ACCESS);
	MLX5_SET(allow_other_vhca_access_in,
		 in, object_type_to_be_accessed, attr->obj_type);
	MLX5_SET(allow_other_vhca_access_in,
		 in, object_id_to_be_accessed, attr->obj_id);

	key = MLX5_ADDR_OF(allow_other_vhca_access_in, in, access_key);
	memcpy(key, attr->access_key, sizeof(attr->access_key));

	return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
}

int mlx5_cmd_alias_obj_create(struct mlx5_core_dev *dev,
			      struct mlx5_cmd_alias_obj_create_attr *alias_attr,
			      u32 *obj_id)
{
	u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
	u32 in[MLX5_ST_SZ_DW(create_alias_obj_in)] = {};
	void *param;
	void *attr;
	void *key;
	int ret;

	attr = MLX5_ADDR_OF(create_alias_obj_in, in, hdr);
	MLX5_SET(general_obj_in_cmd_hdr,
		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
	MLX5_SET(general_obj_in_cmd_hdr,
		 attr, obj_type, alias_attr->obj_type);
	param = MLX5_ADDR_OF(general_obj_in_cmd_hdr, in, op_param);
	MLX5_SET(general_obj_create_param, param, alias_object, 1);

	attr = MLX5_ADDR_OF(create_alias_obj_in, in, alias_ctx);
	MLX5_SET(alias_context, attr, vhca_id_to_be_accessed, alias_attr->vhca_id);
	MLX5_SET(alias_context, attr, object_id_to_be_accessed, alias_attr->obj_id);

	key = MLX5_ADDR_OF(alias_context, attr, access_key);
	memcpy(key, alias_attr->access_key, sizeof(alias_attr->access_key));

	ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
	if (ret)
		return ret;

	*obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);

	return 0;
}

int mlx5_cmd_alias_obj_destroy(struct mlx5_core_dev *dev, u32 obj_id,
			       u16 obj_type)
{
	u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
	u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};

	MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
	MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, obj_type);
	MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, obj_id);

	return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
}

static void destroy_msg_cache(struct mlx5_core_dev *dev)
{
	struct cmd_msg_cache *ch;
+8 −0
Original line number Diff line number Diff line
@@ -168,6 +168,13 @@ struct page_pool;
#define mlx5e_state_dereference(priv, p) \
	rcu_dereference_protected((p), lockdep_is_held(&(priv)->state_lock))

enum mlx5e_devcom_events {
	MPV_DEVCOM_MASTER_UP,
	MPV_DEVCOM_MASTER_DOWN,
	MPV_DEVCOM_IPSEC_MASTER_UP,
	MPV_DEVCOM_IPSEC_MASTER_DOWN,
};

static inline u8 mlx5e_get_num_lag_ports(struct mlx5_core_dev *mdev)
{
	if (mlx5_lag_is_lacp_owner(mdev))
@@ -936,6 +943,7 @@ struct mlx5e_priv {
	struct mlx5e_htb          *htb;
	struct mlx5e_mqprio_rl    *mqprio_rl;
	struct dentry             *dfs_root;
	struct mlx5_devcom_comp_dev *devcom;
};

struct mlx5e_dev {
+2 −1
Original line number Diff line number Diff line
@@ -850,6 +850,7 @@ void mlx5e_ipsec_init(struct mlx5e_priv *priv)

	xa_init_flags(&ipsec->sadb, XA_FLAGS_ALLOC);
	ipsec->mdev = priv->mdev;
	init_completion(&ipsec->comp);
	ipsec->wq = alloc_workqueue("mlx5e_ipsec: %s", WQ_UNBOUND, 0,
				    priv->netdev->name);
	if (!ipsec->wq)
@@ -870,7 +871,7 @@ void mlx5e_ipsec_init(struct mlx5e_priv *priv)
	}

	ipsec->is_uplink_rep = mlx5e_is_uplink_rep(priv);
	ret = mlx5e_accel_ipsec_fs_init(ipsec);
	ret = mlx5e_accel_ipsec_fs_init(ipsec, &priv->devcom);
	if (ret)
		goto err_fs_init;

+24 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <net/xfrm.h>
#include <linux/idr.h>
#include "lib/aso.h"
#include "lib/devcom.h"

#define MLX5E_IPSEC_SADB_RX_BITS 10
#define MLX5E_IPSEC_ESN_SCOPE_MID 0x80000000L
@@ -221,12 +222,20 @@ struct mlx5e_ipsec_tx_create_attr {
	enum mlx5_flow_namespace_type chains_ns;
};

struct mlx5e_ipsec_mpv_work {
	int event;
	struct work_struct work;
	struct mlx5e_priv *slave_priv;
	struct mlx5e_priv *master_priv;
};

struct mlx5e_ipsec {
	struct mlx5_core_dev *mdev;
	struct xarray sadb;
	struct mlx5e_ipsec_sw_stats sw_stats;
	struct mlx5e_ipsec_hw_stats hw_stats;
	struct workqueue_struct *wq;
	struct completion comp;
	struct mlx5e_flow_steering *fs;
	struct mlx5e_ipsec_rx *rx_ipv4;
	struct mlx5e_ipsec_rx *rx_ipv6;
@@ -238,6 +247,7 @@ struct mlx5e_ipsec {
	struct notifier_block netevent_nb;
	struct mlx5_ipsec_fs *roce;
	u8 is_uplink_rep: 1;
	struct mlx5e_ipsec_mpv_work mpv_work;
};

struct mlx5e_ipsec_esn_state {
@@ -302,7 +312,7 @@ void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv);
void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv);

void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec);
int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec);
int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec, struct mlx5_devcom_comp_dev **devcom);
int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry);
void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry);
int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
@@ -328,6 +338,10 @@ void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv,

void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
					struct mlx5_accel_esp_xfrm_attrs *attrs);
void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv,
				  struct mlx5e_priv *master_priv);
void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event);

static inline struct mlx5_core_dev *
mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry)
{
@@ -363,6 +377,15 @@ static inline u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
{
	return 0;
}

static inline void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv,
						struct mlx5e_priv *master_priv)
{
}

static inline void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event)
{
}
#endif

#endif	/* __MLX5E_IPSEC_H__ */
Loading