Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 ZTE Corporation
3 : : */
4 : :
5 : : #include <rte_malloc.h>
6 : :
7 : : #include "zsda_logs.h"
8 : : #include "zsda_qp_common.h"
9 : : #include "zsda_qp.h"
10 : : #include "zsda_comp_pmd.h"
11 : : #include "zsda_comp.h"
12 : :
13 : : static const struct rte_compressdev_capabilities zsda_comp_capabilities[] = {
14 : : {
15 : : .algo = RTE_COMP_ALGO_DEFLATE,
16 : : .comp_feature_flags = RTE_COMP_FF_HUFFMAN_DYNAMIC |
17 : : RTE_COMP_FF_OOP_SGL_IN_SGL_OUT |
18 : : RTE_COMP_FF_OOP_SGL_IN_LB_OUT |
19 : : RTE_COMP_FF_OOP_LB_IN_SGL_OUT |
20 : : RTE_COMP_FF_CRC32_CHECKSUM |
21 : : RTE_COMP_FF_ADLER32_CHECKSUM |
22 : : RTE_COMP_FF_SHAREABLE_PRIV_XFORM,
23 : : .window_size = {.min = 15, .max = 15, .increment = 0},
24 : : },
25 : : };
26 : :
27 : : static int
28 : : zsda_comp_xform_size(void)
29 : : {
30 : : return RTE_ALIGN_CEIL(sizeof(struct zsda_comp_xform), 8);
31 : : }
32 : :
33 : : static struct rte_mempool *
34 : 0 : zsda_comp_xform_pool_create(struct zsda_comp_dev_private *comp_dev,
35 : : struct rte_compressdev_config *config,
36 : : uint32_t num_elements)
37 : : {
38 : : char xform_pool_name[RTE_MEMPOOL_NAMESIZE];
39 : : struct rte_mempool *mp;
40 : :
41 : : snprintf(xform_pool_name, RTE_MEMPOOL_NAMESIZE, "%s_xforms",
42 : 0 : comp_dev->zsda_pci_dev->name);
43 : :
44 : 0 : ZSDA_LOG(DEBUG, "xformpool: %s", xform_pool_name);
45 : 0 : mp = rte_mempool_lookup(xform_pool_name);
46 : :
47 [ # # ]: 0 : if (mp != NULL) {
48 : 0 : ZSDA_LOG(DEBUG, "xformpool already created");
49 [ # # ]: 0 : if (mp->size != num_elements) {
50 : 0 : ZSDA_LOG(DEBUG, "xformpool wrong size - delete it");
51 : 0 : rte_mempool_free(mp);
52 : : mp = NULL;
53 : 0 : comp_dev->xformpool = NULL;
54 : : }
55 : : } else {
56 : 0 : mp = rte_mempool_create(xform_pool_name, num_elements,
57 : : zsda_comp_xform_size(), 0, 0, NULL,
58 : : NULL, NULL, NULL, config->socket_id, 0);
59 [ # # ]: 0 : if (mp == NULL) {
60 : 0 : ZSDA_LOG(ERR, "Failed! mp is NULL");
61 : 0 : return NULL;
62 : : }
63 : : }
64 : :
65 : : return mp;
66 : : }
67 : :
68 : : static int
69 : 0 : zsda_dev_config(struct rte_compressdev *dev,
70 : : struct rte_compressdev_config *config)
71 : : {
72 : 0 : struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;
73 : :
74 [ # # ]: 0 : if (config->max_nb_priv_xforms) {
75 : 0 : comp_dev->xformpool = zsda_comp_xform_pool_create(
76 : : comp_dev, config, config->max_nb_priv_xforms);
77 [ # # ]: 0 : if (comp_dev->xformpool == NULL)
78 : 0 : return -ENOMEM;
79 : : } else
80 : 0 : comp_dev->xformpool = NULL;
81 : :
82 : : return ZSDA_SUCCESS;
83 : : }
84 : :
85 : : static int
86 : 0 : zsda_dev_start(struct rte_compressdev *dev)
87 : : {
88 : 0 : struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;
89 : : int ret;
90 : :
91 : 0 : ret = zsda_queue_start(comp_dev->zsda_pci_dev->pci_dev);
92 : :
93 [ # # ]: 0 : if (ret)
94 : 0 : ZSDA_LOG(ERR, "Failed! zsda_queue_start.");
95 : :
96 : 0 : return ret;
97 : : }
98 : :
99 : : static void
100 : 0 : zsda_dev_stop(struct rte_compressdev *dev)
101 : : {
102 : 0 : struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;
103 : :
104 : 0 : zsda_queue_stop(comp_dev->zsda_pci_dev->pci_dev);
105 : 0 : }
106 : :
107 : : static int
108 : 0 : zsda_qp_release(struct rte_compressdev *dev, uint16_t queue_pair_id)
109 : : {
110 : 0 : return zsda_queue_pair_release(
111 : 0 : (struct zsda_qp **)&(dev->data->queue_pairs[queue_pair_id]));
112 : : }
113 : :
114 : : static int
115 : 0 : zsda_dev_close(struct rte_compressdev *dev)
116 : : {
117 : 0 : struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;
118 : :
119 [ # # ]: 0 : for (int i = 0; i < dev->data->nb_queue_pairs; i++)
120 : 0 : zsda_qp_release(dev, i);
121 : :
122 : 0 : rte_mempool_free(comp_dev->xformpool);
123 : 0 : comp_dev->xformpool = NULL;
124 : :
125 : 0 : return ZSDA_SUCCESS;
126 : : }
127 : :
128 : : static uint16_t
129 : : zsda_comp_max_nb_qps(void)
130 : : {
131 : 0 : uint16_t comp = zsda_nb_qps.encomp;
132 : 0 : uint16_t decomp = zsda_nb_qps.decomp;
133 : : uint16_t min = 0;
134 : :
135 : 0 : if ((comp == MAX_QPS_ON_FUNCTION) ||
136 [ # # ]: 0 : (decomp == MAX_QPS_ON_FUNCTION))
137 : : min = MAX_QPS_ON_FUNCTION;
138 : : else
139 : 0 : min = (comp < decomp) ? comp : decomp;
140 [ # # ]: 0 : if (min == 0)
141 : 0 : return MAX_QPS_ON_FUNCTION;
142 : : return min;
143 : : }
144 : :
145 : : static void
146 : 0 : zsda_dev_info_get(struct rte_compressdev *dev,
147 : : struct rte_compressdev_info *info)
148 : : {
149 : 0 : struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;
150 : :
151 [ # # ]: 0 : if (info != NULL) {
152 : 0 : info->max_nb_queue_pairs = zsda_comp_max_nb_qps();
153 : 0 : info->feature_flags = dev->feature_flags;
154 : 0 : info->capabilities = comp_dev->zsda_dev_capabilities;
155 : : }
156 : 0 : }
157 : :
158 : : static void
159 : 0 : zsda_comp_stats_get(struct rte_compressdev *dev,
160 : : struct rte_compressdev_stats *stats)
161 : : {
162 : 0 : struct zsda_qp_stat stats_info = {0};
163 : :
164 : 0 : zsda_stats_get(dev->data->queue_pairs, dev->data->nb_queue_pairs,
165 : : &stats_info);
166 : 0 : stats->enqueued_count = stats_info.enqueued_count;
167 : 0 : stats->dequeued_count = stats_info.dequeued_count;
168 : 0 : stats->enqueue_err_count = stats_info.enqueue_err_count;
169 : 0 : stats->dequeue_err_count = stats_info.dequeue_err_count;
170 : 0 : }
171 : :
172 : : static void
173 : 0 : zsda_comp_stats_reset(struct rte_compressdev *dev)
174 : : {
175 : 0 : zsda_stats_reset(dev->data->queue_pairs, dev->data->nb_queue_pairs);
176 : 0 : }
177 : :
178 : : static int
179 : 0 : zsda_private_xform_create(struct rte_compressdev *dev,
180 : : const struct rte_comp_xform *xform,
181 : : void **private_xform)
182 : : {
183 : 0 : struct zsda_comp_dev_private *zsda = dev->data->dev_private;
184 : :
185 [ # # ]: 0 : if (unlikely(private_xform == NULL)) {
186 : 0 : ZSDA_LOG(ERR, "Failed! private_xform is NULL");
187 : 0 : return -EINVAL;
188 : : }
189 [ # # ]: 0 : if (unlikely(zsda->xformpool == NULL)) {
190 : 0 : ZSDA_LOG(ERR, "Failed! zsda->xformpool is NULL");
191 : 0 : return -ENOMEM;
192 : : }
193 [ # # ]: 0 : if (rte_mempool_get(zsda->xformpool, private_xform)) {
194 : 0 : ZSDA_LOG(ERR, "Failed! zsda->xformpool is NULL");
195 : 0 : return -ENOMEM;
196 : : }
197 : :
198 : 0 : struct zsda_comp_xform *zsda_xform = *private_xform;
199 : 0 : zsda_xform->type = xform->type;
200 : :
201 [ # # ]: 0 : if (zsda_xform->type == RTE_COMP_COMPRESS)
202 : 0 : zsda_xform->checksum_type = xform->compress.chksum;
203 : : else
204 : 0 : zsda_xform->checksum_type = xform->decompress.chksum;
205 : :
206 [ # # ]: 0 : if (zsda_xform->checksum_type == RTE_COMP_CHECKSUM_CRC32_ADLER32)
207 : 0 : return -EINVAL;
208 : :
209 : : return ZSDA_SUCCESS;
210 : : }
211 : :
212 : : static int
213 : 0 : zsda_private_xform_free(struct rte_compressdev *dev __rte_unused,
214 : : void *private_xform)
215 : : {
216 : : struct zsda_comp_xform *zsda_xform = private_xform;
217 : :
218 [ # # ]: 0 : if (zsda_xform) {
219 : : memset(zsda_xform, 0, zsda_comp_xform_size());
220 : : struct rte_mempool *mp = rte_mempool_from_obj(zsda_xform);
221 : :
222 : 0 : rte_mempool_put(mp, zsda_xform);
223 : 0 : return ZSDA_SUCCESS;
224 : : }
225 : : return -EINVAL;
226 : : }
227 : :
228 : : static int
229 : 0 : zsda_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
230 : : uint32_t max_inflight_ops, int socket_id)
231 : : {
232 : : int ret = ZSDA_SUCCESS;
233 : : struct zsda_qp *qp_new;
234 : :
235 : 0 : struct zsda_qp **qp_addr =
236 : 0 : (struct zsda_qp **)&(dev->data->queue_pairs[qp_id]);
237 : 0 : struct zsda_comp_dev_private *comp_priv = dev->data->dev_private;
238 : 0 : struct zsda_pci_device *zsda_pci_dev = comp_priv->zsda_pci_dev;
239 : : uint16_t nb_des = max_inflight_ops & 0xffff;
240 : : struct task_queue_info task_q_info;
241 : :
242 : : nb_des = (nb_des == NB_DES) ? nb_des : NB_DES;
243 : :
244 [ # # ]: 0 : if (*qp_addr != NULL) {
245 : : ret = zsda_qp_release(dev, qp_id);
246 [ # # ]: 0 : if (ret)
247 : : return ret;
248 : : }
249 : :
250 : 0 : qp_new = rte_zmalloc_socket("zsda PMD qp metadata", sizeof(*qp_new),
251 : : RTE_CACHE_LINE_SIZE, socket_id);
252 [ # # ]: 0 : if (qp_new == NULL) {
253 : 0 : ZSDA_LOG(ERR, "Failed! qp_new is NULL");
254 : 0 : return -ENOMEM;
255 : : }
256 : :
257 : 0 : task_q_info.nb_des = nb_des;
258 : 0 : task_q_info.socket_id = socket_id;
259 : 0 : task_q_info.qp_id = qp_id;
260 : 0 : task_q_info.rx_cb = zsda_comp_callback;
261 : :
262 : 0 : task_q_info.type = ZSDA_SERVICE_COMPRESSION;
263 : 0 : task_q_info.service_str = "comp";
264 : 0 : task_q_info.tx_cb = zsda_comp_wqe_build;
265 : 0 : task_q_info.match = zsda_comp_match;
266 : 0 : ret = zsda_task_queue_setup(zsda_pci_dev, qp_new, &task_q_info);
267 : :
268 : 0 : task_q_info.type = ZSDA_SERVICE_DECOMPRESSION;
269 : 0 : task_q_info.service_str = "decomp";
270 : 0 : task_q_info.tx_cb = zsda_decomp_request_build;
271 : 0 : task_q_info.match = zsda_decomp_match;
272 : 0 : ret |= zsda_task_queue_setup(zsda_pci_dev, qp_new, &task_q_info);
273 : :
274 [ # # ]: 0 : if (ret) {
275 : 0 : rte_free(qp_new);
276 : 0 : return ret;
277 : : }
278 : :
279 : 0 : *qp_addr = qp_new;
280 : :
281 : 0 : return ret;
282 : : }
283 : :
284 : : static struct rte_compressdev_ops compress_zsda_ops = {
285 : : .dev_configure = zsda_dev_config,
286 : : .dev_start = zsda_dev_start,
287 : : .dev_stop = zsda_dev_stop,
288 : : .dev_close = zsda_dev_close,
289 : : .dev_infos_get = zsda_dev_info_get,
290 : :
291 : : .stats_get = zsda_comp_stats_get,
292 : : .stats_reset = zsda_comp_stats_reset,
293 : : .queue_pair_setup = zsda_qp_setup,
294 : : .queue_pair_release = zsda_qp_release,
295 : :
296 : : .private_xform_create = zsda_private_xform_create,
297 : : .private_xform_free = zsda_private_xform_free,
298 : : };
299 : :
300 : : /* An rte_driver is needed in the registration of the device with compressdev.
301 : : * The actual zsda pci's rte_driver can't be used as its name represents
302 : : * the whole pci device with all services. Think of this as a holder for a name
303 : : * for the compression part of the pci device.
304 : : */
305 : : static const char zsda_comp_drv_name[] = RTE_STR(COMPRESSDEV_NAME_ZSDA_PMD);
306 : : static const struct rte_driver compdev_zsda_driver = {
307 : : .name = zsda_comp_drv_name,
308 : : .alias = zsda_comp_drv_name
309 : : };
310 : :
311 : : static uint16_t
312 : 0 : zsda_comp_pmd_enqueue_op_burst(void *qp, struct rte_comp_op **ops,
313 : : uint16_t nb_ops)
314 : : {
315 : 0 : return zsda_enqueue_burst((struct zsda_qp *)qp, (void **)ops,
316 : : nb_ops);
317 : : }
318 : :
319 : : static uint16_t
320 : 0 : zsda_comp_pmd_dequeue_op_burst(void *qp, struct rte_comp_op **ops,
321 : : uint16_t nb_ops)
322 : : {
323 : 0 : return zsda_dequeue_burst((struct zsda_qp *)qp, (void **)ops,
324 : : nb_ops);
325 : : }
326 : :
327 : : int
328 : 0 : zsda_comp_dev_create(struct zsda_pci_device *zsda_pci_dev)
329 : : {
330 : : struct zsda_device_info *dev_info =
331 : 0 : &zsda_devs[zsda_pci_dev->zsda_dev_id];
332 : :
333 : 0 : struct rte_compressdev_pmd_init_params init_params = {
334 : : .name = "",
335 : 0 : .socket_id = (int)rte_socket_id(),
336 : : };
337 : :
338 : : char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
339 : : char capa_memz_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
340 : : struct rte_compressdev *compressdev;
341 : : struct zsda_comp_dev_private *comp_dev;
342 : : const struct rte_compressdev_capabilities *capabilities;
343 : : uint16_t capa_size = sizeof(struct rte_compressdev_capabilities);
344 : :
345 : : snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s",
346 : 0 : zsda_pci_dev->name, "comp");
347 : :
348 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
349 : : return 0;
350 : :
351 : 0 : dev_info->comp_rte_dev.driver = &compdev_zsda_driver;
352 : 0 : dev_info->comp_rte_dev.numa_node = dev_info->pci_dev->device.numa_node;
353 : 0 : dev_info->comp_rte_dev.devargs = NULL;
354 : :
355 : 0 : compressdev = rte_compressdev_pmd_create(
356 : : name, &(dev_info->comp_rte_dev),
357 : : sizeof(struct zsda_comp_dev_private), &init_params);
358 : :
359 [ # # ]: 0 : if (compressdev == NULL)
360 : : return -ENODEV;
361 : :
362 : 0 : compressdev->dev_ops = &compress_zsda_ops;
363 : :
364 : 0 : compressdev->enqueue_burst = zsda_comp_pmd_enqueue_op_burst;
365 : 0 : compressdev->dequeue_burst = zsda_comp_pmd_dequeue_op_burst;
366 : :
367 : 0 : compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
368 : :
369 : 0 : comp_dev = compressdev->data->dev_private;
370 : 0 : comp_dev->zsda_pci_dev = zsda_pci_dev;
371 : 0 : comp_dev->compressdev = compressdev;
372 : :
373 : : capabilities = zsda_comp_capabilities;
374 : :
375 : : snprintf(capa_memz_name, RTE_COMPRESSDEV_NAME_MAX_LEN,
376 : : "ZSDA_COMP_CAPA");
377 : 0 : comp_dev->capa_mz = rte_memzone_lookup(capa_memz_name);
378 [ # # ]: 0 : if (comp_dev->capa_mz == NULL)
379 : 0 : comp_dev->capa_mz = rte_memzone_reserve(
380 : 0 : capa_memz_name, capa_size, rte_socket_id(), 0);
381 : :
382 [ # # ]: 0 : if (comp_dev->capa_mz == NULL) {
383 : 0 : ZSDA_LOG(DEBUG, "Failed! comp_dev->capa_mz is NULL");
384 : : memset(&dev_info->comp_rte_dev, 0,
385 : : sizeof(dev_info->comp_rte_dev));
386 : 0 : rte_compressdev_pmd_destroy(compressdev);
387 : 0 : return -EFAULT;
388 : : }
389 : :
390 : 0 : memcpy(comp_dev->capa_mz->addr, capabilities, capa_size);
391 : 0 : comp_dev->zsda_dev_capabilities = comp_dev->capa_mz->addr;
392 : :
393 : 0 : zsda_pci_dev->comp_dev = comp_dev;
394 : :
395 : 0 : return ZSDA_SUCCESS;
396 : : }
397 : :
398 : : int
399 : 0 : zsda_comp_dev_destroy(struct zsda_pci_device *zsda_pci_dev)
400 : : {
401 : : struct zsda_comp_dev_private *comp_dev;
402 : :
403 [ # # ]: 0 : if (zsda_pci_dev == NULL)
404 : : return -ENODEV;
405 : :
406 : 0 : comp_dev = zsda_pci_dev->comp_dev;
407 [ # # ]: 0 : if (comp_dev == NULL)
408 : : return ZSDA_SUCCESS;
409 : :
410 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY)
411 : 0 : rte_memzone_free(zsda_pci_dev->comp_dev->capa_mz);
412 : :
413 : 0 : zsda_dev_close(comp_dev->compressdev);
414 : :
415 : 0 : rte_compressdev_pmd_destroy(comp_dev->compressdev);
416 : 0 : zsda_pci_dev->comp_dev = NULL;
417 : :
418 : 0 : return ZSDA_SUCCESS;
419 : : }
|