xref: /dpdk/drivers/regex/mlx5/mlx5_regex_fastpath.c (revision 5f41b66d12cda394c919777ae9b80257e97b5018)
1*5f41b66dSYuval Avnery /* SPDX-License-Identifier: BSD-3-Clause
2*5f41b66dSYuval Avnery  * Copyright 2020 Mellanox Technologies, Ltd
3*5f41b66dSYuval Avnery  */
4*5f41b66dSYuval Avnery 
5*5f41b66dSYuval Avnery #include <unistd.h>
6*5f41b66dSYuval Avnery #include <sys/mman.h>
7*5f41b66dSYuval Avnery 
8*5f41b66dSYuval Avnery #include <rte_malloc.h>
9*5f41b66dSYuval Avnery #include <rte_log.h>
10*5f41b66dSYuval Avnery #include <rte_errno.h>
11*5f41b66dSYuval Avnery #include <rte_bus_pci.h>
12*5f41b66dSYuval Avnery #include <rte_pci.h>
13*5f41b66dSYuval Avnery #include <rte_regexdev_driver.h>
14*5f41b66dSYuval Avnery #include <rte_mbuf.h>
15*5f41b66dSYuval Avnery 
16*5f41b66dSYuval Avnery #include <infiniband/mlx5dv.h>
17*5f41b66dSYuval Avnery #include <mlx5_glue.h>
18*5f41b66dSYuval Avnery #include <mlx5_common.h>
19*5f41b66dSYuval Avnery #include <mlx5_prm.h>
20*5f41b66dSYuval Avnery #include <strings.h>
21*5f41b66dSYuval Avnery 
22*5f41b66dSYuval Avnery #include "mlx5_regex_utils.h"
23*5f41b66dSYuval Avnery #include "mlx5_rxp.h"
24*5f41b66dSYuval Avnery #include "mlx5_regex.h"
25*5f41b66dSYuval Avnery 
26*5f41b66dSYuval Avnery #define MLX5_REGEX_METADATA_SIZE 64
27*5f41b66dSYuval Avnery #define MLX5_REGEX_MAX_INPUT (1 << 14)
28*5f41b66dSYuval Avnery #define MLX5_REGEX_MAX_OUTPUT (1 << 11)
29*5f41b66dSYuval Avnery 
30*5f41b66dSYuval Avnery #define MLX5_REGEX_WQE_METADATA_OFFSET 16
31*5f41b66dSYuval Avnery #define MLX5_REGEX_WQE_GATHER_OFFSET 32
32*5f41b66dSYuval Avnery #define MLX5_REGEX_WQE_SCATTER_OFFSET 48
33*5f41b66dSYuval Avnery 
34*5f41b66dSYuval Avnery static inline uint32_t
35*5f41b66dSYuval Avnery sq_size_get(struct mlx5_regex_sq *sq)
36*5f41b66dSYuval Avnery {
37*5f41b66dSYuval Avnery 	return (1U << sq->log_nb_desc);
38*5f41b66dSYuval Avnery }
39*5f41b66dSYuval Avnery 
40*5f41b66dSYuval Avnery struct mlx5_regex_job {
41*5f41b66dSYuval Avnery 	uint64_t user_id;
42*5f41b66dSYuval Avnery 	uint8_t *input;
43*5f41b66dSYuval Avnery 	volatile uint8_t *output;
44*5f41b66dSYuval Avnery 	volatile uint8_t *metadata;
45*5f41b66dSYuval Avnery } __rte_cached_aligned;
46*5f41b66dSYuval Avnery 
47*5f41b66dSYuval Avnery static inline void
48*5f41b66dSYuval Avnery set_data_seg(struct mlx5_wqe_data_seg *seg,
49*5f41b66dSYuval Avnery 	     uint32_t length, uint32_t lkey,
50*5f41b66dSYuval Avnery 	     uintptr_t address)
51*5f41b66dSYuval Avnery {
52*5f41b66dSYuval Avnery 	seg->byte_count = rte_cpu_to_be_32(length);
53*5f41b66dSYuval Avnery 	seg->lkey = rte_cpu_to_be_32(lkey);
54*5f41b66dSYuval Avnery 	seg->addr = rte_cpu_to_be_64(address);
55*5f41b66dSYuval Avnery }
56*5f41b66dSYuval Avnery 
57*5f41b66dSYuval Avnery static inline void
58*5f41b66dSYuval Avnery set_metadata_seg(struct mlx5_wqe_metadata_seg *seg,
59*5f41b66dSYuval Avnery 		 uint32_t mmo_control_31_0, uint32_t lkey,
60*5f41b66dSYuval Avnery 		 uintptr_t address)
61*5f41b66dSYuval Avnery {
62*5f41b66dSYuval Avnery 	seg->mmo_control_31_0 = htobe32(mmo_control_31_0);
63*5f41b66dSYuval Avnery 	seg->lkey = rte_cpu_to_be_32(lkey);
64*5f41b66dSYuval Avnery 	seg->addr = rte_cpu_to_be_64(address);
65*5f41b66dSYuval Avnery }
66*5f41b66dSYuval Avnery 
67*5f41b66dSYuval Avnery static void
68*5f41b66dSYuval Avnery setup_sqs(struct mlx5_regex_qp *queue)
69*5f41b66dSYuval Avnery {
70*5f41b66dSYuval Avnery 	size_t sqid, entry;
71*5f41b66dSYuval Avnery 	uint32_t job_id;
72*5f41b66dSYuval Avnery 	for (sqid = 0; sqid < queue->nb_obj; sqid++) {
73*5f41b66dSYuval Avnery 		struct mlx5_regex_sq *sq = &queue->sqs[sqid];
74*5f41b66dSYuval Avnery 		uint8_t *wqe = (uint8_t *)sq->wqe;
75*5f41b66dSYuval Avnery 		for (entry = 0 ; entry < sq_size_get(sq); entry++) {
76*5f41b66dSYuval Avnery 			job_id = sqid * sq_size_get(sq) + entry;
77*5f41b66dSYuval Avnery 			struct mlx5_regex_job *job = &queue->jobs[job_id];
78*5f41b66dSYuval Avnery 
79*5f41b66dSYuval Avnery 			set_metadata_seg((struct mlx5_wqe_metadata_seg *)
80*5f41b66dSYuval Avnery 					 (wqe + MLX5_REGEX_WQE_METADATA_OFFSET),
81*5f41b66dSYuval Avnery 					 0, queue->metadata->lkey,
82*5f41b66dSYuval Avnery 					 (uintptr_t)job->metadata);
83*5f41b66dSYuval Avnery 			set_data_seg((struct mlx5_wqe_data_seg *)
84*5f41b66dSYuval Avnery 				     (wqe + MLX5_REGEX_WQE_GATHER_OFFSET),
85*5f41b66dSYuval Avnery 				     0, queue->inputs->lkey,
86*5f41b66dSYuval Avnery 				     (uintptr_t)job->input);
87*5f41b66dSYuval Avnery 			set_data_seg((struct mlx5_wqe_data_seg *)
88*5f41b66dSYuval Avnery 				     (wqe + MLX5_REGEX_WQE_SCATTER_OFFSET),
89*5f41b66dSYuval Avnery 				     MLX5_REGEX_MAX_OUTPUT,
90*5f41b66dSYuval Avnery 				     queue->outputs->lkey,
91*5f41b66dSYuval Avnery 				     (uintptr_t)job->output);
92*5f41b66dSYuval Avnery 			wqe += 64;
93*5f41b66dSYuval Avnery 		}
94*5f41b66dSYuval Avnery 		queue->free_sqs |= 1 << sqid;
95*5f41b66dSYuval Avnery 	}
96*5f41b66dSYuval Avnery }
97*5f41b66dSYuval Avnery 
98*5f41b66dSYuval Avnery static int
99*5f41b66dSYuval Avnery setup_buffers(struct mlx5_regex_qp *qp, struct ibv_pd *pd)
100*5f41b66dSYuval Avnery {
101*5f41b66dSYuval Avnery 	uint32_t i;
102*5f41b66dSYuval Avnery 	int err;
103*5f41b66dSYuval Avnery 
104*5f41b66dSYuval Avnery 	void *ptr = rte_calloc(__func__, qp->nb_desc,
105*5f41b66dSYuval Avnery 			       MLX5_REGEX_METADATA_SIZE,
106*5f41b66dSYuval Avnery 			       MLX5_REGEX_METADATA_SIZE);
107*5f41b66dSYuval Avnery 	if (!ptr)
108*5f41b66dSYuval Avnery 		return -ENOMEM;
109*5f41b66dSYuval Avnery 
110*5f41b66dSYuval Avnery 	qp->metadata = mlx5_glue->reg_mr(pd, ptr,
111*5f41b66dSYuval Avnery 					 MLX5_REGEX_METADATA_SIZE*qp->nb_desc,
112*5f41b66dSYuval Avnery 					 IBV_ACCESS_LOCAL_WRITE);
113*5f41b66dSYuval Avnery 	if (!qp->metadata) {
114*5f41b66dSYuval Avnery 		rte_free(ptr);
115*5f41b66dSYuval Avnery 		return -EINVAL;
116*5f41b66dSYuval Avnery 	}
117*5f41b66dSYuval Avnery 	ptr = rte_calloc(__func__, qp->nb_desc,
118*5f41b66dSYuval Avnery 			 MLX5_REGEX_MAX_INPUT,
119*5f41b66dSYuval Avnery 			 MLX5_REGEX_MAX_INPUT);
120*5f41b66dSYuval Avnery 
121*5f41b66dSYuval Avnery 	if (!ptr) {
122*5f41b66dSYuval Avnery 		err = -ENOMEM;
123*5f41b66dSYuval Avnery 		goto err_input;
124*5f41b66dSYuval Avnery 	}
125*5f41b66dSYuval Avnery 	qp->inputs = mlx5_glue->reg_mr(pd, ptr,
126*5f41b66dSYuval Avnery 				       MLX5_REGEX_MAX_INPUT*qp->nb_desc,
127*5f41b66dSYuval Avnery 				       IBV_ACCESS_LOCAL_WRITE);
128*5f41b66dSYuval Avnery 	if (!qp->inputs) {
129*5f41b66dSYuval Avnery 		rte_free(ptr);
130*5f41b66dSYuval Avnery 		err = -EINVAL;
131*5f41b66dSYuval Avnery 		goto err_input;
132*5f41b66dSYuval Avnery 	}
133*5f41b66dSYuval Avnery 
134*5f41b66dSYuval Avnery 	ptr = rte_calloc(__func__, qp->nb_desc,
135*5f41b66dSYuval Avnery 			 MLX5_REGEX_MAX_OUTPUT,
136*5f41b66dSYuval Avnery 			 MLX5_REGEX_MAX_OUTPUT);
137*5f41b66dSYuval Avnery 	if (!ptr) {
138*5f41b66dSYuval Avnery 		err = -ENOMEM;
139*5f41b66dSYuval Avnery 		goto err_output;
140*5f41b66dSYuval Avnery 	}
141*5f41b66dSYuval Avnery 	qp->outputs = mlx5_glue->reg_mr(pd, ptr,
142*5f41b66dSYuval Avnery 					MLX5_REGEX_MAX_OUTPUT * qp->nb_desc,
143*5f41b66dSYuval Avnery 					IBV_ACCESS_LOCAL_WRITE);
144*5f41b66dSYuval Avnery 	if (!qp->outputs) {
145*5f41b66dSYuval Avnery 		rte_free(ptr);
146*5f41b66dSYuval Avnery 		err = -EINVAL;
147*5f41b66dSYuval Avnery 		goto err_output;
148*5f41b66dSYuval Avnery 	}
149*5f41b66dSYuval Avnery 
150*5f41b66dSYuval Avnery 	/* distribute buffers to jobs */
151*5f41b66dSYuval Avnery 	for (i = 0; i < qp->nb_desc; i++) {
152*5f41b66dSYuval Avnery 		qp->jobs[i].input =
153*5f41b66dSYuval Avnery 			(uint8_t *)qp->inputs->addr +
154*5f41b66dSYuval Avnery 			(i % qp->nb_desc) * MLX5_REGEX_MAX_INPUT;
155*5f41b66dSYuval Avnery 		qp->jobs[i].output =
156*5f41b66dSYuval Avnery 			(uint8_t *)qp->outputs->addr +
157*5f41b66dSYuval Avnery 			(i % qp->nb_desc) * MLX5_REGEX_MAX_OUTPUT;
158*5f41b66dSYuval Avnery 		qp->jobs[i].metadata =
159*5f41b66dSYuval Avnery 			(uint8_t *)qp->metadata->addr +
160*5f41b66dSYuval Avnery 			(i % qp->nb_desc) * MLX5_REGEX_METADATA_SIZE;
161*5f41b66dSYuval Avnery 	}
162*5f41b66dSYuval Avnery 	return 0;
163*5f41b66dSYuval Avnery 
164*5f41b66dSYuval Avnery err_output:
165*5f41b66dSYuval Avnery 	ptr = qp->inputs->addr;
166*5f41b66dSYuval Avnery 	rte_free(ptr);
167*5f41b66dSYuval Avnery 	mlx5_glue->dereg_mr(qp->inputs);
168*5f41b66dSYuval Avnery err_input:
169*5f41b66dSYuval Avnery 	ptr = qp->metadata->addr;
170*5f41b66dSYuval Avnery 	rte_free(ptr);
171*5f41b66dSYuval Avnery 	mlx5_glue->dereg_mr(qp->metadata);
172*5f41b66dSYuval Avnery 	return err;
173*5f41b66dSYuval Avnery }
174*5f41b66dSYuval Avnery 
175*5f41b66dSYuval Avnery int
176*5f41b66dSYuval Avnery mlx5_regexdev_setup_fastpath(struct mlx5_regex_priv *priv, uint32_t qp_id)
177*5f41b66dSYuval Avnery {
178*5f41b66dSYuval Avnery 	struct mlx5_regex_qp *qp = &priv->qps[qp_id];
179*5f41b66dSYuval Avnery 	int err;
180*5f41b66dSYuval Avnery 
181*5f41b66dSYuval Avnery 	qp->jobs = rte_calloc(__func__, qp->nb_desc, sizeof(*qp->jobs),
182*5f41b66dSYuval Avnery 			      sizeof(*qp->jobs));
183*5f41b66dSYuval Avnery 	if (!qp->jobs)
184*5f41b66dSYuval Avnery 		return -ENOMEM;
185*5f41b66dSYuval Avnery 	err = setup_buffers(qp, priv->pd);
186*5f41b66dSYuval Avnery 	if (err)
187*5f41b66dSYuval Avnery 		return err;
188*5f41b66dSYuval Avnery 	setup_sqs(qp);
189*5f41b66dSYuval Avnery 	return 0;
190*5f41b66dSYuval Avnery }
191