In preparation to update crypto code for OpenSSL 1.1.0 move locks out of
global data.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>
---
 platform/linux-generic/odp_crypto.c | 67 ++++++++++++++++++++++++++-----------
 1 file changed, 47 insertions(+), 20 deletions(-)

diff --git a/platform/linux-generic/odp_crypto.c 
b/platform/linux-generic/odp_crypto.c
index b53b0fc1..d83b8e09 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -64,7 +64,6 @@ typedef struct odp_crypto_global_s odp_crypto_global_t;
 
 struct odp_crypto_global_s {
        odp_spinlock_t                lock;
-       odp_ticketlock_t **openssl_lock;
        odp_crypto_generic_session_t *free;
        odp_crypto_generic_session_t  sessions[0];
 };
@@ -954,16 +953,53 @@ static unsigned long openssl_thread_id(void)
        return (unsigned long)odp_thread_id();
 }
 
+odp_ticketlock_t *openssl_locks;
+
 static void openssl_lock(int mode, int n,
                         const char *file ODP_UNUSED,
                         int line ODP_UNUSED)
 {
        if (mode & CRYPTO_LOCK)
-               odp_ticketlock_lock((odp_ticketlock_t *)
-                                   &global->openssl_lock[n]);
+               odp_ticketlock_lock(&openssl_locks[n]);
        else
-               odp_ticketlock_unlock((odp_ticketlock_t *)
-                                     &global->openssl_lock[n]);
+               odp_ticketlock_unlock(&openssl_locks[n]);
+}
+
+static void openssl_init_locks(void)
+{
+       int nlocks;
+       size_t mem_size;
+       odp_shm_t shm;
+       int idx;
+
+       nlocks = CRYPTO_num_locks();
+       if (nlocks <= 0)
+               return;
+
+       mem_size = nlocks * sizeof(odp_ticketlock_t);
+
+       /* Allocate our globally shared memory */
+       shm = odp_shm_reserve("crypto_openssl_locks", mem_size,
+                             ODP_CACHE_LINE_SIZE, 0);
+
+       openssl_locks = odp_shm_addr(shm);
+
+       /* Clear it out */
+       memset(openssl_locks, 0, mem_size);
+
+       for (idx = 0; idx < nlocks; idx++)
+               odp_ticketlock_init(&openssl_locks[idx]);
+
+       CRYPTO_set_id_callback(openssl_thread_id);
+       CRYPTO_set_locking_callback(openssl_lock);
+}
+
+static int openssl_term_locks(void)
+{
+       CRYPTO_set_locking_callback(NULL);
+       CRYPTO_set_id_callback(NULL);
+
+       return odp_shm_free(odp_shm_lookup("crypto_openssl_locks"));
 }
 
 int
@@ -972,12 +1008,10 @@ odp_crypto_init_global(void)
        size_t mem_size;
        odp_shm_t shm;
        int idx;
-       int nlocks = CRYPTO_num_locks();
 
        /* Calculate the memory size we need */
        mem_size  = sizeof(*global);
        mem_size += (MAX_SESSIONS * sizeof(odp_crypto_generic_session_t));
-       mem_size += nlocks * sizeof(odp_ticketlock_t);
 
        /* Allocate our globally shared memory */
        shm = odp_shm_reserve("crypto_pool", mem_size,
@@ -995,17 +1029,7 @@ odp_crypto_init_global(void)
        }
        odp_spinlock_init(&global->lock);
 
-       if (nlocks > 0) {
-               global->openssl_lock =
-                       (odp_ticketlock_t **)&global->sessions[MAX_SESSIONS];
-
-               for (idx = 0; idx < nlocks; idx++)
-                       odp_ticketlock_init((odp_ticketlock_t *)
-                                           &global->openssl_lock[idx]);
-
-               CRYPTO_set_id_callback(openssl_thread_id);
-               CRYPTO_set_locking_callback(openssl_lock);
-       }
+       openssl_init_locks();
 
        return 0;
 }
@@ -1024,8 +1048,11 @@ int odp_crypto_term_global(void)
                rc = -1;
        }
 
-       CRYPTO_set_locking_callback(NULL);
-       CRYPTO_set_id_callback(NULL);
+       ret = openssl_term_locks();
+       if (ret < 0) {
+               ODP_ERR("shm free failed for crypto_openssl_locks\n");
+               rc = -1;
+       }
 
        ret = odp_shm_free(odp_shm_lookup("crypto_pool"));
        if (ret < 0) {
-- 
2.11.0

Reply via email to