crypto: fixed async frame enqueue race condition 47/30247/2
authorPiotrX Kleski <piotrx.kleski@intel.com>
Tue, 24 Nov 2020 08:26:26 +0000 (08:26 +0000)
committerDamjan Marion <dmarion@me.com>
Fri, 4 Dec 2020 22:52:16 +0000 (22:52 +0000)
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 <piotrx.kleski@intel.com>
Reviewed-by: Fan Zhang <roy.fan.zhang@intel.com>
Change-Id: Ic1b0c94478b3cfd5fab98657218bbd70c46a220a

src/plugins/crypto_sw_scheduler/main.c
src/plugins/dpdk/cryptodev/cryptodev.c
src/vnet/crypto/crypto.h

index 7de84ff..2e4ad42 100644 (file)
@@ -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 ();
index f58b546..f51a5a5 100644 (file)
@@ -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
index 07a73f1..fdda571 100644 (file)
@@ -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)
     {