xref: /dpdk/examples/vhost_crypto/main.c (revision a106fcce2cfed0fdee7922594e3199d28dfcce59)
1f5188211SFan Zhang /* SPDX-License-Identifier: BSD-3-Clause
2f5188211SFan Zhang  * Copyright(c) 2017-2018 Intel Corporation
3f5188211SFan Zhang  */
4f5188211SFan Zhang 
5f5188211SFan Zhang #include <stdio.h>
6f5188211SFan Zhang #include <stdlib.h>
7f5188211SFan Zhang #include <unistd.h>
8f5188211SFan Zhang #include <stdbool.h>
9f5188211SFan Zhang #include <assert.h>
10f5188211SFan Zhang #include <getopt.h>
11f5188211SFan Zhang 
12f5188211SFan Zhang #include <rte_malloc.h>
13f5188211SFan Zhang #include <rte_cycles.h>
14f5188211SFan Zhang #include <rte_vhost.h>
15f5188211SFan Zhang #include <rte_cryptodev.h>
16f5188211SFan Zhang #include <rte_vhost_crypto.h>
17f5188211SFan Zhang 
18f5188211SFan Zhang #include <cmdline_rdline.h>
19f5188211SFan Zhang #include <cmdline_parse.h>
20f5188211SFan Zhang #include <cmdline_parse_string.h>
21f5188211SFan Zhang #include <cmdline.h>
22f5188211SFan Zhang 
23f5188211SFan Zhang #define NB_VIRTIO_QUEUES		(1)
24f5188211SFan Zhang #define MAX_PKT_BURST			(64)
25f5188211SFan Zhang #define MAX_IV_LEN			(32)
26f5188211SFan Zhang #define NB_MEMPOOL_OBJS			(8192)
27f5188211SFan Zhang #define NB_CRYPTO_DESCRIPTORS		(4096)
28f5188211SFan Zhang #define NB_CACHE_OBJS			(128)
29f5188211SFan Zhang #define SESSION_MAP_ENTRIES		(1024)
30f5188211SFan Zhang #define REFRESH_TIME_SEC		(3)
31f5188211SFan Zhang 
32f5188211SFan Zhang #define MAX_NB_SOCKETS			(32)
33f5188211SFan Zhang #define DEF_SOCKET_FILE			"/tmp/vhost_crypto1.socket"
34f5188211SFan Zhang 
35f5188211SFan Zhang struct vhost_crypto_options {
36f5188211SFan Zhang 	char *socket_files[MAX_NB_SOCKETS];
37f5188211SFan Zhang 	uint32_t nb_sockets;
38f5188211SFan Zhang 	uint8_t cid;
39f5188211SFan Zhang 	uint16_t qid;
40f5188211SFan Zhang 	uint32_t zero_copy;
41f5188211SFan Zhang 	uint32_t guest_polling;
42f5188211SFan Zhang } options;
43f5188211SFan Zhang 
44f5188211SFan Zhang struct vhost_crypto_info {
45f5188211SFan Zhang 	int vids[MAX_NB_SOCKETS];
46f5188211SFan Zhang 	struct rte_mempool *sess_pool;
47f5188211SFan Zhang 	struct rte_mempool *cop_pool;
48f5188211SFan Zhang 	uint32_t lcore_id;
49f5188211SFan Zhang 	uint8_t cid;
50f5188211SFan Zhang 	uint32_t qid;
51f5188211SFan Zhang 	uint32_t nb_vids;
52f5188211SFan Zhang 	volatile uint32_t initialized[MAX_NB_SOCKETS];
53f5188211SFan Zhang 
54f5188211SFan Zhang } info;
55f5188211SFan Zhang 
56f5188211SFan Zhang #define SOCKET_FILE_KEYWORD	"socket-file"
57f5188211SFan Zhang #define CRYPTODEV_ID_KEYWORD	"cdev-id"
58f5188211SFan Zhang #define CRYPTODEV_QUEUE_KEYWORD	"cdev-queue-id"
59f5188211SFan Zhang #define ZERO_COPY_KEYWORD	"zero-copy"
60f5188211SFan Zhang #define POLLING_KEYWORD		"guest-polling"
61f5188211SFan Zhang 
62f5188211SFan Zhang uint64_t vhost_cycles[2], last_v_cycles[2];
63f5188211SFan Zhang uint64_t outpkt_amount;
64f5188211SFan Zhang 
65f5188211SFan Zhang /** support *SOCKET_FILE_PATH:CRYPTODEV_ID* format */
66f5188211SFan Zhang static int
67f5188211SFan Zhang parse_socket_arg(char *arg)
68f5188211SFan Zhang {
69f5188211SFan Zhang 	uint32_t nb_sockets = options.nb_sockets;
70f5188211SFan Zhang 	size_t len = strlen(arg);
71f5188211SFan Zhang 
72f5188211SFan Zhang 	if (nb_sockets >= MAX_NB_SOCKETS) {
73f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Too many socket files!\n");
74f5188211SFan Zhang 		return -ENOMEM;
75f5188211SFan Zhang 	}
76f5188211SFan Zhang 
77f5188211SFan Zhang 	options.socket_files[nb_sockets] = rte_malloc(NULL, len, 0);
78f5188211SFan Zhang 	if (!options.socket_files[nb_sockets]) {
79f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Insufficient memory\n");
80f5188211SFan Zhang 		return -ENOMEM;
81f5188211SFan Zhang 	}
82f5188211SFan Zhang 
83f5188211SFan Zhang 	rte_memcpy(options.socket_files[nb_sockets], arg, len);
84f5188211SFan Zhang 
85f5188211SFan Zhang 	options.nb_sockets++;
86f5188211SFan Zhang 
87f5188211SFan Zhang 	return 0;
88f5188211SFan Zhang }
89f5188211SFan Zhang 
90f5188211SFan Zhang static int
91f5188211SFan Zhang parse_cryptodev_id(const char *q_arg)
92f5188211SFan Zhang {
93f5188211SFan Zhang 	char *end = NULL;
94f5188211SFan Zhang 	uint64_t pm;
95f5188211SFan Zhang 
96f5188211SFan Zhang 	/* parse decimal string */
97f5188211SFan Zhang 	pm = strtoul(q_arg, &end, 10);
98f5188211SFan Zhang 	if (pm > rte_cryptodev_count()) {
99f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Invalid Cryptodev ID %s\n", q_arg);
100f5188211SFan Zhang 		return -1;
101f5188211SFan Zhang 	}
102f5188211SFan Zhang 
103f5188211SFan Zhang 	options.cid = (uint8_t)pm;
104f5188211SFan Zhang 
105f5188211SFan Zhang 	return 0;
106f5188211SFan Zhang }
107f5188211SFan Zhang 
108f5188211SFan Zhang static int
109f5188211SFan Zhang parse_cdev_queue_id(const char *q_arg)
110f5188211SFan Zhang {
111f5188211SFan Zhang 	char *end = NULL;
112f5188211SFan Zhang 	uint64_t pm;
113f5188211SFan Zhang 
114f5188211SFan Zhang 	/* parse decimal string */
115f5188211SFan Zhang 	pm = strtoul(q_arg, &end, 10);
116f5188211SFan Zhang 	if (pm == UINT64_MAX) {
117f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Invalid Cryptodev Queue ID %s\n", q_arg);
118f5188211SFan Zhang 		return -1;
119f5188211SFan Zhang 	}
120f5188211SFan Zhang 
121f5188211SFan Zhang 	options.qid = (uint16_t)pm;
122f5188211SFan Zhang 
123f5188211SFan Zhang 	return 0;
124f5188211SFan Zhang }
125f5188211SFan Zhang 
126f5188211SFan Zhang static void
127f5188211SFan Zhang vhost_crypto_usage(const char *prgname)
128f5188211SFan Zhang {
129f5188211SFan Zhang 	printf("%s [EAL options] --\n"
130f5188211SFan Zhang 		"  --%s SOCKET-FILE-PATH\n"
131f5188211SFan Zhang 		"  --%s CRYPTODEV_ID: crypto device id\n"
132f5188211SFan Zhang 		"  --%s CDEV_QUEUE_ID: crypto device queue id\n"
133f5188211SFan Zhang 		"  --%s: zero copy\n"
134f5188211SFan Zhang 		"  --%s: guest polling\n",
135f5188211SFan Zhang 		prgname, SOCKET_FILE_KEYWORD, CRYPTODEV_ID_KEYWORD,
136f5188211SFan Zhang 		CRYPTODEV_QUEUE_KEYWORD, ZERO_COPY_KEYWORD, POLLING_KEYWORD);
137f5188211SFan Zhang }
138f5188211SFan Zhang 
139f5188211SFan Zhang static int
140f5188211SFan Zhang vhost_crypto_parse_args(int argc, char **argv)
141f5188211SFan Zhang {
142f5188211SFan Zhang 	int opt, ret;
143f5188211SFan Zhang 	char *prgname = argv[0];
144f5188211SFan Zhang 	char **argvopt;
145f5188211SFan Zhang 	int option_index;
146f5188211SFan Zhang 	struct option lgopts[] = {
147f5188211SFan Zhang 			{SOCKET_FILE_KEYWORD, required_argument, 0, 0},
148f5188211SFan Zhang 			{CRYPTODEV_ID_KEYWORD, required_argument, 0, 0},
149f5188211SFan Zhang 			{CRYPTODEV_QUEUE_KEYWORD, required_argument, 0, 0},
150f5188211SFan Zhang 			{ZERO_COPY_KEYWORD, no_argument, 0, 0},
151f5188211SFan Zhang 			{POLLING_KEYWORD, no_argument, 0, 0},
152f5188211SFan Zhang 			{NULL, 0, 0, 0}
153f5188211SFan Zhang 	};
154f5188211SFan Zhang 
155f5188211SFan Zhang 	options.cid = 0;
156f5188211SFan Zhang 	options.qid = 0;
157f5188211SFan Zhang 	options.nb_sockets = 0;
158f5188211SFan Zhang 	options.guest_polling = 0;
159f5188211SFan Zhang 	options.zero_copy = RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE;
160f5188211SFan Zhang 
161f5188211SFan Zhang 	argvopt = argv;
162f5188211SFan Zhang 
163f5188211SFan Zhang 	while ((opt = getopt_long(argc, argvopt, "s:",
164f5188211SFan Zhang 				  lgopts, &option_index)) != EOF) {
165f5188211SFan Zhang 
166f5188211SFan Zhang 		switch (opt) {
167f5188211SFan Zhang 		case 0:
168f5188211SFan Zhang 			if (strcmp(lgopts[option_index].name,
169f5188211SFan Zhang 					SOCKET_FILE_KEYWORD) == 0) {
170f5188211SFan Zhang 				ret = parse_socket_arg(optarg);
171f5188211SFan Zhang 				if (ret < 0) {
172f5188211SFan Zhang 					vhost_crypto_usage(prgname);
173f5188211SFan Zhang 					return ret;
174f5188211SFan Zhang 				}
175f5188211SFan Zhang 			} else if (strcmp(lgopts[option_index].name,
176f5188211SFan Zhang 					CRYPTODEV_ID_KEYWORD) == 0) {
177f5188211SFan Zhang 				ret = parse_cryptodev_id(optarg);
178f5188211SFan Zhang 				if (ret < 0) {
179f5188211SFan Zhang 					vhost_crypto_usage(prgname);
180f5188211SFan Zhang 					return ret;
181f5188211SFan Zhang 				}
182f5188211SFan Zhang 			} else if (strcmp(lgopts[option_index].name,
183f5188211SFan Zhang 					CRYPTODEV_QUEUE_KEYWORD) == 0) {
184f5188211SFan Zhang 				ret = parse_cdev_queue_id(optarg);
185f5188211SFan Zhang 				if (ret < 0) {
186f5188211SFan Zhang 					vhost_crypto_usage(prgname);
187f5188211SFan Zhang 					return ret;
188f5188211SFan Zhang 				}
189f5188211SFan Zhang 			} else if (strcmp(lgopts[option_index].name,
190f5188211SFan Zhang 					ZERO_COPY_KEYWORD) == 0) {
191f5188211SFan Zhang 				options.zero_copy =
192f5188211SFan Zhang 					RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE;
193f5188211SFan Zhang 			} else if (strcmp(lgopts[option_index].name,
194f5188211SFan Zhang 					POLLING_KEYWORD) == 0) {
195f5188211SFan Zhang 				options.guest_polling = 1;
196f5188211SFan Zhang 			} else {
197f5188211SFan Zhang 				vhost_crypto_usage(prgname);
198f5188211SFan Zhang 				return -EINVAL;
199f5188211SFan Zhang 			}
200f5188211SFan Zhang 			break;
201f5188211SFan Zhang 		default:
202f5188211SFan Zhang 			return -1;
203f5188211SFan Zhang 		}
204f5188211SFan Zhang 	}
205f5188211SFan Zhang 
206f5188211SFan Zhang 	if (options.nb_sockets == 0) {
207f5188211SFan Zhang 		options.socket_files[0] = strdup(DEF_SOCKET_FILE);
208f5188211SFan Zhang 		options.nb_sockets = 1;
209f5188211SFan Zhang 		RTE_LOG(INFO, USER1,
210f5188211SFan Zhang 				"VHOST-CRYPTO: use default socket file %s\n",
211f5188211SFan Zhang 				DEF_SOCKET_FILE);
212f5188211SFan Zhang 	}
213f5188211SFan Zhang 
214f5188211SFan Zhang 	return 0;
215f5188211SFan Zhang }
216f5188211SFan Zhang 
217f5188211SFan Zhang static int
218f5188211SFan Zhang new_device(int vid)
219f5188211SFan Zhang {
220f5188211SFan Zhang 	char path[PATH_MAX];
221f5188211SFan Zhang 	uint32_t idx, i;
222f5188211SFan Zhang 	int ret;
223f5188211SFan Zhang 
224f5188211SFan Zhang 	ret = rte_vhost_get_ifname(vid, path, PATH_MAX);
225f5188211SFan Zhang 	if (ret) {
226f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Cannot find matched socket\n");
227f5188211SFan Zhang 		return ret;
228f5188211SFan Zhang 	}
229f5188211SFan Zhang 
230f5188211SFan Zhang 	for (idx = 0; idx < options.nb_sockets; idx++) {
231f5188211SFan Zhang 		if (strcmp(path, options.socket_files[idx]) == 0)
232f5188211SFan Zhang 			break;
233f5188211SFan Zhang 	}
234f5188211SFan Zhang 
235f5188211SFan Zhang 	if (idx == options.nb_sockets) {
236f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Cannot find recorded socket\n");
237f5188211SFan Zhang 		return -ENOENT;
238f5188211SFan Zhang 	}
239f5188211SFan Zhang 
240f5188211SFan Zhang 	for (i = 0; i < 2; i++) {
241f5188211SFan Zhang 		vhost_cycles[i] = 0;
242f5188211SFan Zhang 		last_v_cycles[i] = 0;
243f5188211SFan Zhang 	}
244f5188211SFan Zhang 
245f5188211SFan Zhang 	ret = rte_vhost_crypto_create(vid, info.cid, info.sess_pool,
246f5188211SFan Zhang 			rte_lcore_to_socket_id(info.lcore_id));
247f5188211SFan Zhang 	if (ret) {
248f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Cannot create vhost crypto\n");
249f5188211SFan Zhang 		return ret;
250f5188211SFan Zhang 	}
251f5188211SFan Zhang 
252f5188211SFan Zhang 	ret = rte_vhost_crypto_set_zero_copy(vid, options.zero_copy);
253f5188211SFan Zhang 	if (ret) {
254f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Cannot %s zero copy feature\n",
255f5188211SFan Zhang 				options.zero_copy == 1 ? "enable" : "disable");
256f5188211SFan Zhang 		return ret;
257f5188211SFan Zhang 	}
258f5188211SFan Zhang 
259f5188211SFan Zhang 	info.vids[idx] = vid;
260f5188211SFan Zhang 	info.initialized[idx] = 1;
261f5188211SFan Zhang 
262f5188211SFan Zhang 	rte_wmb();
263f5188211SFan Zhang 
264f5188211SFan Zhang 	RTE_LOG(INFO, USER1, "New Vhost-crypto Device %s, Device ID %d\n", path,
265f5188211SFan Zhang 			vid);
266f5188211SFan Zhang 	return 0;
267f5188211SFan Zhang }
268f5188211SFan Zhang 
269f5188211SFan Zhang static void
270f5188211SFan Zhang destroy_device(int vid)
271f5188211SFan Zhang {
272f5188211SFan Zhang 	uint32_t i;
273f5188211SFan Zhang 
274f5188211SFan Zhang 	for (i = 0; i < info.nb_vids; i++) {
275f5188211SFan Zhang 		if (vid == info.vids[i])
276f5188211SFan Zhang 			break;
277f5188211SFan Zhang 	}
278f5188211SFan Zhang 
279f5188211SFan Zhang 	if (i == info.nb_vids) {
280f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Cannot find socket file from list\n");
281f5188211SFan Zhang 		return;
282f5188211SFan Zhang 	}
283f5188211SFan Zhang 
284f5188211SFan Zhang 	info.initialized[i] = 0;
285f5188211SFan Zhang 
286f5188211SFan Zhang 	rte_wmb();
287f5188211SFan Zhang 
288f5188211SFan Zhang 	rte_vhost_crypto_free(vid);
289f5188211SFan Zhang 
290f5188211SFan Zhang 	RTE_LOG(INFO, USER1, "Vhost Crypto Device %i Removed\n", vid);
291f5188211SFan Zhang }
292f5188211SFan Zhang 
293f5188211SFan Zhang static const struct vhost_device_ops virtio_crypto_device_ops = {
294f5188211SFan Zhang 	.new_device =  new_device,
295f5188211SFan Zhang 	.destroy_device = destroy_device,
296f5188211SFan Zhang };
297f5188211SFan Zhang 
298f5188211SFan Zhang __attribute__((unused))
299f5188211SFan Zhang static void clrscr(void)
300f5188211SFan Zhang {
301f5188211SFan Zhang 	system("@cls||clear");
302f5188211SFan Zhang }
303f5188211SFan Zhang 
304f5188211SFan Zhang static int
305f5188211SFan Zhang vhost_crypto_worker(__rte_unused void *arg)
306f5188211SFan Zhang {
307f5188211SFan Zhang 	struct rte_crypto_op *ops[NB_VIRTIO_QUEUES][MAX_PKT_BURST + 1];
308f5188211SFan Zhang 	struct rte_crypto_op *ops_deq[NB_VIRTIO_QUEUES][MAX_PKT_BURST + 1];
309f5188211SFan Zhang 	uint32_t nb_inflight_ops = 0;
310f5188211SFan Zhang 	uint16_t nb_callfds;
311f5188211SFan Zhang 	int callfds[VIRTIO_CRYPTO_MAX_NUM_BURST_VQS];
312f5188211SFan Zhang 	uint32_t lcore_id = rte_lcore_id();
313f5188211SFan Zhang 	uint32_t burst_size = MAX_PKT_BURST;
314f5188211SFan Zhang 	uint32_t i, j, k;
315f5188211SFan Zhang 	uint32_t to_fetch, fetched;
316f5188211SFan Zhang 	uint64_t t_start, t_end, interval;
317f5188211SFan Zhang 
318f5188211SFan Zhang 	int ret = 0;
319f5188211SFan Zhang 
320f5188211SFan Zhang 	RTE_LOG(INFO, USER1, "Processing on Core %u started\n", lcore_id);
321f5188211SFan Zhang 
322f5188211SFan Zhang 	for (i = 0; i < NB_VIRTIO_QUEUES; i++) {
323f5188211SFan Zhang 		if (rte_crypto_op_bulk_alloc(info.cop_pool,
324f5188211SFan Zhang 				RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops[i],
325f5188211SFan Zhang 				burst_size) < burst_size) {
326f5188211SFan Zhang 			RTE_LOG(ERR, USER1, "Failed to alloc cops\n");
327f5188211SFan Zhang 			ret = -1;
328f5188211SFan Zhang 			goto exit;
329f5188211SFan Zhang 		}
330f5188211SFan Zhang 	}
331f5188211SFan Zhang 
332f5188211SFan Zhang 	while (1) {
333f5188211SFan Zhang 		for (i = 0; i < info.nb_vids; i++) {
334f5188211SFan Zhang 			if (unlikely(info.initialized[i] == 0))
335f5188211SFan Zhang 				continue;
336f5188211SFan Zhang 
337f5188211SFan Zhang 			for (j = 0; j < NB_VIRTIO_QUEUES; j++) {
338f5188211SFan Zhang 				t_start = rte_rdtsc_precise();
339f5188211SFan Zhang 
340f5188211SFan Zhang 				to_fetch = RTE_MIN(burst_size,
341f5188211SFan Zhang 						(NB_CRYPTO_DESCRIPTORS -
342f5188211SFan Zhang 						nb_inflight_ops));
343f5188211SFan Zhang 				fetched = rte_vhost_crypto_fetch_requests(
344f5188211SFan Zhang 						info.vids[i], j, ops[j],
345f5188211SFan Zhang 						to_fetch);
346f5188211SFan Zhang 				nb_inflight_ops += rte_cryptodev_enqueue_burst(
347f5188211SFan Zhang 						info.cid, info.qid, ops[j],
348f5188211SFan Zhang 						fetched);
349f5188211SFan Zhang 				if (unlikely(rte_crypto_op_bulk_alloc(
350f5188211SFan Zhang 						info.cop_pool,
351f5188211SFan Zhang 						RTE_CRYPTO_OP_TYPE_SYMMETRIC,
352f5188211SFan Zhang 						ops[j], fetched) < fetched)) {
353f5188211SFan Zhang 					RTE_LOG(ERR, USER1, "Failed realloc\n");
354f5188211SFan Zhang 					return -1;
355f5188211SFan Zhang 				}
356f5188211SFan Zhang 				t_end = rte_rdtsc_precise();
357f5188211SFan Zhang 				interval = t_end - t_start;
358f5188211SFan Zhang 
359f5188211SFan Zhang 				vhost_cycles[fetched > 0] += interval;
360f5188211SFan Zhang 
361f5188211SFan Zhang 				t_start = t_end;
362f5188211SFan Zhang 				fetched = rte_cryptodev_dequeue_burst(
363f5188211SFan Zhang 						info.cid, info.qid,
364f5188211SFan Zhang 						ops_deq[j], RTE_MIN(burst_size,
365f5188211SFan Zhang 						nb_inflight_ops));
366f5188211SFan Zhang 				fetched = rte_vhost_crypto_finalize_requests(
367f5188211SFan Zhang 						ops_deq[j], fetched, callfds,
368f5188211SFan Zhang 						&nb_callfds);
369f5188211SFan Zhang 
370f5188211SFan Zhang 				nb_inflight_ops -= fetched;
371f5188211SFan Zhang 				outpkt_amount += fetched;
372f5188211SFan Zhang 
373f5188211SFan Zhang 				if (!options.guest_polling) {
374f5188211SFan Zhang 					for (k = 0; k < nb_callfds; k++)
375f5188211SFan Zhang 						eventfd_write(callfds[k],
376f5188211SFan Zhang 								(eventfd_t)1);
377f5188211SFan Zhang 				}
378f5188211SFan Zhang 
379f5188211SFan Zhang 				rte_mempool_put_bulk(info.cop_pool,
380f5188211SFan Zhang 						(void **)ops_deq[j], fetched);
381f5188211SFan Zhang 				interval = rte_rdtsc_precise() - t_start;
382f5188211SFan Zhang 
383f5188211SFan Zhang 				vhost_cycles[fetched > 0] += interval;
384f5188211SFan Zhang 			}
385f5188211SFan Zhang 		}
386f5188211SFan Zhang 	}
387f5188211SFan Zhang exit:
388f5188211SFan Zhang 	return ret;
389f5188211SFan Zhang }
390f5188211SFan Zhang 
391f5188211SFan Zhang 
392f5188211SFan Zhang static void
393f5188211SFan Zhang unregister_drivers(int socket_num)
394f5188211SFan Zhang {
395f5188211SFan Zhang 	int ret;
396f5188211SFan Zhang 
397f5188211SFan Zhang 	ret = rte_vhost_driver_unregister(options.socket_files[socket_num]);
398f5188211SFan Zhang 	if (ret != 0)
399f5188211SFan Zhang 		RTE_LOG(ERR, USER1,
400f5188211SFan Zhang 			"Fail to unregister vhost driver for %s.\n",
401f5188211SFan Zhang 			options.socket_files[socket_num]);
402f5188211SFan Zhang }
403f5188211SFan Zhang 
404f5188211SFan Zhang int
405f5188211SFan Zhang main(int argc, char *argv[])
406f5188211SFan Zhang {
407f5188211SFan Zhang 	struct rte_cryptodev_qp_conf qp_conf = {NB_CRYPTO_DESCRIPTORS};
408f5188211SFan Zhang 	struct rte_cryptodev_config config;
409f5188211SFan Zhang 	struct rte_cryptodev_info dev_info;
410f5188211SFan Zhang 	uint32_t cryptodev_id;
411f5188211SFan Zhang 	uint32_t worker_lcore;
412f5188211SFan Zhang 	char name[128];
413f5188211SFan Zhang 	uint32_t i = 0;
414f5188211SFan Zhang 	int ret;
415f5188211SFan Zhang 
416f5188211SFan Zhang 	ret = rte_eal_init(argc, argv);
417f5188211SFan Zhang 	if (ret < 0)
418f5188211SFan Zhang 		return -1;
419f5188211SFan Zhang 	argc -= ret;
420f5188211SFan Zhang 	argv += ret;
421f5188211SFan Zhang 
422f5188211SFan Zhang 	ret = vhost_crypto_parse_args(argc, argv);
423f5188211SFan Zhang 	if (ret < 0)
424f5188211SFan Zhang 		rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n");
425f5188211SFan Zhang 
426f5188211SFan Zhang 	info.cid = options.cid;
427f5188211SFan Zhang 	info.qid = options.qid;
428f5188211SFan Zhang 
429f5188211SFan Zhang 	worker_lcore = rte_get_next_lcore(0, 1, 0);
430f5188211SFan Zhang 	if (worker_lcore == RTE_MAX_LCORE)
431f5188211SFan Zhang 		rte_exit(EXIT_FAILURE, "Not enough lcore\n");
432f5188211SFan Zhang 
433f5188211SFan Zhang 	cryptodev_id = info.cid;
434f5188211SFan Zhang 	rte_cryptodev_info_get(cryptodev_id, &dev_info);
435f5188211SFan Zhang 	if (dev_info.max_nb_queue_pairs < info.qid + 1) {
436f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Number of queues cannot over %u",
437f5188211SFan Zhang 				dev_info.max_nb_queue_pairs);
438f5188211SFan Zhang 		goto error_exit;
439f5188211SFan Zhang 	}
440f5188211SFan Zhang 
441f5188211SFan Zhang 	config.nb_queue_pairs = dev_info.max_nb_queue_pairs;
442f5188211SFan Zhang 	config.socket_id = rte_lcore_to_socket_id(worker_lcore);
443f5188211SFan Zhang 
444f5188211SFan Zhang 	ret = rte_cryptodev_configure(cryptodev_id, &config);
445f5188211SFan Zhang 	if (ret < 0) {
446f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Failed to configure cryptodev %u",
447f5188211SFan Zhang 				cryptodev_id);
448f5188211SFan Zhang 		goto error_exit;
449f5188211SFan Zhang 	}
450f5188211SFan Zhang 
451f5188211SFan Zhang 	snprintf(name, 127, "SESS_POOL_%u", worker_lcore);
452f5188211SFan Zhang 	info.sess_pool = rte_mempool_create(name, SESSION_MAP_ENTRIES,
453*a106fcceSPablo de Lara 			rte_cryptodev_sym_get_private_session_size(
454f5188211SFan Zhang 			cryptodev_id), 64, 0, NULL, NULL, NULL, NULL,
455f5188211SFan Zhang 			rte_lcore_to_socket_id(worker_lcore), 0);
456f5188211SFan Zhang 	if (!info.sess_pool) {
457f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Failed to create mempool");
458f5188211SFan Zhang 		goto error_exit;
459f5188211SFan Zhang 	}
460f5188211SFan Zhang 
461f5188211SFan Zhang 	snprintf(name, 127, "COPPOOL_%u", worker_lcore);
462f5188211SFan Zhang 	info.cop_pool = rte_crypto_op_pool_create(name,
463f5188211SFan Zhang 			RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MEMPOOL_OBJS,
464f5188211SFan Zhang 			NB_CACHE_OBJS, 0, rte_lcore_to_socket_id(worker_lcore));
465f5188211SFan Zhang 
466f5188211SFan Zhang 	if (!info.cop_pool) {
467f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Lcore %u failed to create crypto pool",
468f5188211SFan Zhang 				worker_lcore);
469f5188211SFan Zhang 		ret = -1;
470f5188211SFan Zhang 		goto error_exit;
471f5188211SFan Zhang 	}
472f5188211SFan Zhang 
473f5188211SFan Zhang 	info.nb_vids = options.nb_sockets;
474f5188211SFan Zhang 	for (i = 0; i < MAX_NB_SOCKETS; i++)
475f5188211SFan Zhang 		info.vids[i] = -1;
476f5188211SFan Zhang 
477f5188211SFan Zhang 	for (i = 0; i < dev_info.max_nb_queue_pairs; i++) {
478f5188211SFan Zhang 		ret = rte_cryptodev_queue_pair_setup(cryptodev_id, i,
479f5188211SFan Zhang 				&qp_conf, rte_lcore_to_socket_id(worker_lcore),
480f5188211SFan Zhang 				info.sess_pool);
481f5188211SFan Zhang 		if (ret < 0) {
482f5188211SFan Zhang 			RTE_LOG(ERR, USER1, "Failed to configure qp %u\n",
483f5188211SFan Zhang 					info.cid);
484f5188211SFan Zhang 			goto error_exit;
485f5188211SFan Zhang 		}
486f5188211SFan Zhang 	}
487f5188211SFan Zhang 
488f5188211SFan Zhang 	ret = rte_cryptodev_start(cryptodev_id);
489f5188211SFan Zhang 	if (ret < 0) {
490f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Failed to start cryptodev %u\n", info.cid);
491f5188211SFan Zhang 		goto error_exit;
492f5188211SFan Zhang 	}
493f5188211SFan Zhang 
494f5188211SFan Zhang 	info.cid = cryptodev_id;
495f5188211SFan Zhang 	info.lcore_id = worker_lcore;
496f5188211SFan Zhang 
497f5188211SFan Zhang 	if (rte_eal_remote_launch(vhost_crypto_worker, NULL, worker_lcore)
498f5188211SFan Zhang 			< 0) {
499f5188211SFan Zhang 		RTE_LOG(ERR, USER1, "Failed to start worker lcore");
500f5188211SFan Zhang 		goto error_exit;
501f5188211SFan Zhang 	}
502f5188211SFan Zhang 
503f5188211SFan Zhang 	for (i = 0; i < options.nb_sockets; i++) {
504f5188211SFan Zhang 		if (rte_vhost_driver_register(options.socket_files[i],
505f5188211SFan Zhang 				RTE_VHOST_USER_DEQUEUE_ZERO_COPY) < 0) {
506f5188211SFan Zhang 			RTE_LOG(ERR, USER1, "socket %s already exists\n",
507f5188211SFan Zhang 					options.socket_files[i]);
508f5188211SFan Zhang 			goto error_exit;
509f5188211SFan Zhang 		}
510f5188211SFan Zhang 
511f5188211SFan Zhang 		rte_vhost_driver_callback_register(options.socket_files[i],
512f5188211SFan Zhang 				&virtio_crypto_device_ops);
513f5188211SFan Zhang 
514f5188211SFan Zhang 		if (rte_vhost_driver_start(options.socket_files[i]) < 0) {
515f5188211SFan Zhang 			RTE_LOG(ERR, USER1, "failed to start vhost driver.\n");
516f5188211SFan Zhang 			goto error_exit;
517f5188211SFan Zhang 		}
518f5188211SFan Zhang 	}
519f5188211SFan Zhang 
520f5188211SFan Zhang 	RTE_LCORE_FOREACH(worker_lcore)
521f5188211SFan Zhang 		rte_eal_wait_lcore(worker_lcore);
522f5188211SFan Zhang 
523f5188211SFan Zhang 	rte_mempool_free(info.sess_pool);
524f5188211SFan Zhang 	rte_mempool_free(info.cop_pool);
525f5188211SFan Zhang 
526f5188211SFan Zhang 	return 0;
527f5188211SFan Zhang 
528f5188211SFan Zhang error_exit:
529f5188211SFan Zhang 	for (i = 0; i < options.nb_sockets; i++)
530f5188211SFan Zhang 		unregister_drivers(i);
531f5188211SFan Zhang 
532f5188211SFan Zhang 	rte_mempool_free(info.cop_pool);
533f5188211SFan Zhang 	rte_mempool_free(info.sess_pool);
534f5188211SFan Zhang 
535f5188211SFan Zhang 	return -1;
536f5188211SFan Zhang }
537