crypto: make crypto-dispatch node working in adaptive mode
[vpp.git] / src / plugins / crypto_sw_scheduler / main.c
index 47fa37d..1cc7a08 100644 (file)
@@ -25,14 +25,14 @@ crypto_sw_scheduler_set_worker_crypto (u32 worker_idx, u8 enabled)
   crypto_sw_scheduler_main_t *cm = &crypto_sw_scheduler_main;
   vlib_thread_main_t *tm = vlib_get_thread_main ();
   crypto_sw_scheduler_per_thread_data_t *ptd = 0;
-  u32 count = 0, i = vlib_num_workers () > 0;
+  u32 count = 0, i;
 
   if (worker_idx >= vlib_num_workers ())
     {
       return VNET_API_ERROR_INVALID_VALUE;
     }
 
-  for (; i < tm->n_vlib_mains; i++)
+  for (i = 0; i < tm->n_vlib_mains; i++)
     {
       ptd = cm->per_thread_data + i;
       count += ptd->self_crypto_enabled;
@@ -244,7 +244,7 @@ crypto_sw_scheduler_convert_link_crypto (vlib_main_t * vm,
   integ_op->digest = fe->digest;
   integ_op->digest_len = digest_len;
   integ_op->key_index = key->index_integ;
-  integ_op->flags = fe->flags & ~VNET_CRYPTO_OP_FLAG_INIT_IV;
+  integ_op->flags = fe->flags;
   crypto_op->user_data = integ_op->user_data = index;
 }
 
@@ -260,17 +260,22 @@ process_ops (vlib_main_t * vm, vnet_crypto_async_frame_t * f,
 
   n_fail = n_ops - vnet_crypto_process_ops (vm, op, n_ops);
 
-  while (n_fail)
+  /*
+   * If we had a failure in the ops then we need to walk all the ops
+   * and set the status in the corresponding frame. This status is
+   * not set in the case with no failures, as in that case the overall
+   * frame status is success.
+   */
+  if (n_fail)
     {
-      ASSERT (op - ops < n_ops);
-
-      if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
+      for (int i = 0; i < n_ops; i++)
        {
+         ASSERT (op - ops < n_ops);
+
          f->elts[op->user_data].status = op->status;
-         *state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
-         n_fail--;
+         op++;
        }
-      op++;
+      *state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
     }
 }
 
@@ -287,17 +292,22 @@ process_chained_ops (vlib_main_t * vm, vnet_crypto_async_frame_t * f,
 
   n_fail = n_ops - vnet_crypto_process_chained_ops (vm, op, chunks, n_ops);
 
-  while (n_fail)
+  /*
+   * If we had a failure in the ops then we need to walk all the ops
+   * and set the status in the corresponding frame. This status is
+   * not set in the case with no failures, as in that case the overall
+   * frame status is success.
+   */
+  if (n_fail)
     {
-      ASSERT (op - ops < n_ops);
-
-      if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED)
+      for (int i = 0; i < n_ops; i++)
        {
+         ASSERT (op - ops < n_ops);
+
          f->elts[op->user_data].status = op->status;
-         *state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
-         n_fail--;
+         op++;
        }
-      op++;
+      *state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
     }
 }
 
@@ -471,6 +481,15 @@ crypto_sw_scheduler_process_aead (vlib_main_t *vm,
              tail = current_queue->tail;
              head = current_queue->head;
 
+             /* Skip this queue unless tail < head or head has overflowed
+              * and tail has not. At the point where tail overflows (== 0),
+              * the largest possible value of head is (queue size - 1).
+              * Prior to that, the largest possible value of head is
+              * (queue size - 2).
+              */
+             if ((tail > head) && (head >= CRYPTO_SW_SCHEDULER_QUEUE_MASK))
+               goto skip_queue;
+
              for (j = tail; j != head; j++)
                {
 
@@ -488,6 +507,7 @@ crypto_sw_scheduler_process_aead (vlib_main_t *vm,
                    }
                }
 
+           skip_queue:
              if (found || i == ptd->last_serve_lcore_id)
                {
                  CLIB_MEMORY_STORE_BARRIER ();