1de06137cSYuval Avnery /* SPDX-License-Identifier: BSD-3-Clause
2de06137cSYuval Avnery * Copyright 2020 Mellanox Technologies, Ltd
3de06137cSYuval Avnery */
4de06137cSYuval Avnery
5de06137cSYuval Avnery #include <stdio.h>
6de06137cSYuval Avnery #include <stdlib.h>
7de06137cSYuval Avnery #include <string.h>
8de06137cSYuval Avnery #include <stdint.h>
9de06137cSYuval Avnery #include <stdbool.h>
10de06137cSYuval Avnery #include <stdarg.h>
11de06137cSYuval Avnery #include <ctype.h>
12de06137cSYuval Avnery #include <errno.h>
13de06137cSYuval Avnery #include <getopt.h>
14de06137cSYuval Avnery #include <signal.h>
15de06137cSYuval Avnery
16de06137cSYuval Avnery #include <rte_eal.h>
17de06137cSYuval Avnery #include <rte_common.h>
18de06137cSYuval Avnery #include <rte_malloc.h>
19de06137cSYuval Avnery #include <rte_mempool.h>
20de06137cSYuval Avnery #include <rte_mbuf.h>
21de06137cSYuval Avnery #include <rte_cycles.h>
22de06137cSYuval Avnery #include <rte_regexdev.h>
23de06137cSYuval Avnery
24de06137cSYuval Avnery #define MAX_FILE_NAME 255
25de06137cSYuval Avnery #define MBUF_CACHE_SIZE 256
26de06137cSYuval Avnery #define MBUF_SIZE (1 << 8)
27de06137cSYuval Avnery #define START_BURST_SIZE 32u
28*b6aceadaSGerry Gribbon #define MAX_MATCH_MODE 2
29de06137cSYuval Avnery
30de06137cSYuval Avnery enum app_args {
31de06137cSYuval Avnery ARG_HELP,
32de06137cSYuval Avnery ARG_RULES_FILE_NAME,
33de06137cSYuval Avnery ARG_DATA_FILE_NAME,
34de06137cSYuval Avnery ARG_NUM_OF_JOBS,
35de06137cSYuval Avnery ARG_PERF_MODE,
36de06137cSYuval Avnery ARG_NUM_OF_ITERATIONS,
374545bd00SOphir Munk ARG_NUM_OF_QPS,
386b99ba8dSOphir Munk ARG_NUM_OF_LCORES,
39cace2d7eSSuanming Mou ARG_NUM_OF_MBUF_SEGS,
40*b6aceadaSGerry Gribbon ARG_NUM_OF_MATCH_MODE,
41de06137cSYuval Avnery };
42de06137cSYuval Avnery
4330cf1713SGuy Kaneti struct job_ctx {
4430cf1713SGuy Kaneti struct rte_mbuf *mbuf;
4530cf1713SGuy Kaneti };
4630cf1713SGuy Kaneti
474545bd00SOphir Munk struct qp_params {
484545bd00SOphir Munk uint32_t total_enqueue;
494545bd00SOphir Munk uint32_t total_dequeue;
504545bd00SOphir Munk uint32_t total_matches;
514545bd00SOphir Munk struct rte_regex_ops **ops;
524545bd00SOphir Munk struct job_ctx *jobs_ctx;
534545bd00SOphir Munk char *buf;
54e5e518edSOphir Munk uint64_t start;
55e5e518edSOphir Munk uint64_t cycles;
564545bd00SOphir Munk };
574545bd00SOphir Munk
586b99ba8dSOphir Munk struct qps_per_lcore {
596b99ba8dSOphir Munk unsigned int lcore_id;
606b99ba8dSOphir Munk int socket;
616b99ba8dSOphir Munk uint16_t qp_id_base;
626b99ba8dSOphir Munk uint16_t nb_qps;
636b99ba8dSOphir Munk };
646b99ba8dSOphir Munk
656b99ba8dSOphir Munk struct regex_conf {
666b99ba8dSOphir Munk uint32_t nb_jobs;
676b99ba8dSOphir Munk bool perf_mode;
686b99ba8dSOphir Munk uint32_t nb_iterations;
696b99ba8dSOphir Munk char *data_file;
706b99ba8dSOphir Munk uint8_t nb_max_matches;
716b99ba8dSOphir Munk uint32_t nb_qps;
726b99ba8dSOphir Munk uint16_t qp_id_base;
736b99ba8dSOphir Munk char *data_buf;
746b99ba8dSOphir Munk long data_len;
756b99ba8dSOphir Munk long job_len;
76cace2d7eSSuanming Mou uint32_t nb_segs;
77*b6aceadaSGerry Gribbon uint32_t match_mode;
786b99ba8dSOphir Munk };
796b99ba8dSOphir Munk
80de06137cSYuval Avnery static void
usage(const char * prog_name)81de06137cSYuval Avnery usage(const char *prog_name)
82de06137cSYuval Avnery {
83de06137cSYuval Avnery printf("%s [EAL options] --\n"
84de06137cSYuval Avnery " --rules NAME: precompiled rules file\n"
85de06137cSYuval Avnery " --data NAME: data file to use\n"
86de06137cSYuval Avnery " --nb_jobs: number of jobs to use\n"
87de06137cSYuval Avnery " --perf N: only outputs the performance data\n"
884545bd00SOphir Munk " --nb_iter N: number of iteration to run\n"
896b99ba8dSOphir Munk " --nb_qps N: number of queues to use\n"
90cace2d7eSSuanming Mou " --nb_lcores N: number of lcores to use\n"
91*b6aceadaSGerry Gribbon " --nb_segs N: number of mbuf segments\n"
92*b6aceadaSGerry Gribbon " --match_mode N: match mode: 0 - None (default),"
93*b6aceadaSGerry Gribbon " 1 - Highest Priority, 2 - Stop On Any\n",
94de06137cSYuval Avnery prog_name);
95de06137cSYuval Avnery }
96de06137cSYuval Avnery
97de06137cSYuval Avnery static void
args_parse(int argc,char ** argv,char * rules_file,char * data_file,uint32_t * nb_jobs,bool * perf_mode,uint32_t * nb_iterations,uint32_t * nb_qps,uint32_t * nb_lcores,uint32_t * nb_segs,uint32_t * match_mode)98de06137cSYuval Avnery args_parse(int argc, char **argv, char *rules_file, char *data_file,
994545bd00SOphir Munk uint32_t *nb_jobs, bool *perf_mode, uint32_t *nb_iterations,
100*b6aceadaSGerry Gribbon uint32_t *nb_qps, uint32_t *nb_lcores, uint32_t *nb_segs,
101*b6aceadaSGerry Gribbon uint32_t *match_mode)
102de06137cSYuval Avnery {
103de06137cSYuval Avnery char **argvopt;
104de06137cSYuval Avnery int opt;
105de06137cSYuval Avnery int opt_idx;
106de06137cSYuval Avnery size_t len;
107de06137cSYuval Avnery static struct option lgopts[] = {
108de06137cSYuval Avnery { "help", 0, 0, ARG_HELP},
109de06137cSYuval Avnery /* Rules database file to load. */
110de06137cSYuval Avnery { "rules", 1, 0, ARG_RULES_FILE_NAME},
111de06137cSYuval Avnery /* Data file to load. */
112de06137cSYuval Avnery { "data", 1, 0, ARG_DATA_FILE_NAME},
113de06137cSYuval Avnery /* Number of jobs to create. */
114de06137cSYuval Avnery { "nb_jobs", 1, 0, ARG_NUM_OF_JOBS},
115de06137cSYuval Avnery /* Perf test only */
116de06137cSYuval Avnery { "perf", 0, 0, ARG_PERF_MODE},
117de06137cSYuval Avnery /* Number of iterations to run with perf test */
11806ca0e4bSOphir Munk { "nb_iter", 1, 0, ARG_NUM_OF_ITERATIONS},
1194545bd00SOphir Munk /* Number of QPs. */
1204545bd00SOphir Munk { "nb_qps", 1, 0, ARG_NUM_OF_QPS},
1216b99ba8dSOphir Munk /* Number of lcores. */
1226b99ba8dSOphir Munk { "nb_lcores", 1, 0, ARG_NUM_OF_LCORES},
123cace2d7eSSuanming Mou /* Number of mbuf segments. */
124cace2d7eSSuanming Mou { "nb_segs", 1, 0, ARG_NUM_OF_MBUF_SEGS},
125*b6aceadaSGerry Gribbon /* Match mode. */
126*b6aceadaSGerry Gribbon { "match_mode", 1, 0, ARG_NUM_OF_MATCH_MODE},
12706ca0e4bSOphir Munk /* End of options */
12806ca0e4bSOphir Munk { 0, 0, 0, 0 }
129de06137cSYuval Avnery };
130de06137cSYuval Avnery
131de06137cSYuval Avnery argvopt = argv;
132de06137cSYuval Avnery while ((opt = getopt_long(argc, argvopt, "",
133de06137cSYuval Avnery lgopts, &opt_idx)) != EOF) {
134de06137cSYuval Avnery switch (opt) {
135de06137cSYuval Avnery case ARG_RULES_FILE_NAME:
136de06137cSYuval Avnery len = strnlen(optarg, MAX_FILE_NAME - 1);
137de06137cSYuval Avnery if (len == MAX_FILE_NAME)
138de06137cSYuval Avnery rte_exit(EXIT_FAILURE,
139de06137cSYuval Avnery "Rule file name to long max %d\n",
140de06137cSYuval Avnery MAX_FILE_NAME - 1);
141de06137cSYuval Avnery strncpy(rules_file, optarg, MAX_FILE_NAME - 1);
142de06137cSYuval Avnery break;
143de06137cSYuval Avnery case ARG_DATA_FILE_NAME:
144de06137cSYuval Avnery len = strnlen(optarg, MAX_FILE_NAME - 1);
145de06137cSYuval Avnery if (len == MAX_FILE_NAME)
146de06137cSYuval Avnery rte_exit(EXIT_FAILURE,
147de06137cSYuval Avnery "Data file name to long max %d\n",
148de06137cSYuval Avnery MAX_FILE_NAME - 1);
149de06137cSYuval Avnery strncpy(data_file, optarg, MAX_FILE_NAME - 1);
150de06137cSYuval Avnery break;
151de06137cSYuval Avnery case ARG_NUM_OF_JOBS:
152de06137cSYuval Avnery *nb_jobs = atoi(optarg);
153de06137cSYuval Avnery break;
154de06137cSYuval Avnery case ARG_PERF_MODE:
155de06137cSYuval Avnery *perf_mode = true;
156de06137cSYuval Avnery break;
157de06137cSYuval Avnery case ARG_NUM_OF_ITERATIONS:
158de06137cSYuval Avnery *nb_iterations = atoi(optarg);
159de06137cSYuval Avnery break;
1604545bd00SOphir Munk case ARG_NUM_OF_QPS:
1614545bd00SOphir Munk *nb_qps = atoi(optarg);
1624545bd00SOphir Munk break;
1636b99ba8dSOphir Munk case ARG_NUM_OF_LCORES:
1646b99ba8dSOphir Munk *nb_lcores = atoi(optarg);
1656b99ba8dSOphir Munk break;
166cace2d7eSSuanming Mou case ARG_NUM_OF_MBUF_SEGS:
167cace2d7eSSuanming Mou *nb_segs = atoi(optarg);
168cace2d7eSSuanming Mou break;
169*b6aceadaSGerry Gribbon case ARG_NUM_OF_MATCH_MODE:
170*b6aceadaSGerry Gribbon *match_mode = atoi(optarg);
171*b6aceadaSGerry Gribbon if (*match_mode > MAX_MATCH_MODE)
172*b6aceadaSGerry Gribbon rte_exit(EXIT_FAILURE,
173*b6aceadaSGerry Gribbon "Invalid match mode value\n");
174*b6aceadaSGerry Gribbon break;
175de06137cSYuval Avnery case ARG_HELP:
176e0512833SThomas Monjalon usage(argv[0]);
177de06137cSYuval Avnery break;
178de06137cSYuval Avnery default:
179e0512833SThomas Monjalon usage(argv[0]);
180487cfc24SThomas Monjalon rte_exit(EXIT_FAILURE, "Invalid option: %s\n", argv[optind]);
181de06137cSYuval Avnery break;
182de06137cSYuval Avnery }
183de06137cSYuval Avnery }
184de06137cSYuval Avnery
185de06137cSYuval Avnery if (!perf_mode)
186de06137cSYuval Avnery *nb_iterations = 1;
187de06137cSYuval Avnery }
188de06137cSYuval Avnery
189de06137cSYuval Avnery static long
read_file(char * file,char ** buf)190de06137cSYuval Avnery read_file(char *file, char **buf)
191de06137cSYuval Avnery {
192de06137cSYuval Avnery FILE *fp;
193de06137cSYuval Avnery long buf_len = 0;
194de06137cSYuval Avnery size_t read_len;
195de06137cSYuval Avnery int res = 0;
196de06137cSYuval Avnery
197de06137cSYuval Avnery fp = fopen(file, "r");
198de06137cSYuval Avnery if (!fp)
199de06137cSYuval Avnery return -EIO;
200de06137cSYuval Avnery if (fseek(fp, 0L, SEEK_END) == 0) {
201de06137cSYuval Avnery buf_len = ftell(fp);
202de06137cSYuval Avnery if (buf_len == -1) {
203de06137cSYuval Avnery res = EIO;
204de06137cSYuval Avnery goto error;
205de06137cSYuval Avnery }
206de06137cSYuval Avnery *buf = rte_malloc(NULL, sizeof(char) * (buf_len + 1), 4096);
207de06137cSYuval Avnery if (!*buf) {
208de06137cSYuval Avnery res = ENOMEM;
209de06137cSYuval Avnery goto error;
210de06137cSYuval Avnery }
211de06137cSYuval Avnery if (fseek(fp, 0L, SEEK_SET) != 0) {
212de06137cSYuval Avnery res = EIO;
213de06137cSYuval Avnery goto error;
214de06137cSYuval Avnery }
215de06137cSYuval Avnery read_len = fread(*buf, sizeof(char), buf_len, fp);
216de06137cSYuval Avnery if (read_len != (unsigned long)buf_len) {
217de06137cSYuval Avnery res = EIO;
218de06137cSYuval Avnery goto error;
219de06137cSYuval Avnery }
220de06137cSYuval Avnery }
221de06137cSYuval Avnery fclose(fp);
222de06137cSYuval Avnery return buf_len;
223de06137cSYuval Avnery error:
224de06137cSYuval Avnery printf("Error, can't open file %s\n, err = %d", file, res);
225de06137cSYuval Avnery if (fp)
226de06137cSYuval Avnery fclose(fp);
227de06137cSYuval Avnery rte_free(*buf);
228de06137cSYuval Avnery return -res;
229de06137cSYuval Avnery }
230de06137cSYuval Avnery
231de06137cSYuval Avnery static int
clone_buf(char * data_buf,char ** buf,long data_len)232f5cffb7eSOphir Munk clone_buf(char *data_buf, char **buf, long data_len)
233f5cffb7eSOphir Munk {
234f5cffb7eSOphir Munk char *dest_buf;
235f5cffb7eSOphir Munk dest_buf =
236f5cffb7eSOphir Munk rte_malloc(NULL, sizeof(char) * (data_len + 1), 4096);
237f5cffb7eSOphir Munk if (!dest_buf)
238f5cffb7eSOphir Munk return -ENOMEM;
239f5cffb7eSOphir Munk memcpy(dest_buf, data_buf, data_len + 1);
240f5cffb7eSOphir Munk *buf = dest_buf;
241f5cffb7eSOphir Munk return 0;
242f5cffb7eSOphir Munk }
243f5cffb7eSOphir Munk
244f5cffb7eSOphir Munk static int
init_port(uint16_t * nb_max_payload,char * rules_file,uint8_t * nb_max_matches,uint32_t nb_qps)2454545bd00SOphir Munk init_port(uint16_t *nb_max_payload, char *rules_file, uint8_t *nb_max_matches,
2464545bd00SOphir Munk uint32_t nb_qps)
247de06137cSYuval Avnery {
248de06137cSYuval Avnery uint16_t id;
2494545bd00SOphir Munk uint16_t qp_id;
250de06137cSYuval Avnery uint16_t num_devs;
251de06137cSYuval Avnery char *rules = NULL;
252de06137cSYuval Avnery long rules_len;
253de06137cSYuval Avnery struct rte_regexdev_info info;
254de06137cSYuval Avnery struct rte_regexdev_config dev_conf = {
2554545bd00SOphir Munk .nb_queue_pairs = nb_qps,
256de06137cSYuval Avnery .nb_groups = 1,
257de06137cSYuval Avnery };
258de06137cSYuval Avnery struct rte_regexdev_qp_conf qp_conf = {
259de06137cSYuval Avnery .nb_desc = 1024,
260d96d0fa7SGuy Kaneti .qp_conf_flags = 0,
261de06137cSYuval Avnery };
262de06137cSYuval Avnery int res = 0;
263de06137cSYuval Avnery
264de06137cSYuval Avnery num_devs = rte_regexdev_count();
265de06137cSYuval Avnery if (num_devs == 0) {
266de06137cSYuval Avnery printf("Error, no devices detected.\n");
267de06137cSYuval Avnery return -EINVAL;
268de06137cSYuval Avnery }
269de06137cSYuval Avnery
270de06137cSYuval Avnery rules_len = read_file(rules_file, &rules);
271de06137cSYuval Avnery if (rules_len < 0) {
272de06137cSYuval Avnery printf("Error, can't read rules files.\n");
273de06137cSYuval Avnery res = -EIO;
274de06137cSYuval Avnery goto error;
275de06137cSYuval Avnery }
276de06137cSYuval Avnery
277de06137cSYuval Avnery for (id = 0; id < num_devs; id++) {
278de06137cSYuval Avnery res = rte_regexdev_info_get(id, &info);
279de06137cSYuval Avnery if (res != 0) {
280de06137cSYuval Avnery printf("Error, can't get device info.\n");
281de06137cSYuval Avnery goto error;
282de06137cSYuval Avnery }
283de06137cSYuval Avnery printf(":: initializing dev: %d\n", id);
284de06137cSYuval Avnery *nb_max_matches = info.max_matches;
285de06137cSYuval Avnery *nb_max_payload = info.max_payload_size;
286de06137cSYuval Avnery if (info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_AS_END_F)
2874545bd00SOphir Munk dev_conf.dev_cfg_flags |=
2884545bd00SOphir Munk RTE_REGEXDEV_CFG_MATCH_AS_END_F;
289de06137cSYuval Avnery dev_conf.nb_max_matches = info.max_matches;
290de06137cSYuval Avnery dev_conf.nb_rules_per_group = info.max_rules_per_group;
291de06137cSYuval Avnery dev_conf.rule_db_len = rules_len;
292de06137cSYuval Avnery dev_conf.rule_db = rules;
293de06137cSYuval Avnery res = rte_regexdev_configure(id, &dev_conf);
294de06137cSYuval Avnery if (res < 0) {
295de06137cSYuval Avnery printf("Error, can't configure device %d.\n", id);
296de06137cSYuval Avnery goto error;
297de06137cSYuval Avnery }
298d96d0fa7SGuy Kaneti if (info.regexdev_capa & RTE_REGEXDEV_CAPA_QUEUE_PAIR_OOS_F)
2994545bd00SOphir Munk qp_conf.qp_conf_flags |=
3004545bd00SOphir Munk RTE_REGEX_QUEUE_PAIR_CFG_OOS_F;
3014545bd00SOphir Munk for (qp_id = 0; qp_id < nb_qps; qp_id++) {
3024545bd00SOphir Munk res = rte_regexdev_queue_pair_setup(id, qp_id,
3034545bd00SOphir Munk &qp_conf);
304de06137cSYuval Avnery if (res < 0) {
3054545bd00SOphir Munk printf("Error, can't setup queue pair %u for "
3064545bd00SOphir Munk "device %d.\n", qp_id, id);
307de06137cSYuval Avnery goto error;
308de06137cSYuval Avnery }
3094545bd00SOphir Munk }
310de06137cSYuval Avnery printf(":: initializing device: %d done\n", id);
311de06137cSYuval Avnery }
312de06137cSYuval Avnery rte_free(rules);
313de06137cSYuval Avnery return 0;
314de06137cSYuval Avnery error:
315de06137cSYuval Avnery rte_free(rules);
316de06137cSYuval Avnery return res;
317de06137cSYuval Avnery }
318de06137cSYuval Avnery
319de06137cSYuval Avnery static void
extbuf_free_cb(void * addr __rte_unused,void * fcb_opaque __rte_unused)320de06137cSYuval Avnery extbuf_free_cb(void *addr __rte_unused, void *fcb_opaque __rte_unused)
321de06137cSYuval Avnery {
322de06137cSYuval Avnery }
323de06137cSYuval Avnery
324cace2d7eSSuanming Mou static inline struct rte_mbuf *
regex_create_segmented_mbuf(struct rte_mempool * mbuf_pool,int pkt_len,int nb_segs,void * buf)325cace2d7eSSuanming Mou regex_create_segmented_mbuf(struct rte_mempool *mbuf_pool, int pkt_len,
326cace2d7eSSuanming Mou int nb_segs, void *buf) {
327cace2d7eSSuanming Mou
328cace2d7eSSuanming Mou struct rte_mbuf *m = NULL, *mbuf = NULL;
329cace2d7eSSuanming Mou uint8_t *dst;
330cace2d7eSSuanming Mou char *src = buf;
331cace2d7eSSuanming Mou int data_len = 0;
332cace2d7eSSuanming Mou int i, size;
333cace2d7eSSuanming Mou int t_len;
334cace2d7eSSuanming Mou
335cace2d7eSSuanming Mou if (pkt_len < 1) {
336cace2d7eSSuanming Mou printf("Packet size must be 1 or more (is %d)\n", pkt_len);
337cace2d7eSSuanming Mou return NULL;
338cace2d7eSSuanming Mou }
339cace2d7eSSuanming Mou
340cace2d7eSSuanming Mou if (nb_segs < 1) {
341cace2d7eSSuanming Mou printf("Number of segments must be 1 or more (is %d)\n",
342cace2d7eSSuanming Mou nb_segs);
343cace2d7eSSuanming Mou return NULL;
344cace2d7eSSuanming Mou }
345cace2d7eSSuanming Mou
346cace2d7eSSuanming Mou t_len = pkt_len >= nb_segs ? (pkt_len / nb_segs +
347cace2d7eSSuanming Mou !!(pkt_len % nb_segs)) : 1;
348cace2d7eSSuanming Mou size = pkt_len;
349cace2d7eSSuanming Mou
350cace2d7eSSuanming Mou /* Create chained mbuf_src and fill it with buf data */
351cace2d7eSSuanming Mou for (i = 0; size > 0; i++) {
352cace2d7eSSuanming Mou
353cace2d7eSSuanming Mou m = rte_pktmbuf_alloc(mbuf_pool);
354cace2d7eSSuanming Mou if (i == 0)
355cace2d7eSSuanming Mou mbuf = m;
356cace2d7eSSuanming Mou
357cace2d7eSSuanming Mou if (m == NULL) {
358cace2d7eSSuanming Mou printf("Cannot create segment for source mbuf");
359cace2d7eSSuanming Mou goto fail;
360cace2d7eSSuanming Mou }
361cace2d7eSSuanming Mou
362cace2d7eSSuanming Mou data_len = size > t_len ? t_len : size;
363cace2d7eSSuanming Mou memset(rte_pktmbuf_mtod(m, uint8_t *), 0,
364cace2d7eSSuanming Mou rte_pktmbuf_tailroom(m));
365cace2d7eSSuanming Mou memcpy(rte_pktmbuf_mtod(m, uint8_t *), src, data_len);
366cace2d7eSSuanming Mou dst = (uint8_t *)rte_pktmbuf_append(m, data_len);
367cace2d7eSSuanming Mou if (dst == NULL) {
368cace2d7eSSuanming Mou printf("Cannot append %d bytes to the mbuf\n",
369cace2d7eSSuanming Mou data_len);
370cace2d7eSSuanming Mou goto fail;
371cace2d7eSSuanming Mou }
372cace2d7eSSuanming Mou
373cace2d7eSSuanming Mou if (mbuf != m)
374cace2d7eSSuanming Mou rte_pktmbuf_chain(mbuf, m);
375cace2d7eSSuanming Mou src += data_len;
376cace2d7eSSuanming Mou size -= data_len;
377cace2d7eSSuanming Mou
378cace2d7eSSuanming Mou }
379cace2d7eSSuanming Mou return mbuf;
380cace2d7eSSuanming Mou
381cace2d7eSSuanming Mou fail:
382cace2d7eSSuanming Mou rte_pktmbuf_free(mbuf);
383cace2d7eSSuanming Mou return NULL;
384cace2d7eSSuanming Mou }
385cace2d7eSSuanming Mou
386de06137cSYuval Avnery static int
run_regex(void * args)3876b99ba8dSOphir Munk run_regex(void *args)
388de06137cSYuval Avnery {
3896b99ba8dSOphir Munk struct regex_conf *rgxc = args;
3906b99ba8dSOphir Munk uint32_t nb_jobs = rgxc->nb_jobs;
391cace2d7eSSuanming Mou uint32_t nb_segs = rgxc->nb_segs;
3926b99ba8dSOphir Munk uint32_t nb_iterations = rgxc->nb_iterations;
3936b99ba8dSOphir Munk uint8_t nb_max_matches = rgxc->nb_max_matches;
3946b99ba8dSOphir Munk uint32_t nb_qps = rgxc->nb_qps;
3956b99ba8dSOphir Munk uint16_t qp_id_base = rgxc->qp_id_base;
3966b99ba8dSOphir Munk char *data_buf = rgxc->data_buf;
3976b99ba8dSOphir Munk long data_len = rgxc->data_len;
3986b99ba8dSOphir Munk long job_len = rgxc->job_len;
399*b6aceadaSGerry Gribbon uint32_t match_mode = rgxc->match_mode;
400c1d1b94eSGerry Gribbon long remainder;
401c1d1b94eSGerry Gribbon long act_job_len = 0;
402c1d1b94eSGerry Gribbon bool last_job = false;
403de06137cSYuval Avnery char *buf = NULL;
404de06137cSYuval Avnery uint32_t actual_jobs = 0;
405de06137cSYuval Avnery uint32_t i;
406c1d1b94eSGerry Gribbon uint32_t job_id;
4074545bd00SOphir Munk uint16_t qp_id;
408de06137cSYuval Avnery uint16_t dev_id = 0;
409de06137cSYuval Avnery uint8_t nb_matches;
410392ac62bSGerry Gribbon uint16_t rsp_flags = 0;
411de06137cSYuval Avnery struct rte_regexdev_match *match;
4124545bd00SOphir Munk long pos;
413de06137cSYuval Avnery unsigned long d_ind = 0;
414de06137cSYuval Avnery struct rte_mbuf_ext_shared_info shinfo;
415de06137cSYuval Avnery int res = 0;
416e5e518edSOphir Munk long double time;
4172d1fb3f2SOphir Munk struct rte_mempool *mbuf_mp;
4184545bd00SOphir Munk struct qp_params *qp;
4194545bd00SOphir Munk struct qp_params *qps = NULL;
4204545bd00SOphir Munk bool update;
4214545bd00SOphir Munk uint16_t qps_used = 0;
4226b99ba8dSOphir Munk char mbuf_pool[16];
423de06137cSYuval Avnery
424de06137cSYuval Avnery shinfo.free_cb = extbuf_free_cb;
4256b99ba8dSOphir Munk snprintf(mbuf_pool,
4266b99ba8dSOphir Munk sizeof(mbuf_pool),
4276b99ba8dSOphir Munk "mbuf_pool_%2u", qp_id_base);
428cace2d7eSSuanming Mou mbuf_mp = rte_pktmbuf_pool_create(mbuf_pool,
429cace2d7eSSuanming Mou rte_align32pow2(nb_jobs * nb_qps * nb_segs),
430cace2d7eSSuanming Mou 0, 0, (nb_segs == 1) ? MBUF_SIZE :
431a442ca2dSRaslan Darawsheh (rte_align32pow2(job_len + (data_len % nb_jobs)) /
432a442ca2dSRaslan Darawsheh nb_segs + RTE_PKTMBUF_HEADROOM),
433cace2d7eSSuanming Mou rte_socket_id());
4342d1fb3f2SOphir Munk if (mbuf_mp == NULL) {
4352d1fb3f2SOphir Munk printf("Error, can't create memory pool\n");
4362d1fb3f2SOphir Munk return -ENOMEM;
4372d1fb3f2SOphir Munk }
4382d1fb3f2SOphir Munk
4394545bd00SOphir Munk qps = rte_malloc(NULL, sizeof(*qps) * nb_qps, 0);
4404545bd00SOphir Munk if (!qps) {
4414545bd00SOphir Munk printf("Error, can't allocate memory for QPs\n");
4424545bd00SOphir Munk res = -ENOMEM;
4434545bd00SOphir Munk goto end;
444de06137cSYuval Avnery }
445de06137cSYuval Avnery
4464545bd00SOphir Munk for (qp_id = 0; qp_id < nb_qps; qp_id++) {
4474545bd00SOphir Munk struct rte_regex_ops **ops;
4484545bd00SOphir Munk struct job_ctx *jobs_ctx;
4494545bd00SOphir Munk
4504545bd00SOphir Munk qps_used++;
4514545bd00SOphir Munk qp = &qps[qp_id];
4524545bd00SOphir Munk qp->jobs_ctx = NULL;
4534545bd00SOphir Munk qp->buf = NULL;
4544545bd00SOphir Munk qp->ops = ops = rte_malloc(NULL, sizeof(*ops) * nb_jobs, 0);
4554545bd00SOphir Munk if (!ops) {
4564545bd00SOphir Munk printf("Error, can't allocate memory for ops.\n");
4574545bd00SOphir Munk res = -ENOMEM;
4584545bd00SOphir Munk goto end;
4594545bd00SOphir Munk }
4604545bd00SOphir Munk
4614545bd00SOphir Munk qp->jobs_ctx = jobs_ctx =
4624545bd00SOphir Munk rte_malloc(NULL, sizeof(*jobs_ctx) * nb_jobs, 0);
46330cf1713SGuy Kaneti if (!jobs_ctx) {
46430cf1713SGuy Kaneti printf("Error, can't allocate memory for jobs_ctx.\n");
4654545bd00SOphir Munk res = -ENOMEM;
4664545bd00SOphir Munk goto end;
46730cf1713SGuy Kaneti }
46830cf1713SGuy Kaneti
469f5cffb7eSOphir Munk if (clone_buf(data_buf, &buf, data_len)) {
470f5cffb7eSOphir Munk printf("Error, can't clone buf.\n");
471de06137cSYuval Avnery res = -EXIT_FAILURE;
472de06137cSYuval Avnery goto end;
473de06137cSYuval Avnery }
474de06137cSYuval Avnery
475de06137cSYuval Avnery /* Assign each mbuf with the data to handle. */
4764545bd00SOphir Munk actual_jobs = 0;
4774545bd00SOphir Munk pos = 0;
478c1d1b94eSGerry Gribbon remainder = data_len % nb_jobs;
479c1d1b94eSGerry Gribbon
480cace2d7eSSuanming Mou /* Allocate the jobs and assign each job with an mbuf. */
481f5cffb7eSOphir Munk for (i = 0; (pos < data_len) && (i < nb_jobs) ; i++) {
482c1d1b94eSGerry Gribbon act_job_len = RTE_MIN(job_len, data_len - pos);
483c1d1b94eSGerry Gribbon
484c1d1b94eSGerry Gribbon if (i == (nb_jobs - 1)) {
485c1d1b94eSGerry Gribbon last_job = true;
486c1d1b94eSGerry Gribbon act_job_len += remainder;
487c1d1b94eSGerry Gribbon }
488cace2d7eSSuanming Mou
489cace2d7eSSuanming Mou ops[i] = rte_malloc(NULL, sizeof(*ops[0]) +
490cace2d7eSSuanming Mou nb_max_matches *
491cace2d7eSSuanming Mou sizeof(struct rte_regexdev_match), 0);
492cace2d7eSSuanming Mou if (!ops[i]) {
493cace2d7eSSuanming Mou printf("Error, can't allocate "
494cace2d7eSSuanming Mou "memory for op.\n");
495cace2d7eSSuanming Mou res = -ENOMEM;
496cace2d7eSSuanming Mou goto end;
497cace2d7eSSuanming Mou }
498cace2d7eSSuanming Mou if (nb_segs > 1) {
499cace2d7eSSuanming Mou ops[i]->mbuf = regex_create_segmented_mbuf
500cace2d7eSSuanming Mou (mbuf_mp, act_job_len,
501cace2d7eSSuanming Mou nb_segs, &buf[pos]);
502cace2d7eSSuanming Mou } else {
503cace2d7eSSuanming Mou ops[i]->mbuf = rte_pktmbuf_alloc(mbuf_mp);
504cace2d7eSSuanming Mou if (ops[i]->mbuf) {
505cace2d7eSSuanming Mou rte_pktmbuf_attach_extbuf(ops[i]->mbuf,
506cace2d7eSSuanming Mou &buf[pos], 0, act_job_len, &shinfo);
507c1d1b94eSGerry Gribbon
508c1d1b94eSGerry Gribbon if (!last_job)
509de06137cSYuval Avnery ops[i]->mbuf->data_len = job_len;
510c1d1b94eSGerry Gribbon else
511c1d1b94eSGerry Gribbon ops[i]->mbuf->data_len = act_job_len;
512c1d1b94eSGerry Gribbon
513de06137cSYuval Avnery ops[i]->mbuf->pkt_len = act_job_len;
514cace2d7eSSuanming Mou }
515cace2d7eSSuanming Mou }
516cace2d7eSSuanming Mou if (!ops[i]->mbuf) {
517cace2d7eSSuanming Mou printf("Error, can't add mbuf.\n");
518cace2d7eSSuanming Mou res = -ENOMEM;
519cace2d7eSSuanming Mou goto end;
520cace2d7eSSuanming Mou }
521cace2d7eSSuanming Mou
522cace2d7eSSuanming Mou jobs_ctx[i].mbuf = ops[i]->mbuf;
523de06137cSYuval Avnery ops[i]->user_id = i;
524de06137cSYuval Avnery ops[i]->group_id0 = 1;
525*b6aceadaSGerry Gribbon switch (match_mode) {
526*b6aceadaSGerry Gribbon case 0:
527*b6aceadaSGerry Gribbon /* Nothing to set in req_flags */
528*b6aceadaSGerry Gribbon break;
529*b6aceadaSGerry Gribbon case 1:
530*b6aceadaSGerry Gribbon ops[i]->req_flags |= RTE_REGEX_OPS_REQ_MATCH_HIGH_PRIORITY_F;
531*b6aceadaSGerry Gribbon break;
532*b6aceadaSGerry Gribbon case 2:
533*b6aceadaSGerry Gribbon ops[i]->req_flags |= RTE_REGEX_OPS_REQ_STOP_ON_MATCH_F;
534*b6aceadaSGerry Gribbon break;
535*b6aceadaSGerry Gribbon default:
536*b6aceadaSGerry Gribbon rte_exit(EXIT_FAILURE,
537*b6aceadaSGerry Gribbon "Invalid match mode value\n");
538*b6aceadaSGerry Gribbon break;
539*b6aceadaSGerry Gribbon }
540de06137cSYuval Avnery pos += act_job_len;
541de06137cSYuval Avnery actual_jobs++;
542de06137cSYuval Avnery }
543de06137cSYuval Avnery
5444545bd00SOphir Munk qp->buf = buf;
5454545bd00SOphir Munk qp->total_matches = 0;
5466e3c6bd6SOphir Munk qp->start = 0;
547e5e518edSOphir Munk qp->cycles = 0;
5484545bd00SOphir Munk }
5494545bd00SOphir Munk
550de06137cSYuval Avnery for (i = 0; i < nb_iterations; i++) {
5514545bd00SOphir Munk for (qp_id = 0; qp_id < nb_qps; qp_id++) {
5524545bd00SOphir Munk qp = &qps[qp_id];
5534545bd00SOphir Munk qp->total_enqueue = 0;
5544545bd00SOphir Munk qp->total_dequeue = 0;
555c1d1b94eSGerry Gribbon /* Re-set user id after dequeue to match data in mbuf. */
556c1d1b94eSGerry Gribbon for (job_id = 0 ; job_id < nb_jobs; job_id++)
557c1d1b94eSGerry Gribbon qp->ops[job_id]->user_id = job_id;
558de06137cSYuval Avnery }
5594545bd00SOphir Munk do {
5604545bd00SOphir Munk update = false;
5614545bd00SOphir Munk for (qp_id = 0; qp_id < nb_qps; qp_id++) {
5624545bd00SOphir Munk qp = &qps[qp_id];
5634545bd00SOphir Munk if (qp->total_dequeue < actual_jobs) {
564e5e518edSOphir Munk qp->start = rte_rdtsc_precise();
5654545bd00SOphir Munk struct rte_regex_ops **
5664545bd00SOphir Munk cur_ops_to_enqueue = qp->ops +
5674545bd00SOphir Munk qp->total_enqueue;
5684545bd00SOphir Munk
5694545bd00SOphir Munk if (actual_jobs - qp->total_enqueue)
5704545bd00SOphir Munk qp->total_enqueue +=
5714545bd00SOphir Munk rte_regexdev_enqueue_burst
5724545bd00SOphir Munk (dev_id,
5736b99ba8dSOphir Munk qp_id_base + qp_id,
5744545bd00SOphir Munk cur_ops_to_enqueue,
5754545bd00SOphir Munk actual_jobs -
5764545bd00SOphir Munk qp->total_enqueue);
5774545bd00SOphir Munk }
5784545bd00SOphir Munk }
5794545bd00SOphir Munk for (qp_id = 0; qp_id < nb_qps; qp_id++) {
5804545bd00SOphir Munk qp = &qps[qp_id];
5814545bd00SOphir Munk if (qp->total_dequeue < actual_jobs) {
5824545bd00SOphir Munk struct rte_regex_ops **
5834545bd00SOphir Munk cur_ops_to_dequeue = qp->ops +
5844545bd00SOphir Munk qp->total_dequeue;
5854545bd00SOphir Munk
5864545bd00SOphir Munk qp->total_dequeue +=
5874545bd00SOphir Munk rte_regexdev_dequeue_burst
5884545bd00SOphir Munk (dev_id,
5896b99ba8dSOphir Munk qp_id_base + qp_id,
5904545bd00SOphir Munk cur_ops_to_dequeue,
5914545bd00SOphir Munk qp->total_enqueue -
5924545bd00SOphir Munk qp->total_dequeue);
593e5e518edSOphir Munk qp->cycles +=
594e5e518edSOphir Munk (rte_rdtsc_precise() - qp->start);
5954545bd00SOphir Munk update = true;
5964545bd00SOphir Munk }
5974545bd00SOphir Munk }
5984545bd00SOphir Munk } while (update);
599de06137cSYuval Avnery }
6006e3c6bd6SOphir Munk for (qp_id = 0; qp_id < nb_qps; qp_id++) {
6016e3c6bd6SOphir Munk qp = &qps[qp_id];
602e5e518edSOphir Munk time = (long double)qp->cycles / rte_get_timer_hz();
603c1d1b94eSGerry Gribbon printf("Core=%u QP=%u Job=%ld Bytes Last Job=%ld Bytes Time=%Lf sec Perf=%Lf "
604e5e518edSOphir Munk "Gbps\n", rte_lcore_id(), qp_id + qp_id_base,
605c1d1b94eSGerry Gribbon job_len, act_job_len, time,
606c1d1b94eSGerry Gribbon (((double)data_len * nb_iterations * 8)
607e5e518edSOphir Munk / time) / 1000000000.0);
6086e3c6bd6SOphir Munk }
609de06137cSYuval Avnery
6106b99ba8dSOphir Munk if (rgxc->perf_mode)
6114545bd00SOphir Munk goto end;
6124545bd00SOphir Munk for (qp_id = 0; qp_id < nb_qps; qp_id++) {
6136e3c6bd6SOphir Munk printf("\n############ Core=%u QP=%u ############\n",
6146e3c6bd6SOphir Munk rte_lcore_id(), qp_id + qp_id_base);
6154545bd00SOphir Munk qp = &qps[qp_id];
616de06137cSYuval Avnery /* Log results per job. */
6174545bd00SOphir Munk for (d_ind = 0; d_ind < qp->total_dequeue; d_ind++) {
6184545bd00SOphir Munk nb_matches = qp->ops[d_ind % actual_jobs]->nb_matches;
619392ac62bSGerry Gribbon rsp_flags = qp->ops[d_ind % actual_jobs]->rsp_flags;
620392ac62bSGerry Gribbon printf("Job id %"PRIu64" number of matches = %d, rsp flags = 0x%x\n",
621392ac62bSGerry Gribbon qp->ops[d_ind]->user_id, nb_matches, rsp_flags);
6224545bd00SOphir Munk qp->total_matches += nb_matches;
6234545bd00SOphir Munk match = qp->ops[d_ind % actual_jobs]->matches;
624de06137cSYuval Avnery for (i = 0; i < nb_matches; i++) {
6254545bd00SOphir Munk printf("match %d, rule = %d, "
6264545bd00SOphir Munk "start = %d,len = %d\n",
627de06137cSYuval Avnery i, match->rule_id, match->start_offset,
628de06137cSYuval Avnery match->len);
629de06137cSYuval Avnery match++;
630de06137cSYuval Avnery }
631de06137cSYuval Avnery }
6324545bd00SOphir Munk printf("Total matches = %d\n", qp->total_matches);
633de06137cSYuval Avnery printf("All Matches:\n");
634de06137cSYuval Avnery /* Log absolute results. */
6354545bd00SOphir Munk for (d_ind = 0; d_ind < qp->total_dequeue; d_ind++) {
6364545bd00SOphir Munk nb_matches = qp->ops[d_ind % actual_jobs]->nb_matches;
6374545bd00SOphir Munk qp->total_matches += nb_matches;
6384545bd00SOphir Munk match = qp->ops[d_ind % actual_jobs]->matches;
639de06137cSYuval Avnery for (i = 0; i < nb_matches; i++) {
640c1d1b94eSGerry Gribbon printf("start = %d, len = %d, rule = %d\n",
6414545bd00SOphir Munk match->start_offset +
642c1d1b94eSGerry Gribbon (int)(qp->ops[d_ind % actual_jobs]->user_id * job_len),
643de06137cSYuval Avnery match->len, match->rule_id);
644de06137cSYuval Avnery match++;
645de06137cSYuval Avnery }
646de06137cSYuval Avnery }
647de06137cSYuval Avnery }
648de06137cSYuval Avnery end:
6494545bd00SOphir Munk for (qp_id = 0; qp_id < qps_used; qp_id++) {
6504545bd00SOphir Munk qp = &qps[qp_id];
6514545bd00SOphir Munk for (i = 0; i < actual_jobs && qp->ops; i++)
6524545bd00SOphir Munk rte_free(qp->ops[i]);
6534545bd00SOphir Munk rte_free(qp->ops);
6544545bd00SOphir Munk qp->ops = NULL;
6554545bd00SOphir Munk for (i = 0; i < actual_jobs && qp->jobs_ctx; i++)
6564545bd00SOphir Munk rte_pktmbuf_free(qp->jobs_ctx[i].mbuf);
6574545bd00SOphir Munk rte_free(qp->jobs_ctx);
6584545bd00SOphir Munk qp->jobs_ctx = NULL;
6594545bd00SOphir Munk rte_free(qp->buf);
6604545bd00SOphir Munk qp->buf = NULL;
661de06137cSYuval Avnery }
6622d1fb3f2SOphir Munk rte_mempool_free(mbuf_mp);
6634545bd00SOphir Munk rte_free(qps);
664de06137cSYuval Avnery return res;
665de06137cSYuval Avnery }
666de06137cSYuval Avnery
6676b99ba8dSOphir Munk static int
distribute_qps_to_lcores(uint32_t nb_cores,uint32_t nb_qps,struct qps_per_lcore ** qpl)6686b99ba8dSOphir Munk distribute_qps_to_lcores(uint32_t nb_cores, uint32_t nb_qps,
6696b99ba8dSOphir Munk struct qps_per_lcore **qpl)
6706b99ba8dSOphir Munk {
6716b99ba8dSOphir Munk int socket;
6726b99ba8dSOphir Munk unsigned lcore_id;
6736b99ba8dSOphir Munk uint32_t i;
6746b99ba8dSOphir Munk uint16_t min_qp_id;
6756b99ba8dSOphir Munk uint16_t max_qp_id;
6766b99ba8dSOphir Munk struct qps_per_lcore *qps_per_lcore;
6776b99ba8dSOphir Munk uint32_t detected_lcores;
6786b99ba8dSOphir Munk
6796b99ba8dSOphir Munk if (nb_qps < nb_cores) {
6806b99ba8dSOphir Munk nb_cores = nb_qps;
6816b99ba8dSOphir Munk printf("Reducing number of cores to number of QPs (%u)\n",
6826b99ba8dSOphir Munk nb_cores);
6836b99ba8dSOphir Munk }
6846b99ba8dSOphir Munk /* Allocate qps_per_lcore array */
6856b99ba8dSOphir Munk qps_per_lcore =
6866b99ba8dSOphir Munk rte_malloc(NULL, sizeof(*qps_per_lcore) * nb_cores, 0);
6876b99ba8dSOphir Munk if (!qps_per_lcore)
6886b99ba8dSOphir Munk rte_exit(EXIT_FAILURE, "Failed to create qps_per_lcore array\n");
6896b99ba8dSOphir Munk *qpl = qps_per_lcore;
6906b99ba8dSOphir Munk detected_lcores = 0;
6916b99ba8dSOphir Munk min_qp_id = 0;
6926b99ba8dSOphir Munk
6936b99ba8dSOphir Munk RTE_LCORE_FOREACH_WORKER(lcore_id) {
6946b99ba8dSOphir Munk if (detected_lcores >= nb_cores)
6956b99ba8dSOphir Munk break;
6966b99ba8dSOphir Munk qps_per_lcore[detected_lcores].lcore_id = lcore_id;
6976b99ba8dSOphir Munk socket = rte_lcore_to_socket_id(lcore_id);
6986b99ba8dSOphir Munk if (socket == SOCKET_ID_ANY)
6996b99ba8dSOphir Munk socket = 0;
7006b99ba8dSOphir Munk qps_per_lcore[detected_lcores].socket = socket;
7016b99ba8dSOphir Munk qps_per_lcore[detected_lcores].qp_id_base = min_qp_id;
7026b99ba8dSOphir Munk max_qp_id = min_qp_id + nb_qps / nb_cores - 1;
7036b99ba8dSOphir Munk if (nb_qps % nb_cores > detected_lcores)
7046b99ba8dSOphir Munk max_qp_id++;
7056b99ba8dSOphir Munk qps_per_lcore[detected_lcores].nb_qps = max_qp_id -
7066b99ba8dSOphir Munk min_qp_id + 1;
7076b99ba8dSOphir Munk min_qp_id = max_qp_id + 1;
7086b99ba8dSOphir Munk detected_lcores++;
7096b99ba8dSOphir Munk }
7106b99ba8dSOphir Munk if (detected_lcores != nb_cores)
7116b99ba8dSOphir Munk return -1;
7126b99ba8dSOphir Munk
7136b99ba8dSOphir Munk for (i = 0; i < detected_lcores; i++) {
7146b99ba8dSOphir Munk printf("===> Core %d: allocated queues: ",
7156b99ba8dSOphir Munk qps_per_lcore[i].lcore_id);
7166b99ba8dSOphir Munk min_qp_id = qps_per_lcore[i].qp_id_base;
7176b99ba8dSOphir Munk max_qp_id =
7186b99ba8dSOphir Munk qps_per_lcore[i].qp_id_base + qps_per_lcore[i].nb_qps;
7196b99ba8dSOphir Munk while (min_qp_id < max_qp_id) {
7206b99ba8dSOphir Munk printf("%u ", min_qp_id);
7216b99ba8dSOphir Munk min_qp_id++;
7226b99ba8dSOphir Munk }
7236b99ba8dSOphir Munk printf("\n");
7246b99ba8dSOphir Munk }
7256b99ba8dSOphir Munk return 0;
7266b99ba8dSOphir Munk }
7276b99ba8dSOphir Munk
728de06137cSYuval Avnery int
main(int argc,char ** argv)729de06137cSYuval Avnery main(int argc, char **argv)
730de06137cSYuval Avnery {
731de06137cSYuval Avnery char rules_file[MAX_FILE_NAME];
732de06137cSYuval Avnery char data_file[MAX_FILE_NAME];
733de06137cSYuval Avnery uint32_t nb_jobs = 0;
734de06137cSYuval Avnery bool perf_mode = 0;
735de06137cSYuval Avnery uint32_t nb_iterations = 0;
736de06137cSYuval Avnery int ret;
7374545bd00SOphir Munk uint16_t nb_max_payload = 0;
7384545bd00SOphir Munk uint8_t nb_max_matches = 0;
7394545bd00SOphir Munk uint32_t nb_qps = 1;
740f5cffb7eSOphir Munk char *data_buf;
741f5cffb7eSOphir Munk long data_len;
742f5cffb7eSOphir Munk long job_len;
743cace2d7eSSuanming Mou uint32_t nb_lcores = 1, nb_segs = 1;
744*b6aceadaSGerry Gribbon uint32_t match_mode = 0;
7456b99ba8dSOphir Munk struct regex_conf *rgxc;
7466b99ba8dSOphir Munk uint32_t i;
7476b99ba8dSOphir Munk struct qps_per_lcore *qps_per_lcore;
748de06137cSYuval Avnery
7494545bd00SOphir Munk /* Init EAL. */
750de06137cSYuval Avnery ret = rte_eal_init(argc, argv);
751de06137cSYuval Avnery if (ret < 0)
752de06137cSYuval Avnery rte_exit(EXIT_FAILURE, "EAL init failed\n");
753de06137cSYuval Avnery argc -= ret;
754de06137cSYuval Avnery argv += ret;
755de06137cSYuval Avnery if (argc > 1)
756de06137cSYuval Avnery args_parse(argc, argv, rules_file, data_file, &nb_jobs,
7576b99ba8dSOphir Munk &perf_mode, &nb_iterations, &nb_qps,
758*b6aceadaSGerry Gribbon &nb_lcores, &nb_segs, &match_mode);
759de06137cSYuval Avnery
7604545bd00SOphir Munk if (nb_qps == 0)
7614545bd00SOphir Munk rte_exit(EXIT_FAILURE, "Number of QPs must be greater than 0\n");
7626b99ba8dSOphir Munk if (nb_lcores == 0)
7636b99ba8dSOphir Munk rte_exit(EXIT_FAILURE, "Number of lcores must be greater than 0\n");
7641afdf9edSThierry Herbelot if (nb_jobs == 0)
7651afdf9edSThierry Herbelot rte_exit(EXIT_FAILURE, "Number of jobs must be greater than 0\n");
7666b99ba8dSOphir Munk if (distribute_qps_to_lcores(nb_lcores, nb_qps, &qps_per_lcore) < 0)
7676b99ba8dSOphir Munk rte_exit(EXIT_FAILURE, "Failed to distribute queues to lcores!\n");
7684545bd00SOphir Munk ret = init_port(&nb_max_payload, rules_file,
7694545bd00SOphir Munk &nb_max_matches, nb_qps);
770de06137cSYuval Avnery if (ret < 0)
771de06137cSYuval Avnery rte_exit(EXIT_FAILURE, "init port failed\n");
772f5cffb7eSOphir Munk
773f5cffb7eSOphir Munk data_len = read_file(data_file, &data_buf);
774f5cffb7eSOphir Munk if (data_len <= 0)
775f5cffb7eSOphir Munk rte_exit(EXIT_FAILURE, "Error, can't read file, or file is empty.\n");
776f5cffb7eSOphir Munk
777f5cffb7eSOphir Munk job_len = data_len / nb_jobs;
778f5cffb7eSOphir Munk if (job_len == 0)
779f5cffb7eSOphir Munk rte_exit(EXIT_FAILURE, "Error, To many jobs, for the given input.\n");
780f5cffb7eSOphir Munk
781f5cffb7eSOphir Munk if (job_len > nb_max_payload)
782f5cffb7eSOphir Munk rte_exit(EXIT_FAILURE, "Error, not enough jobs to cover input.\n");
783f5cffb7eSOphir Munk
7846b99ba8dSOphir Munk rgxc = rte_malloc(NULL, sizeof(*rgxc) * nb_lcores, 0);
7856b99ba8dSOphir Munk if (!rgxc)
7866b99ba8dSOphir Munk rte_exit(EXIT_FAILURE, "Failed to create Regex Conf\n");
7876b99ba8dSOphir Munk for (i = 0; i < nb_lcores; i++) {
7886b99ba8dSOphir Munk rgxc[i] = (struct regex_conf){
7896b99ba8dSOphir Munk .nb_jobs = nb_jobs,
790cace2d7eSSuanming Mou .nb_segs = nb_segs,
7916b99ba8dSOphir Munk .perf_mode = perf_mode,
7926b99ba8dSOphir Munk .nb_iterations = nb_iterations,
7936b99ba8dSOphir Munk .nb_max_matches = nb_max_matches,
7946b99ba8dSOphir Munk .nb_qps = qps_per_lcore[i].nb_qps,
7956b99ba8dSOphir Munk .qp_id_base = qps_per_lcore[i].qp_id_base,
7966b99ba8dSOphir Munk .data_buf = data_buf,
7976b99ba8dSOphir Munk .data_len = data_len,
7986b99ba8dSOphir Munk .job_len = job_len,
799*b6aceadaSGerry Gribbon .match_mode = match_mode,
8006b99ba8dSOphir Munk };
8016b99ba8dSOphir Munk rte_eal_remote_launch(run_regex, &rgxc[i],
8026b99ba8dSOphir Munk qps_per_lcore[i].lcore_id);
803de06137cSYuval Avnery }
8046b99ba8dSOphir Munk rte_eal_mp_wait_lcore();
805f5cffb7eSOphir Munk rte_free(data_buf);
8066b99ba8dSOphir Munk rte_free(rgxc);
8076b99ba8dSOphir Munk rte_free(qps_per_lcore);
808de06137cSYuval Avnery return EXIT_SUCCESS;
809de06137cSYuval Avnery }
810