Commit d589e785 authored by Vlad Buslov's avatar Vlad Buslov Committed by Saeed Mahameed

net/mlx5e: Allow concurrent creation of encap entries

Encap entries creation is fully synchronized by encap_tbl_lock. In order to
allow concurrent allocation of hardware resources used to offload
encapsulation, extend mlx5e_encap_entry with 'res_ready' completion. Move
call to mlx5e_tc_tun_create_header_ipv{4|6}() out of encap_tbl_lock
critical section. Modify code that attaches new flows to existing encap to
wait for 'res_ready' completion before using the entry. Insert encap entry
to table before provisioning it to hardware and modify all users of the
encap table to verify that encap was fully initialized by checking
completion result for non-zero value (and to wait for 'res_ready'
completion, if necessary).
Signed-off-by: default avatarVlad Buslov <vladbu@mellanox.com>
Reviewed-by: default avatarRoi Dayan <roid@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 61086f39
...@@ -165,6 +165,8 @@ struct mlx5e_encap_entry { ...@@ -165,6 +165,8 @@ struct mlx5e_encap_entry {
char *encap_header; char *encap_header;
int encap_size; int encap_size;
refcount_t refcnt; refcount_t refcnt;
struct completion res_ready;
int compl_result;
}; };
struct mlx5e_rep_sq { struct mlx5e_rep_sq {
......
...@@ -2904,8 +2904,18 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -2904,8 +2904,18 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
e = mlx5e_encap_get(priv, &key, hash_key); e = mlx5e_encap_get(priv, &key, hash_key);
/* must verify if encap is valid or not */ /* must verify if encap is valid or not */
if (e) if (e) {
mutex_unlock(&esw->offloads.encap_tbl_lock);
wait_for_completion(&e->res_ready);
/* Protect against concurrent neigh update. */
mutex_lock(&esw->offloads.encap_tbl_lock);
if (e->compl_result) {
err = -EREMOTEIO;
goto out_err;
}
goto attach_flow; goto attach_flow;
}
e = kzalloc(sizeof(*e), GFP_KERNEL); e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e) { if (!e) {
...@@ -2914,22 +2924,32 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -2914,22 +2924,32 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
} }
refcount_set(&e->refcnt, 1); refcount_set(&e->refcnt, 1);
init_completion(&e->res_ready);
e->tun_info = tun_info; e->tun_info = tun_info;
err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack); err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack);
if (err) if (err) {
kfree(e);
e = NULL;
goto out_err; goto out_err;
}
INIT_LIST_HEAD(&e->flows); INIT_LIST_HEAD(&e->flows);
hash_add_rcu(esw->offloads.encap_tbl, &e->encap_hlist, hash_key);
mutex_unlock(&esw->offloads.encap_tbl_lock);
if (family == AF_INET) if (family == AF_INET)
err = mlx5e_tc_tun_create_header_ipv4(priv, mirred_dev, e); err = mlx5e_tc_tun_create_header_ipv4(priv, mirred_dev, e);
else if (family == AF_INET6) else if (family == AF_INET6)
err = mlx5e_tc_tun_create_header_ipv6(priv, mirred_dev, e); err = mlx5e_tc_tun_create_header_ipv6(priv, mirred_dev, e);
if (err) /* Protect against concurrent neigh update. */
mutex_lock(&esw->offloads.encap_tbl_lock);
complete_all(&e->res_ready);
if (err) {
e->compl_result = err;
goto out_err; goto out_err;
}
hash_add_rcu(esw->offloads.encap_tbl, &e->encap_hlist, hash_key);
attach_flow: attach_flow:
flow->encaps[out_index].e = e; flow->encaps[out_index].e = e;
...@@ -2949,7 +2969,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -2949,7 +2969,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
out_err: out_err:
mutex_unlock(&esw->offloads.encap_tbl_lock); mutex_unlock(&esw->offloads.encap_tbl_lock);
kfree(e); if (e)
mlx5e_encap_put(priv, e);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment