aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/crypto/crypto.h
diff options
context:
space:
mode:
authorPiotrX Kleski <piotrx.kleski@intel.com>2020-07-08 14:36:34 +0200
committerDamjan Marion <dmarion@me.com>2020-09-03 14:23:51 +0000
commit2284817eae67d78f3a9afffed9d830da658dd568 (patch)
tree0d108b262c42caa5b70d065dd5596f368a79a795 /src/vnet/crypto/crypto.h
parent56230097e2a642740a1a00483e54419edc7fc2ba (diff)
crypto: SW scheduler async crypto engine
Type: feature This patch adds new sw_scheduler async crypto engine. The engine transforms async frames info sync crypto ops and delegates them to active sync engines. With the patch it is possible to increase the single worker crypto throughput by offloading the crypto workload to multiple workers. By default all workers in the system will attend the crypto workload processing. However a worker's available cycles are limited. To avail more cycles to one worker to process other workload (e.g. the worker core that handles the RX/TX and IPSec stack processing), a useful cli command is added to remove itself (or add it back later) from the heavy crypto workload but only let other workers to process the crypto. The command is: - set sw_scheduler worker <idx> crypto <on|off> It also adds new interrupt mode to async crypto dispatch node. This mode signals the node when new frames are enqueued as opposed to polling mode that continuously calls dispatch node. New cli commands: - set crypto async dispatch [polling|interrupt] - show crypto async status (displays mode and nodes' states) Signed-off-by: PiotrX Kleski <piotrx.kleski@intel.com> Signed-off-by: DariuszX Kazimierski <dariuszx.kazimierski@intel.com> Reviewed-by: Fan Zhang <roy.fan.zhang@intel.com> Change-Id: I332655f347bb9e3bc9c64166e86e393e911bdb39
Diffstat (limited to 'src/vnet/crypto/crypto.h')
-rw-r--r--src/vnet/crypto/crypto.h44
1 files changed, 34 insertions, 10 deletions
diff --git a/src/vnet/crypto/crypto.h b/src/vnet/crypto/crypto.h
index 777923a8be7..a4a82d6118c 100644
--- a/src/vnet/crypto/crypto.h
+++ b/src/vnet/crypto/crypto.h
@@ -18,7 +18,7 @@
#include <vlib/vlib.h>
-#define VNET_CRYPTO_FRAME_SIZE 32
+#define VNET_CRYPTO_FRAME_SIZE 64
/* CRYPTO_ID, PRETTY_NAME, KEY_LENGTH_IN_BYTES */
#define foreach_crypto_cipher_alg \
@@ -322,15 +322,17 @@ typedef struct
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
#define VNET_CRYPTO_FRAME_STATE_NOT_PROCESSED 0
-#define VNET_CRYPTO_FRAME_STATE_WORK_IN_PROGRESS 1
-#define VNET_CRYPTO_FRAME_STATE_SUCCESS 2
-#define VNET_CRYPTO_FRAME_STATE_ELT_ERROR 3
+#define VNET_CRYPTO_FRAME_STATE_PENDING 1 /* frame waiting to be processed */
+#define VNET_CRYPTO_FRAME_STATE_WORK_IN_PROGRESS 2
+#define VNET_CRYPTO_FRAME_STATE_SUCCESS 3
+#define VNET_CRYPTO_FRAME_STATE_ELT_ERROR 4
u8 state;
vnet_crypto_async_op_id_t op:8;
u16 n_elts;
vnet_crypto_async_frame_elt_t elts[VNET_CRYPTO_FRAME_SIZE];
u32 buffer_indices[VNET_CRYPTO_FRAME_SIZE];
u16 next_node_index[VNET_CRYPTO_FRAME_SIZE];
+ u32 enqueue_thread_index;
} vnet_crypto_async_frame_t;
typedef struct
@@ -357,13 +359,16 @@ typedef void (vnet_crypto_key_handler_t) (vlib_main_t * vm,
vnet_crypto_key_index_t idx);
/** async crypto function handlers **/
-typedef int (vnet_crypto_frame_enqueue_t) (vlib_main_t * vm,
- vnet_crypto_async_frame_t * frame);
+typedef int
+ (vnet_crypto_frame_enqueue_t) (vlib_main_t * vm,
+ vnet_crypto_async_frame_t * frame);
typedef vnet_crypto_async_frame_t *
- (vnet_crypto_frame_dequeue_t) (vlib_main_t * vm);
+ (vnet_crypto_frame_dequeue_t) (vlib_main_t * vm, u32 * nb_elts_processed,
+ u32 * enqueue_thread_idx);
-u32 vnet_crypto_register_engine (vlib_main_t * vm, char *name, int prio,
- char *desc);
+u32
+vnet_crypto_register_engine (vlib_main_t * vm, char *name, int prio,
+ char *desc);
void vnet_crypto_register_ops_handler (vlib_main_t * vm, u32 engine_index,
vnet_crypto_op_id_t opt,
@@ -431,6 +436,10 @@ typedef struct
vnet_crypto_async_alg_data_t *async_algs;
u32 async_refcnt;
vnet_crypto_async_next_node_t *next_nodes;
+ u32 crypto_node_index;
+#define VNET_CRYPTO_ASYNC_DISPATCH_POLLING 0
+#define VNET_CRYPTO_ASYNC_DISPATCH_INTERRUPT 1
+ u8 dispatch_mode;
} vnet_crypto_main_t;
extern vnet_crypto_main_t crypto_main;
@@ -466,6 +475,8 @@ int vnet_crypto_is_set_async_handler (vnet_crypto_async_op_id_t opt);
void vnet_crypto_request_async_mode (int is_enable);
+void vnet_crypto_set_async_dispatch_mode (u8 mode);
+
vnet_crypto_async_alg_t vnet_crypto_link_algs (vnet_crypto_alg_t crypto_alg,
vnet_crypto_alg_t integ_alg);
@@ -551,14 +562,18 @@ vnet_crypto_async_submit_open_frame (vlib_main_t * vm,
vnet_crypto_async_frame_t * frame)
{
vnet_crypto_main_t *cm = &crypto_main;
+ vlib_thread_main_t *tm = vlib_get_thread_main ();
vnet_crypto_thread_t *ct = cm->threads + vm->thread_index;
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->enqueue_thread_index = vm->thread_index;
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_WORK_IN_PROGRESS;
+ 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));
@@ -567,6 +582,15 @@ vnet_crypto_async_submit_open_frame (vlib_main_t * vm,
nf->n_elts = 0;
ct->frames[opt] = nf;
}
+
+ if (cm->dispatch_mode == VNET_CRYPTO_ASYNC_DISPATCH_INTERRUPT)
+ {
+ for (; i < tm->n_vlib_mains; i++)
+ {
+ vlib_node_set_interrupt_pending (vlib_mains[i],
+ cm->crypto_node_index);
+ }
+ }
return ret;
}