From: PiotrX Kleski Date: Tue, 24 Nov 2020 08:26:26 +0000 (+0000) Subject: crypto: fixed async frame enqueue race condition X-Git-Tag: v21.06-rc0~59 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F47%2F30247%2F2;p=vpp.git crypto: fixed async frame enqueue race condition Type: fix To avoid race condition happening in async crypto engines, async frame state and thread index set should happen before enqueue. In addition as the enqueue handler already returns the enqueue status, when an enqueue is failed, the async crypto engine shall not worry about setting the async frame state but let the submit_open_frame function to do just that. Signed-off-by: PiotrX Kleski Reviewed-by: Fan Zhang Change-Id: Ic1b0c94478b3cfd5fab98657218bbd70c46a220a --- diff --git a/src/plugins/crypto_sw_scheduler/main.c b/src/plugins/crypto_sw_scheduler/main.c index 7de84ff1200..2e4ad428ea0 100644 --- a/src/plugins/crypto_sw_scheduler/main.c +++ b/src/plugins/crypto_sw_scheduler/main.c @@ -88,10 +88,8 @@ crypto_sw_scheduler_frame_enqueue (vlib_main_t * vm, u32 n_elts = frame->n_elts, i; for (i = 0; i < n_elts; i++) frame->elts[i].status = VNET_CRYPTO_OP_STATUS_FAIL_ENGINE_ERR; - frame->state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR; return -1; } - frame->state = VNET_CRYPTO_FRAME_STATE_NOT_PROCESSED; q->jobs[head & CRYPTO_SW_SCHEDULER_QUEUE_MASK] = frame; head += 1; CLIB_MEMORY_STORE_BARRIER (); diff --git a/src/plugins/dpdk/cryptodev/cryptodev.c b/src/plugins/dpdk/cryptodev/cryptodev.c index f58b54634a7..f51a5a527dc 100644 --- a/src/plugins/dpdk/cryptodev/cryptodev.c +++ b/src/plugins/dpdk/cryptodev/cryptodev.c @@ -412,7 +412,6 @@ cryptodev_mark_frame_err_status (vnet_crypto_async_frame_t * f, for (i = 0; i < n_elts; i++) f->elts[i].status = s; - f->state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR; } static_always_inline rte_iova_t diff --git a/src/vnet/crypto/crypto.h b/src/vnet/crypto/crypto.h index 07a73f14d04..fdda571d054 100644 --- a/src/vnet/crypto/crypto.h +++ b/src/vnet/crypto/crypto.h @@ -566,13 +566,15 @@ vnet_crypto_async_submit_open_frame (vlib_main_t * vm, vnet_crypto_async_op_id_t opt = frame->op; u32 i = vlib_num_workers () > 0; - int ret = (cm->enqueue_handlers[frame->op]) (vm, frame); + frame->state = VNET_CRYPTO_FRAME_STATE_PENDING; frame->enqueue_thread_index = vm->thread_index; + + int ret = (cm->enqueue_handlers[frame->op]) (vm, frame); + clib_bitmap_set_no_check (cm->async_active_ids, opt, 1); if (PREDICT_TRUE (ret == 0)) { vnet_crypto_async_frame_t *nf = 0; - frame->state = VNET_CRYPTO_FRAME_STATE_PENDING; pool_get_aligned (ct->frame_pool, nf, CLIB_CACHE_LINE_BYTES); if (CLIB_DEBUG > 0) clib_memset (nf, 0xfe, sizeof (*nf)); @@ -581,6 +583,10 @@ vnet_crypto_async_submit_open_frame (vlib_main_t * vm, nf->n_elts = 0; ct->frames[opt] = nf; } + else + { + frame->state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR; + } if (cm->dispatch_mode == VNET_CRYPTO_ASYNC_DISPATCH_INTERRUPT) {