aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRadu Nicolau <radu.nicolau@intel.com>2018-04-06 12:12:21 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2018-04-10 10:32:25 +0000
commit5aaea1186e4464c0bcbd165ead4b1782a35bb056 (patch)
tree9c178dc6dcac235a3dcb97c2028e8ee15d9370fc
parent380e3daaaffd309febfc4764731982af08aa2dce (diff)
CSIT-895 dpdk/ipsec: add locks on session data hash updates
Change-Id: I6400b77de388c01e85209e5dc5f11ccafb79a459 Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
-rw-r--r--src/plugins/dpdk/ipsec/ipsec.c72
-rw-r--r--src/plugins/dpdk/ipsec/ipsec.h1
2 files changed, 40 insertions, 33 deletions
diff --git a/src/plugins/dpdk/ipsec/ipsec.c b/src/plugins/dpdk/ipsec/ipsec.c
index 9be7b3bf6a0..3574f3eced0 100644
--- a/src/plugins/dpdk/ipsec/ipsec.c
+++ b/src/plugins/dpdk/ipsec/ipsec.c
@@ -330,12 +330,11 @@ create_sym_session (struct rte_cryptodev_sym_session **session,
struct rte_crypto_sym_xform *xfs;
struct rte_cryptodev_sym_session **s;
crypto_session_key_t key = { 0 };
+ clib_error_t *erorr = 0;
key.drv_id = res->drv_id;
key.sa_idx = sa_idx;
- data = vec_elt_at_index (dcm->data, res->numa);
-
sa = pool_elt_at_index (im->sad, sa_idx);
if ((sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128) |
@@ -362,6 +361,9 @@ create_sym_session (struct rte_cryptodev_sym_session **session,
}
}
+ data = vec_elt_at_index (dcm->data, res->numa);
+ clib_spinlock_lock_if_init (&data->lockp);
+
/*
* DPDK_VER >= 1708:
* Multiple worker/threads share the session for an SA
@@ -375,7 +377,8 @@ create_sym_session (struct rte_cryptodev_sym_session **session,
if (!session[0])
{
data->session_h_failed += 1;
- return clib_error_return (0, "failed to create session header");
+ erorr = clib_error_return (0, "failed to create session header");
+ goto done;
}
hash_set (data->session_by_sa_index, sa_idx, session[0]);
}
@@ -391,13 +394,16 @@ create_sym_session (struct rte_cryptodev_sym_session **session,
if (ret)
{
data->session_drv_failed[res->drv_id] += 1;
- return clib_error_return (0, "failed to init session for drv %u",
- res->drv_id);
+ erorr = clib_error_return (0, "failed to init session for drv %u",
+ res->drv_id);
+ goto done;
}
hash_set (data->session_by_drv_id_and_sa_index, key.val, session[0]);
- return 0;
+done:
+ clib_spinlock_unlock_if_init (&data->lockp);
+ return erorr;
}
static void __attribute__ ((unused)) clear_and_free_obj (void *obj)
@@ -509,34 +515,32 @@ add_del_sa_session (u32 sa_index, u8 is_add)
/* *INDENT-OFF* */
vec_foreach (data, dcm->data)
{
+ clib_spinlock_lock_if_init (&data->lockp);
val = hash_get (data->session_by_sa_index, sa_index);
-
- if (!val)
- continue;
-
- s = (struct rte_cryptodev_sym_session *) val[0];
-
- vec_foreach_index (drv_id, dcm->drv)
- {
- key.drv_id = drv_id;
- val = hash_get (data->session_by_drv_id_and_sa_index, key.val);
-
- if (!val)
- continue;
-
- hash_unset (data->session_by_drv_id_and_sa_index, key.val);
- }
-
- hash_unset (data->session_by_sa_index, sa_index);
-
- u64 ts = unix_time_now_nsec ();
- dpdk_crypto_session_disposal (data->session_disposal, ts);
-
- crypto_session_disposal_t sd;
- sd.ts = ts;
- sd.session = s;
-
- vec_add1 (data->session_disposal, sd);
+ s = (struct rte_cryptodev_sym_session *) val;
+ if (s)
+ {
+ vec_foreach_index (drv_id, dcm->drv)
+ {
+ key.drv_id = drv_id;
+ val = hash_get (data->session_by_drv_id_and_sa_index, key.val);
+ s = (struct rte_cryptodev_sym_session *) val;
+ if (s)
+ hash_unset (data->session_by_drv_id_and_sa_index, key.val);
+ }
+
+ hash_unset (data->session_by_sa_index, sa_index);
+
+ u64 ts = unix_time_now_nsec ();
+ dpdk_crypto_session_disposal (data->session_disposal, ts);
+
+ crypto_session_disposal_t sd;
+ sd.ts = ts;
+ sd.session = s;
+
+ vec_add1 (data->session_disposal, sd);
+ }
+ clib_spinlock_unlock_if_init (&data->lockp);
}
/* *INDENT-ON* */
@@ -925,6 +929,7 @@ crypto_create_session_drv_pool (vlib_main_t * vm, crypto_dev_t * dev)
return error;
data->session_drv[dev->drv_id] = mp;
+ clib_spinlock_init (&data->lockp);
return NULL;
}
@@ -977,6 +982,7 @@ crypto_disable (void)
rte_mempool_free (data->session_drv[i]);
vec_free (data->session_drv);
+ clib_spinlock_free (&data->lockp);
}
/* *INDENT-ON* */
diff --git a/src/plugins/dpdk/ipsec/ipsec.h b/src/plugins/dpdk/ipsec/ipsec.h
index a46f5bf5735..d1009ecdb33 100644
--- a/src/plugins/dpdk/ipsec/ipsec.h
+++ b/src/plugins/dpdk/ipsec/ipsec.h
@@ -135,6 +135,7 @@ typedef struct
u64 crypto_op_get_failed;
u64 session_h_failed;
u64 *session_drv_failed;
+ clib_spinlock_t lockp;
} crypto_data_t;
typedef struct