Skip to content

Commit 8efd7b1

Browse files
rleonkuba-moo
authored andcommitted
net/mlx5: Provide an interface to block change of IPsec capabilities
mlx5 HW can't perform IPsec offload operation simultaneously both on PF and VFs at the same time. While the previous patches added devlink knobs to change IPsec capabilities dynamically, there is a need to add a logic to block such IPsec capabilities for the cases when IPsec is already configured. Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> Link: https://lore.kernel.org/r/20230825062836.103744-7-saeed@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 17c8da5 commit 8efd7b1

4 files changed

Lines changed: 61 additions & 1 deletion

File tree

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <net/netevent.h>
3939

4040
#include "en.h"
41+
#include "eswitch.h"
4142
#include "ipsec.h"
4243
#include "ipsec_rxtx.h"
4344
#include "en_rep.h"
@@ -670,6 +671,11 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
670671
if (err)
671672
goto err_xfrm;
672673

674+
if (!mlx5_eswitch_block_ipsec(priv->mdev)) {
675+
err = -EBUSY;
676+
goto err_xfrm;
677+
}
678+
673679
/* check esn */
674680
if (x->props.flags & XFRM_STATE_ESN)
675681
mlx5e_ipsec_update_esn_state(sa_entry);
@@ -678,7 +684,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
678684

679685
err = mlx5_ipsec_create_work(sa_entry);
680686
if (err)
681-
goto err_xfrm;
687+
goto unblock_ipsec;
682688

683689
err = mlx5e_ipsec_create_dwork(sa_entry);
684690
if (err)
@@ -735,6 +741,8 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
735741
if (sa_entry->work)
736742
kfree(sa_entry->work->data);
737743
kfree(sa_entry->work);
744+
unblock_ipsec:
745+
mlx5_eswitch_unblock_ipsec(priv->mdev);
738746
err_xfrm:
739747
kfree(sa_entry);
740748
NL_SET_ERR_MSG_WEAK_MOD(extack, "Device failed to offload this state");
@@ -764,6 +772,7 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
764772
static void mlx5e_xfrm_free_state(struct xfrm_state *x)
765773
{
766774
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
775+
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
767776

768777
if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ)
769778
goto sa_entry_free;
@@ -780,6 +789,7 @@ static void mlx5e_xfrm_free_state(struct xfrm_state *x)
780789
if (sa_entry->work)
781790
kfree(sa_entry->work->data);
782791
kfree(sa_entry->work);
792+
mlx5_eswitch_unblock_ipsec(ipsec->mdev);
783793
sa_entry_free:
784794
kfree(sa_entry);
785795
}
@@ -1055,6 +1065,11 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
10551065
pol_entry->x = x;
10561066
pol_entry->ipsec = priv->ipsec;
10571067

1068+
if (!mlx5_eswitch_block_ipsec(priv->mdev)) {
1069+
err = -EBUSY;
1070+
goto ipsec_busy;
1071+
}
1072+
10581073
mlx5e_ipsec_build_accel_pol_attrs(pol_entry, &pol_entry->attrs);
10591074
err = mlx5e_accel_ipsec_fs_add_pol(pol_entry);
10601075
if (err)
@@ -1064,6 +1079,8 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
10641079
return 0;
10651080

10661081
err_fs:
1082+
mlx5_eswitch_unblock_ipsec(priv->mdev);
1083+
ipsec_busy:
10671084
kfree(pol_entry);
10681085
NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this policy");
10691086
return err;
@@ -1074,6 +1091,7 @@ static void mlx5e_xfrm_del_policy(struct xfrm_policy *x)
10741091
struct mlx5e_ipsec_pol_entry *pol_entry = to_ipsec_pol_entry(x);
10751092

10761093
mlx5e_accel_ipsec_fs_del_pol(pol_entry);
1094+
mlx5_eswitch_unblock_ipsec(pol_entry->ipsec->mdev);
10771095
}
10781096

10791097
static void mlx5e_xfrm_free_policy(struct xfrm_policy *x)

drivers/net/ethernet/mellanox/mlx5/core/eswitch.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "devlink.h"
4949
#include "ecpf.h"
5050
#include "en/mod_hdr.h"
51+
#include "en_accel/ipsec.h"
5152

5253
enum {
5354
MLX5_ACTION_NONE = 0,
@@ -2336,3 +2337,34 @@ struct mlx5_core_dev *mlx5_eswitch_get_core_dev(struct mlx5_eswitch *esw)
23362337
return mlx5_esw_allowed(esw) ? esw->dev : NULL;
23372338
}
23382339
EXPORT_SYMBOL(mlx5_eswitch_get_core_dev);
2340+
2341+
bool mlx5_eswitch_block_ipsec(struct mlx5_core_dev *dev)
2342+
{
2343+
struct mlx5_eswitch *esw = dev->priv.eswitch;
2344+
2345+
if (!mlx5_esw_allowed(esw))
2346+
return true;
2347+
2348+
mutex_lock(&esw->state_lock);
2349+
if (esw->enabled_ipsec_vf_count) {
2350+
mutex_unlock(&esw->state_lock);
2351+
return false;
2352+
}
2353+
2354+
dev->num_ipsec_offloads++;
2355+
mutex_unlock(&esw->state_lock);
2356+
return true;
2357+
}
2358+
2359+
void mlx5_eswitch_unblock_ipsec(struct mlx5_core_dev *dev)
2360+
{
2361+
struct mlx5_eswitch *esw = dev->priv.eswitch;
2362+
2363+
if (!mlx5_esw_allowed(esw))
2364+
/* Failure means no eswitch => core dev is not a PF */
2365+
return;
2366+
2367+
mutex_lock(&esw->state_lock);
2368+
dev->num_ipsec_offloads--;
2369+
mutex_unlock(&esw->state_lock);
2370+
}

drivers/net/ethernet/mellanox/mlx5/core/eswitch.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ struct mlx5_eswitch {
380380
struct blocking_notifier_head n_head;
381381
struct xarray paired;
382382
struct mlx5_devcom_comp_dev *devcom;
383+
u16 enabled_ipsec_vf_count;
383384
};
384385

385386
void esw_offloads_disable(struct mlx5_eswitch *esw);
@@ -855,6 +856,8 @@ mlx5_eswitch_get_slow_fdb(struct mlx5_eswitch *esw)
855856

856857
int mlx5_eswitch_restore_ipsec_rule(struct mlx5_eswitch *esw, struct mlx5_flow_handle *rule,
857858
struct mlx5_esw_flow_attr *esw_attr, int attr_idx);
859+
bool mlx5_eswitch_block_ipsec(struct mlx5_core_dev *dev);
860+
void mlx5_eswitch_unblock_ipsec(struct mlx5_core_dev *dev);
858861
#else /* CONFIG_MLX5_ESWITCH */
859862
/* eswitch API stubs */
860863
static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
@@ -916,6 +919,12 @@ static inline void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev)
916919

917920
static inline int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev) { return 0; }
918921
static inline void mlx5_eswitch_unblock_mode(struct mlx5_core_dev *dev) {}
922+
static inline bool mlx5_eswitch_block_ipsec(struct mlx5_core_dev *dev)
923+
{
924+
return false;
925+
}
926+
927+
static inline void mlx5_eswitch_unblock_ipsec(struct mlx5_core_dev *dev) {}
919928
#endif /* CONFIG_MLX5_ESWITCH */
920929

921930
#endif /* __MLX5_ESWITCH_H__ */

include/linux/mlx5/driver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@ struct mlx5_core_dev {
813813
/* MACsec notifier chain to sync MACsec core and IB database */
814814
struct blocking_notifier_head macsec_nh;
815815
#endif
816+
u64 num_ipsec_offloads;
816817
};
817818

818819
struct mlx5_db {

0 commit comments

Comments
 (0)