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_comp_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_comp_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_comp_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_comp_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_comp_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_comp_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_comp_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_comp_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_comp_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_comp_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_comp_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_request_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 : :
286 : : .dev_configure = zsda_comp_dev_config,
287 : : .dev_start = zsda_comp_dev_start,
288 : : .dev_stop = zsda_comp_dev_stop,
289 : : .dev_close = zsda_comp_dev_close,
290 : : .dev_infos_get = zsda_comp_dev_info_get,
291 : :
292 : : .stats_get = zsda_comp_stats_get,
293 : : .stats_reset = zsda_comp_stats_reset,
294 : : .queue_pair_setup = zsda_comp_qp_setup,
295 : : .queue_pair_release = zsda_comp_qp_release,
296 : :
297 : : .private_xform_create = zsda_comp_private_xform_create,
298 : : .private_xform_free = zsda_comp_private_xform_free,
299 : : };
300 : :
301 : : /* An rte_driver is needed in the registration of the device with compressdev.
302 : : * The actual zsda pci's rte_driver can't be used as its name represents
303 : : * the whole pci device with all services. Think of this as a holder for a name
304 : : * for the compression part of the pci device.
305 : : */
306 : : static const char zsda_comp_drv_name[] = RTE_STR(COMPRESSDEV_NAME_ZSDA_PMD);
307 : : static const struct rte_driver compdev_zsda_driver = {
308 : : .name = zsda_comp_drv_name, .alias = zsda_comp_drv_name};
309 : :
310 : : static uint16_t
311 : 0 : zsda_comp_pmd_enqueue_op_burst(void *qp, struct rte_comp_op **ops,
312 : : uint16_t nb_ops)
313 : : {
314 : 0 : return zsda_enqueue_burst((struct zsda_qp *)qp, (void **)ops,
315 : : nb_ops);
316 : : }
317 : :
318 : : static uint16_t
319 : 0 : zsda_comp_pmd_dequeue_op_burst(void *qp, struct rte_comp_op **ops,
320 : : uint16_t nb_ops)
321 : : {
322 : 0 : return zsda_dequeue_burst((struct zsda_qp *)qp, (void **)ops,
323 : : nb_ops);
324 : : }
325 : :
326 : : int
327 : 0 : zsda_comp_dev_create(struct zsda_pci_device *zsda_pci_dev)
328 : : {
329 : : struct zsda_device_info *dev_info =
330 : 0 : &zsda_devs[zsda_pci_dev->zsda_dev_id];
331 : :
332 : 0 : struct rte_compressdev_pmd_init_params init_params = {
333 : : .name = "",
334 : 0 : .socket_id = (int)rte_socket_id(),
335 : : };
336 : :
337 : : char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
338 : : char capa_memz_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
339 : : struct rte_compressdev *compressdev;
340 : : struct zsda_comp_dev_private *comp_dev;
341 : : const struct rte_compressdev_capabilities *capabilities;
342 : : uint16_t capa_size = sizeof(struct rte_compressdev_capabilities);
343 : :
344 : : snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s",
345 : 0 : zsda_pci_dev->name, "comp");
346 : :
347 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
348 : : return 0;
349 : :
350 : 0 : dev_info->comp_rte_dev.driver = &compdev_zsda_driver;
351 : 0 : dev_info->comp_rte_dev.numa_node = dev_info->pci_dev->device.numa_node;
352 : 0 : dev_info->comp_rte_dev.devargs = NULL;
353 : :
354 : 0 : compressdev = rte_compressdev_pmd_create(
355 : : name, &(dev_info->comp_rte_dev),
356 : : sizeof(struct zsda_comp_dev_private), &init_params);
357 : :
358 [ # # ]: 0 : if (compressdev == NULL)
359 : : return -ENODEV;
360 : :
361 : 0 : compressdev->dev_ops = &compress_zsda_ops;
362 : :
363 : 0 : compressdev->enqueue_burst = zsda_comp_pmd_enqueue_op_burst;
364 : 0 : compressdev->dequeue_burst = zsda_comp_pmd_dequeue_op_burst;
365 : :
366 : 0 : compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
367 : :
368 : 0 : comp_dev = compressdev->data->dev_private;
369 : 0 : comp_dev->zsda_pci_dev = zsda_pci_dev;
370 : 0 : comp_dev->compressdev = compressdev;
371 : :
372 : : capabilities = zsda_comp_capabilities;
373 : :
374 : : snprintf(capa_memz_name, RTE_COMPRESSDEV_NAME_MAX_LEN,
375 : : "ZSDA_COMP_CAPA");
376 : 0 : comp_dev->capa_mz = rte_memzone_lookup(capa_memz_name);
377 [ # # ]: 0 : if (comp_dev->capa_mz == NULL)
378 : 0 : comp_dev->capa_mz = rte_memzone_reserve(
379 : 0 : capa_memz_name, capa_size, rte_socket_id(), 0);
380 : :
381 [ # # ]: 0 : if (comp_dev->capa_mz == NULL) {
382 : 0 : ZSDA_LOG(DEBUG, "Failed! comp_dev->capa_mz is NULL");
383 : : memset(&dev_info->comp_rte_dev, 0,
384 : : sizeof(dev_info->comp_rte_dev));
385 : 0 : rte_compressdev_pmd_destroy(compressdev);
386 : 0 : return -EFAULT;
387 : : }
388 : :
389 : 0 : memcpy(comp_dev->capa_mz->addr, capabilities, capa_size);
390 : 0 : comp_dev->zsda_dev_capabilities = comp_dev->capa_mz->addr;
391 : :
392 : 0 : zsda_pci_dev->comp_dev = comp_dev;
393 : :
394 : 0 : return ZSDA_SUCCESS;
395 : : }
396 : :
397 : : int
398 : 0 : zsda_comp_dev_destroy(struct zsda_pci_device *zsda_pci_dev)
399 : : {
400 : : struct zsda_comp_dev_private *comp_dev;
401 : :
402 [ # # ]: 0 : if (zsda_pci_dev == NULL)
403 : : return -ENODEV;
404 : :
405 : 0 : comp_dev = zsda_pci_dev->comp_dev;
406 [ # # ]: 0 : if (comp_dev == NULL)
407 : : return ZSDA_SUCCESS;
408 : :
409 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY)
410 : 0 : rte_memzone_free(zsda_pci_dev->comp_dev->capa_mz);
411 : :
412 : 0 : zsda_comp_dev_close(comp_dev->compressdev);
413 : :
414 : 0 : rte_compressdev_pmd_destroy(comp_dev->compressdev);
415 : 0 : zsda_pci_dev->comp_dev = NULL;
416 : :
417 : 0 : return ZSDA_SUCCESS;
418 : : }
|