From: Zhiqi Song songzhiqi1@huawei.com
Change the name of async_poll_task_free() to async_module_uninit(). This name will better indicates that its function is to release resources of the async_module_init().
Add check for hardware support before calling async_module_uninit() in engine destroy process. As async_module_init() will be called only when supported by hardware, async_module_uninit() should also add this kind of check, otherwise it will release incorrect resources.
And do not call async_module_uninit() at OPENSSL_atexit(). Because in dynamic unload scenario, the function entry of async_module_uninit() will not valid, calling it as part of OPENSSL_cleanup will generate segmentation fault.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_async.c | 85 +++++++++++++++++++++++------------------- src/uadk_async.h | 1 + src/uadk_engine_init.c | 3 +- src/uadk_prov_init.c | 2 +- 4 files changed, 51 insertions(+), 40 deletions(-)
diff --git a/src/uadk_async.c b/src/uadk_async.c index 6fe78e8..b88e9ea 100644 --- a/src/uadk_async.c +++ b/src/uadk_async.c @@ -109,34 +109,6 @@ int async_clear_async_event_notification(void) return UADK_E_SUCCESS; }
-void async_poll_task_free(void) -{ - struct async_poll_task *task; - int error; - - /* Disable async poll state first */ - uadk_e_set_async_poll_state(DISABLE_ASYNC_POLLING); - - error = pthread_mutex_lock(&poll_queue.async_task_mutex); - if (error) - return; - - task = poll_queue.head; - if (task) - OPENSSL_free(task); - - poll_queue.head = NULL; - - sem_post(&poll_queue.full_sem); - pthread_join(poll_queue.thread_id, NULL); - - pthread_mutex_unlock(&poll_queue.async_task_mutex); - pthread_attr_destroy(&poll_queue.thread_attr); - sem_destroy(&poll_queue.empty_sem); - sem_destroy(&poll_queue.full_sem); - pthread_mutex_destroy(&poll_queue.async_task_mutex); -} - static int async_get_poll_task(int *id) { int idx = poll_queue.rid; @@ -335,10 +307,9 @@ static void *async_poll_process_func(void *args) } }
- if (!uadk_e_get_async_poll_state()) { - /* exit by main thread */ + /* exit by main thread */ + if (!uadk_e_get_async_poll_state()) break; - }
task = async_get_queue_task(); if (!task) { @@ -372,26 +343,64 @@ int async_module_init(void) if (pthread_mutex_init(&(poll_queue.async_task_mutex), NULL) < 0) return UADK_E_FAIL;
- poll_queue.head = OPENSSL_malloc(ASYNC_QUEUE_TASK_NUM * sizeof(struct async_poll_task)); + poll_queue.head = OPENSSL_zalloc(ASYNC_QUEUE_TASK_NUM * sizeof(struct async_poll_task)); if (!poll_queue.head) - return UADK_E_FAIL; + goto destroy_mutex;
if (sem_init(&poll_queue.empty_sem, 0, ASYNC_QUEUE_TASK_NUM) != 0) - goto err; + goto free_head;
if (sem_init(&poll_queue.full_sem, 0, 0) != 0) - goto err; + goto destroy_empty_sem;
uadk_e_set_async_poll_state(ENABLE_ASYNC_POLLING);
pthread_attr_init(&poll_queue.thread_attr); if (pthread_create(&thread_id, &poll_queue.thread_attr, async_poll_process_func, NULL)) - goto err; + goto destroy_full_sem;
poll_queue.thread_id = thread_id; + return UADK_E_SUCCESS;
-err: - async_poll_task_free(); +destroy_full_sem: + uadk_e_set_async_poll_state(DISABLE_ASYNC_POLLING); + sem_destroy(&poll_queue.full_sem); + pthread_attr_destroy(&poll_queue.thread_attr); +destroy_empty_sem: + sem_destroy(&poll_queue.empty_sem); +free_head: + OPENSSL_free(poll_queue.head); +destroy_mutex: + pthread_mutex_destroy(&poll_queue.async_task_mutex); + return UADK_E_FAIL; } + +void async_module_uninit(void) +{ + int error; + struct async_poll_task *task; + + /* Disable async poll state first */ + uadk_e_set_async_poll_state(DISABLE_ASYNC_POLLING); + + error = pthread_mutex_lock(&poll_queue.async_task_mutex); + if (error) + return; + + sem_post(&poll_queue.full_sem); + pthread_join(poll_queue.thread_id, NULL); + + task = poll_queue.head; + if (task) + OPENSSL_free(task); + + poll_queue.head = NULL; + + pthread_mutex_unlock(&poll_queue.async_task_mutex); + pthread_attr_destroy(&poll_queue.thread_attr); + sem_destroy(&poll_queue.empty_sem); + sem_destroy(&poll_queue.full_sem); + pthread_mutex_destroy(&poll_queue.async_task_mutex); +} diff --git a/src/uadk_async.h b/src/uadk_async.h index 5afc3c6..dcb94d3 100644 --- a/src/uadk_async.h +++ b/src/uadk_async.h @@ -80,6 +80,7 @@ int async_clear_async_event_notification(void); int async_pause_job(void *ctx, struct async_op *op, enum task_type type); void async_register_poll_fn(int type, async_recv_t func); int async_module_init(void); +void async_module_uninit(void); int async_wake_job(ASYNC_JOB *job); void async_free_poll_task(int id, bool is_cb); int async_get_free_task(int *id); diff --git a/src/uadk_engine_init.c b/src/uadk_engine_init.c index c9cdd10..bba382f 100644 --- a/src/uadk_engine_init.c +++ b/src/uadk_engine_init.c @@ -232,7 +232,8 @@ static int uadk_destroy(ENGINE *e) if (uadk_dh) uadk_e_destroy_dh();
- async_poll_task_free(); + if (uadk_cipher || uadk_digest || uadk_rsa || uadk_dh || uadk_ecc) + async_module_uninit();
pthread_mutex_lock(&uadk_engine_mutex); uadk_inited = 0; diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index 010c87b..ab0705f 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -205,7 +205,7 @@ static void uadk_teardown(void *provctx) uadk_prov_dh_uninit(); OPENSSL_free(ctx); OSSL_PROVIDER_unload(prov); - async_poll_task_free(); + async_module_uninit(); }
static const OSSL_DISPATCH uadk_dispatch_table[] = {