On 9 January 2017 at 16:24, Bill Fischofer <bill.fischo...@linaro.org> wrote:
> Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2798 by adding
> OpenSSL callbacks for locking that use ticketlocks to provide
> thread-safety for OpenSSL calls made by ODP components such as random
> number generation.
>
> Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org>

Reviewed-by: Christophe Milard <christophe.mil...@linaro.org>
> ---
Note that this has not proven to be working as the error root is very
unsure and hard to reproduce. But I believe it is better to have an
unknown correction rather than a known bug :-)

> Changes for v3:
> - Move code from odp_init.c to odp_crypto.c as suggested by Petri
>   and Christophe
>
> Changes for v2:
> - OPENSSL_INIT stage should precede CRYPTO_INIT stage since crypto uses 
> OpenSSL
>
>  platform/linux-generic/odp_crypto.c | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
>
> diff --git a/platform/linux-generic/odp_crypto.c 
> b/platform/linux-generic/odp_crypto.c
> index 5808d16..4f17fd6 100644
> --- a/platform/linux-generic/odp_crypto.c
> +++ b/platform/linux-generic/odp_crypto.c
> @@ -64,6 +64,7 @@ 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];
>  };
> @@ -948,16 +949,35 @@ odp_crypto_operation(odp_crypto_op_param_t *param,
>         return 0;
>  }
>
> +static unsigned long openssl_thread_id(void)
> +{
> +       return (unsigned long)odp_thread_id();
> +}
> +
> +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]);
> +       else
> +               odp_ticketlock_unlock((odp_ticketlock_t *)
> +                                     &global->openssl_lock[n]);
> +}
> +
>  int
>  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,
> @@ -975,6 +995,18 @@ 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);
> +       }
> +
>         return 0;
>  }
>
> @@ -992,6 +1024,9 @@ int odp_crypto_term_global(void)
>                 rc = -1;
>         }
>
> +       CRYPTO_set_locking_callback(NULL);
> +       CRYPTO_set_id_callback(NULL);
> +
>         ret = odp_shm_free(odp_shm_lookup("crypto_pool"));
>         if (ret < 0) {
>                 ODP_ERR("shm free failed for crypto_pool\n");
> --
> 2.9.3
>

Reply via email to