Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Intel Corporation
3 : : */
4 : : #include <string.h>
5 : :
6 : : #include <rte_common.h>
7 : : #include <rte_malloc.h>
8 : : #include <dev_driver.h>
9 : : #include <rte_cryptodev.h>
10 : : #include <cryptodev_pmd.h>
11 : : #include <rte_security_driver.h>
12 : : #include <rte_reorder.h>
13 : : #include <rte_errno.h>
14 : :
15 : : #include "scheduler_pmd_private.h"
16 : :
17 : : struct scheduler_configured_sess_info {
18 : : uint8_t dev_id;
19 : : uint8_t driver_id;
20 : : union {
21 : : struct rte_cryptodev_sym_session *sess;
22 : : struct {
23 : : struct rte_security_session *sec_sess;
24 : : struct rte_security_ctx *sec_ctx;
25 : : };
26 : : };
27 : : };
28 : :
29 : : static int
30 [ # # ]: 0 : scheduler_session_create(void *sess, void *sess_params,
31 : : struct scheduler_ctx *sched_ctx,
32 : : enum rte_crypto_op_sess_type session_type)
33 : : {
34 : : struct rte_mempool *mp = rte_mempool_from_obj(sess);
35 : : struct scheduler_session_ctx *sess_ctx;
36 : 0 : struct scheduler_configured_sess_info configured_sess[
37 : : RTE_CRYPTODEV_SCHEDULER_MAX_NB_WORKERS] = {{0}};
38 : : uint32_t i, j, n_configured_sess = 0;
39 : : int ret = 0;
40 : :
41 [ # # ]: 0 : if (session_type == RTE_CRYPTO_OP_WITH_SESSION)
42 : 0 : sess_ctx = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
43 : : else
44 : 0 : sess_ctx = SECURITY_GET_SESS_PRIV(sess);
45 : :
46 [ # # ]: 0 : if (mp == NULL)
47 : : return -EINVAL;
48 : :
49 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
50 : : struct scheduler_worker *worker = &sched_ctx->workers[i];
51 : 0 : struct rte_cryptodev *dev = &rte_cryptodevs[worker->dev_id];
52 : : uint8_t next_worker = 0;
53 : :
54 [ # # ]: 0 : for (j = 0; j < n_configured_sess; j++) {
55 [ # # ]: 0 : if (configured_sess[j].driver_id == worker->driver_id) {
56 [ # # ]: 0 : if (session_type == RTE_CRYPTO_OP_WITH_SESSION)
57 : 0 : sess_ctx->worker_sess[i] =
58 : 0 : configured_sess[j].sess;
59 : : else
60 : 0 : sess_ctx->worker_sec_sess[i] =
61 : 0 : configured_sess[j].sec_sess;
62 : :
63 : : next_worker = 1;
64 : : break;
65 : : }
66 : : }
67 : 0 : if (next_worker)
68 : 0 : continue;
69 : :
70 [ # # ]: 0 : if (rte_mempool_avail_count(mp) == 0) {
71 : : ret = -ENOMEM;
72 : 0 : goto error_exit;
73 : : }
74 : :
75 [ # # ]: 0 : if (session_type == RTE_CRYPTO_OP_WITH_SESSION) {
76 : : struct rte_cryptodev_sym_session *worker_sess =
77 : 0 : rte_cryptodev_sym_session_create(worker->dev_id,
78 : : sess_params, mp);
79 : :
80 [ # # ]: 0 : if (worker_sess == NULL) {
81 : 0 : ret = -rte_errno;
82 : 0 : goto error_exit;
83 : : }
84 : :
85 : 0 : worker_sess->opaque_data = (uint64_t)sess;
86 : 0 : sess_ctx->worker_sess[i] = worker_sess;
87 : 0 : configured_sess[n_configured_sess].sess = worker_sess;
88 : : } else {
89 : : struct rte_security_session *worker_sess =
90 : 0 : rte_security_session_create(dev->security_ctx,
91 : : sess_params, mp);
92 : :
93 [ # # ]: 0 : if (worker_sess == NULL) {
94 : 0 : ret = -rte_errno;
95 : 0 : goto error_exit;
96 : : }
97 : :
98 : 0 : worker_sess->opaque_data = (uint64_t)sess;
99 : 0 : sess_ctx->worker_sec_sess[i] = worker_sess;
100 : 0 : configured_sess[n_configured_sess].sec_sess =
101 : : worker_sess;
102 : 0 : configured_sess[n_configured_sess].sec_ctx =
103 : 0 : dev->security_ctx;
104 : : }
105 : :
106 : 0 : configured_sess[n_configured_sess].driver_id =
107 : 0 : worker->driver_id;
108 : 0 : configured_sess[n_configured_sess].dev_id = worker->dev_id;
109 : 0 : n_configured_sess++;
110 : : }
111 : :
112 : : return 0;
113 : :
114 : 0 : error_exit:
115 : 0 : sess_ctx->ref_cnt = sched_ctx->ref_cnt;
116 [ # # ]: 0 : for (i = 0; i < n_configured_sess; i++) {
117 [ # # ]: 0 : if (session_type == RTE_CRYPTO_OP_WITH_SESSION)
118 : 0 : rte_cryptodev_sym_session_free(
119 : 0 : configured_sess[i].dev_id,
120 : 0 : configured_sess[i].sess);
121 : : else
122 : 0 : rte_security_session_destroy(
123 : 0 : configured_sess[i].sec_ctx,
124 : 0 : configured_sess[i].sec_sess);
125 : : }
126 : :
127 : : return ret;
128 : : }
129 : :
130 : : static void
131 : 0 : scheduler_session_destroy(void *sess, struct scheduler_ctx *sched_ctx,
132 : : uint8_t session_type)
133 : : {
134 : : struct scheduler_session_ctx *sess_ctx;
135 : 0 : struct scheduler_configured_sess_info deleted_sess[
136 : : RTE_CRYPTODEV_SCHEDULER_MAX_NB_WORKERS] = {{0}};
137 : : uint32_t i, j, n_deleted_sess = 0;
138 : :
139 [ # # ]: 0 : if (session_type == RTE_CRYPTO_OP_WITH_SESSION)
140 : 0 : sess_ctx = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
141 : : else
142 : 0 : sess_ctx = SECURITY_GET_SESS_PRIV(sess);
143 : :
144 [ # # ]: 0 : if (sched_ctx->ref_cnt != sess_ctx->ref_cnt) {
145 : 0 : CR_SCHED_LOG(WARNING,
146 : : "Worker updated between session creation/deletion. "
147 : : "The session may not be freed fully.");
148 : : }
149 : :
150 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
151 : : struct scheduler_worker *worker = &sched_ctx->workers[i];
152 : 0 : struct rte_cryptodev *dev = &rte_cryptodevs[worker->dev_id];
153 : : uint8_t next_worker = 0;
154 : :
155 [ # # ]: 0 : for (j = 0; j < n_deleted_sess; j++) {
156 [ # # ]: 0 : if (deleted_sess[j].driver_id == worker->driver_id) {
157 [ # # ]: 0 : if (session_type == RTE_CRYPTO_OP_WITH_SESSION)
158 : 0 : sess_ctx->worker_sess[i] = NULL;
159 : : else
160 : 0 : sess_ctx->worker_sec_sess[i] = NULL;
161 : :
162 : : next_worker = 1;
163 : : break;
164 : : }
165 : : }
166 : 0 : if (next_worker)
167 : 0 : continue;
168 : :
169 [ # # ]: 0 : if (session_type == RTE_CRYPTO_OP_WITH_SESSION) {
170 : 0 : rte_cryptodev_sym_session_free(worker->dev_id,
171 : 0 : sess_ctx->worker_sess[i]);
172 : 0 : sess_ctx->worker_sess[i] = NULL;
173 : : } else {
174 : 0 : rte_security_session_destroy(dev->security_ctx,
175 : 0 : sess_ctx->worker_sec_sess[i]);
176 : 0 : sess_ctx->worker_sec_sess[i] = NULL;
177 : : }
178 : :
179 : 0 : deleted_sess[n_deleted_sess++].driver_id = worker->driver_id;
180 : : }
181 : 0 : }
182 : :
183 : : static unsigned int
184 : 0 : scheduler_session_size_get(struct scheduler_ctx *sched_ctx,
185 : : uint8_t session_type)
186 : : {
187 : : uint8_t i = 0;
188 : : uint32_t max_priv_sess_size = sizeof(struct scheduler_session_ctx);
189 : :
190 : : /* Check what is the maximum private session size for all workers */
191 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
192 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
193 : 0 : struct rte_cryptodev *dev = &rte_cryptodevs[worker_dev_id];
194 : 0 : struct rte_security_ctx *sec_ctx = dev->security_ctx;
195 : : uint32_t priv_sess_size = 0;
196 : :
197 [ # # ]: 0 : if (session_type == RTE_CRYPTO_OP_WITH_SESSION) {
198 : : priv_sess_size =
199 : 0 : (*dev->dev_ops->sym_session_get_size)(dev);
200 : : } else {
201 : 0 : priv_sess_size = (*sec_ctx->ops->session_get_size)(dev);
202 : : }
203 : :
204 : 0 : max_priv_sess_size = RTE_MAX(max_priv_sess_size, priv_sess_size);
205 : : }
206 : :
207 : 0 : return max_priv_sess_size;
208 : : }
209 : :
210 : : /** attaching the workers predefined by scheduler's EAL options */
211 : : static int
212 : 0 : scheduler_attach_init_worker(struct rte_cryptodev *dev)
213 : : {
214 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
215 : 0 : uint8_t scheduler_id = dev->data->dev_id;
216 : : int i;
217 : :
218 [ # # ]: 0 : for (i = sched_ctx->nb_init_workers - 1; i >= 0; i--) {
219 : 0 : const char *dev_name = sched_ctx->init_worker_names[i];
220 : : struct rte_cryptodev *worker_dev =
221 : 0 : rte_cryptodev_pmd_get_named_dev(dev_name);
222 : : int status;
223 : :
224 [ # # ]: 0 : if (!worker_dev) {
225 : 0 : CR_SCHED_LOG(ERR, "Failed to locate worker dev %s",
226 : : dev_name);
227 : 0 : return -EINVAL;
228 : : }
229 : :
230 : 0 : status = rte_cryptodev_scheduler_worker_attach(
231 : 0 : scheduler_id, worker_dev->data->dev_id);
232 : :
233 [ # # ]: 0 : if (status < 0) {
234 : 0 : CR_SCHED_LOG(ERR, "Failed to attach worker cryptodev %u",
235 : : worker_dev->data->dev_id);
236 : 0 : return status;
237 : : }
238 : :
239 : 0 : CR_SCHED_LOG(INFO, "Scheduler %s attached worker %s",
240 : : dev->data->name,
241 : : sched_ctx->init_worker_names[i]);
242 : :
243 : 0 : rte_free(sched_ctx->init_worker_names[i]);
244 : 0 : sched_ctx->init_worker_names[i] = NULL;
245 : :
246 : 0 : sched_ctx->nb_init_workers -= 1;
247 : : }
248 : :
249 : : return 0;
250 : : }
251 : : /** Configure device */
252 : : static int
253 : 0 : scheduler_pmd_config(struct rte_cryptodev *dev,
254 : : struct rte_cryptodev_config *config)
255 : : {
256 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
257 : : uint32_t i;
258 : : int ret;
259 : :
260 : : /* although scheduler_attach_init_worker presents multiple times,
261 : : * there will be only 1 meaningful execution.
262 : : */
263 : 0 : ret = scheduler_attach_init_worker(dev);
264 [ # # ]: 0 : if (ret < 0)
265 : : return ret;
266 : :
267 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
268 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
269 : :
270 : 0 : ret = rte_cryptodev_configure(worker_dev_id, config);
271 [ # # ]: 0 : if (ret < 0)
272 : : break;
273 : : }
274 : :
275 : : return ret;
276 : : }
277 : :
278 : : static int
279 : 0 : update_order_ring(struct rte_cryptodev *dev, uint16_t qp_id)
280 : : {
281 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
282 : 0 : struct scheduler_qp_ctx *qp_ctx = dev->data->queue_pairs[qp_id];
283 : :
284 [ # # ]: 0 : if (sched_ctx->reordering_enabled) {
285 : : char order_ring_name[RTE_CRYPTODEV_NAME_MAX_LEN];
286 : 0 : uint32_t buff_size = rte_align32pow2(
287 [ # # ]: 0 : sched_ctx->nb_workers * PER_WORKER_BUFF_SIZE);
288 : :
289 [ # # ]: 0 : if (qp_ctx->order_ring) {
290 : 0 : rte_ring_free(qp_ctx->order_ring);
291 : 0 : qp_ctx->order_ring = NULL;
292 : : }
293 : :
294 [ # # ]: 0 : if (!buff_size)
295 : 0 : return 0;
296 : :
297 : 0 : if (snprintf(order_ring_name, RTE_CRYPTODEV_NAME_MAX_LEN,
298 : : "%s_rb_%u_%u", RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD),
299 [ # # ]: 0 : dev->data->dev_id, qp_id) < 0) {
300 : 0 : CR_SCHED_LOG(ERR, "failed to create unique reorder buffer"
301 : : "name");
302 : 0 : return -ENOMEM;
303 : : }
304 : :
305 : 0 : qp_ctx->order_ring = rte_ring_create(order_ring_name,
306 : 0 : buff_size, rte_socket_id(),
307 : : RING_F_SP_ENQ | RING_F_SC_DEQ);
308 [ # # ]: 0 : if (!qp_ctx->order_ring) {
309 : 0 : CR_SCHED_LOG(ERR, "failed to create order ring");
310 : 0 : return -ENOMEM;
311 : : }
312 : : } else {
313 [ # # ]: 0 : if (qp_ctx->order_ring) {
314 : 0 : rte_ring_free(qp_ctx->order_ring);
315 : 0 : qp_ctx->order_ring = NULL;
316 : : }
317 : : }
318 : :
319 : : return 0;
320 : : }
321 : :
322 : : /** Start device */
323 : : static int
324 : 0 : scheduler_pmd_start(struct rte_cryptodev *dev)
325 : : {
326 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
327 : : uint32_t i;
328 : : int ret;
329 : :
330 [ # # ]: 0 : if (dev->data->dev_started)
331 : : return 0;
332 : :
333 : : /* although scheduler_attach_init_worker presents multiple times,
334 : : * there will be only 1 meaningful execution.
335 : : */
336 : 0 : ret = scheduler_attach_init_worker(dev);
337 [ # # ]: 0 : if (ret < 0)
338 : : return ret;
339 : :
340 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
341 : 0 : ret = update_order_ring(dev, i);
342 [ # # ]: 0 : if (ret < 0) {
343 : 0 : CR_SCHED_LOG(ERR, "Failed to update reorder buffer");
344 : 0 : return ret;
345 : : }
346 : : }
347 : :
348 [ # # ]: 0 : if (sched_ctx->mode == CDEV_SCHED_MODE_NOT_SET) {
349 : 0 : CR_SCHED_LOG(ERR, "Scheduler mode is not set");
350 : 0 : return -1;
351 : : }
352 : :
353 [ # # ]: 0 : if (!sched_ctx->nb_workers) {
354 : 0 : CR_SCHED_LOG(ERR, "No worker in the scheduler");
355 : 0 : return -1;
356 : : }
357 : :
358 [ # # ]: 0 : if (*sched_ctx->ops.worker_attach == NULL)
359 : : return -ENOTSUP;
360 : :
361 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
362 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
363 : :
364 [ # # ]: 0 : if ((*sched_ctx->ops.worker_attach)(dev, worker_dev_id) < 0) {
365 : 0 : CR_SCHED_LOG(ERR, "Failed to attach worker");
366 : 0 : return -ENOTSUP;
367 : : }
368 : : }
369 : :
370 [ # # ]: 0 : if (*sched_ctx->ops.scheduler_start == NULL)
371 : : return -ENOTSUP;
372 : :
373 [ # # ]: 0 : if ((*sched_ctx->ops.scheduler_start)(dev) < 0) {
374 : 0 : CR_SCHED_LOG(ERR, "Scheduler start failed");
375 : 0 : return -1;
376 : : }
377 : :
378 : : /* start all workers */
379 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
380 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
381 : 0 : ret = rte_cryptodev_start(worker_dev_id);
382 [ # # ]: 0 : if (ret < 0) {
383 : 0 : CR_SCHED_LOG(ERR, "Failed to start worker dev %u",
384 : : worker_dev_id);
385 : 0 : return ret;
386 : : }
387 : : }
388 : :
389 : : return 0;
390 : : }
391 : :
392 : : /** Stop device */
393 : : static void
394 : 0 : scheduler_pmd_stop(struct rte_cryptodev *dev)
395 : : {
396 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
397 : : uint32_t i;
398 : :
399 [ # # ]: 0 : if (!dev->data->dev_started)
400 : : return;
401 : :
402 : : /* stop all workers first */
403 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
404 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
405 : :
406 : 0 : rte_cryptodev_stop(worker_dev_id);
407 : : }
408 : :
409 [ # # ]: 0 : if (*sched_ctx->ops.scheduler_stop)
410 : 0 : (*sched_ctx->ops.scheduler_stop)(dev);
411 : :
412 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
413 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
414 : :
415 [ # # ]: 0 : if (*sched_ctx->ops.worker_detach)
416 : 0 : (*sched_ctx->ops.worker_detach)(dev, worker_dev_id);
417 : : }
418 : : }
419 : :
420 : : /** Close device */
421 : : static int
422 : 0 : scheduler_pmd_close(struct rte_cryptodev *dev)
423 : : {
424 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
425 : : uint32_t i;
426 : : int ret;
427 : :
428 : : /* the dev should be stopped before being closed */
429 [ # # ]: 0 : if (dev->data->dev_started)
430 : : return -EBUSY;
431 : :
432 : : /* close all workers first */
433 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
434 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
435 : : struct rte_cryptodev *worker_dev =
436 : 0 : rte_cryptodev_pmd_get_dev(worker_dev_id);
437 : :
438 : 0 : ret = (*worker_dev->dev_ops->dev_close)(worker_dev);
439 [ # # ]: 0 : if (ret < 0)
440 : 0 : return ret;
441 : : }
442 : :
443 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
444 : 0 : struct scheduler_qp_ctx *qp_ctx = dev->data->queue_pairs[i];
445 : :
446 [ # # ]: 0 : if (qp_ctx->order_ring) {
447 : 0 : rte_ring_free(qp_ctx->order_ring);
448 : 0 : qp_ctx->order_ring = NULL;
449 : : }
450 : :
451 [ # # ]: 0 : if (qp_ctx->private_qp_ctx) {
452 : 0 : rte_free(qp_ctx->private_qp_ctx);
453 : 0 : qp_ctx->private_qp_ctx = NULL;
454 : : }
455 : : }
456 : :
457 [ # # ]: 0 : if (sched_ctx->private_ctx) {
458 : 0 : rte_free(sched_ctx->private_ctx);
459 : 0 : sched_ctx->private_ctx = NULL;
460 : : }
461 : :
462 : : scheduler_free_capabilities(sched_ctx);
463 : :
464 : 0 : return 0;
465 : : }
466 : :
467 : : /** Get device statistics */
468 : : static void
469 : 0 : scheduler_pmd_stats_get(struct rte_cryptodev *dev,
470 : : struct rte_cryptodev_stats *stats)
471 : : {
472 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
473 : : uint32_t i;
474 : :
475 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
476 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
477 : : struct rte_cryptodev *worker_dev =
478 : 0 : rte_cryptodev_pmd_get_dev(worker_dev_id);
479 : 0 : struct rte_cryptodev_stats worker_stats = {0};
480 : :
481 : 0 : (*worker_dev->dev_ops->stats_get)(worker_dev, &worker_stats);
482 : :
483 : 0 : stats->enqueued_count += worker_stats.enqueued_count;
484 : 0 : stats->dequeued_count += worker_stats.dequeued_count;
485 : :
486 : 0 : stats->enqueue_err_count += worker_stats.enqueue_err_count;
487 : 0 : stats->dequeue_err_count += worker_stats.dequeue_err_count;
488 : : }
489 : 0 : }
490 : :
491 : : /** Reset device statistics */
492 : : static void
493 : 0 : scheduler_pmd_stats_reset(struct rte_cryptodev *dev)
494 : : {
495 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
496 : : uint32_t i;
497 : :
498 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
499 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
500 : : struct rte_cryptodev *worker_dev =
501 : 0 : rte_cryptodev_pmd_get_dev(worker_dev_id);
502 : :
503 : 0 : (*worker_dev->dev_ops->stats_reset)(worker_dev);
504 : : }
505 : 0 : }
506 : :
507 : : /** Get device info */
508 : : static void
509 : 0 : scheduler_pmd_info_get(struct rte_cryptodev *dev,
510 : : struct rte_cryptodev_info *dev_info)
511 : : {
512 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
513 : : uint32_t max_nb_sess = 0;
514 : : uint16_t headroom_sz = 0;
515 : : uint16_t tailroom_sz = 0;
516 : : uint32_t i;
517 : :
518 [ # # ]: 0 : if (!dev_info)
519 : : return;
520 : :
521 : : /* although scheduler_attach_init_worker presents multiple times,
522 : : * there will be only 1 meaningful execution.
523 : : */
524 : 0 : scheduler_attach_init_worker(dev);
525 : :
526 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
527 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
528 : : struct rte_cryptodev_info worker_info;
529 : :
530 : 0 : rte_cryptodev_info_get(worker_dev_id, &worker_info);
531 : 0 : uint32_t dev_max_sess = worker_info.sym.max_nb_sessions;
532 [ # # ]: 0 : if (dev_max_sess != 0) {
533 [ # # ]: 0 : if (max_nb_sess == 0 || dev_max_sess < max_nb_sess)
534 : : max_nb_sess = worker_info.sym.max_nb_sessions;
535 : : }
536 : :
537 : : /* Get the max headroom requirement among worker PMDs */
538 : 0 : headroom_sz = worker_info.min_mbuf_headroom_req >
539 : : headroom_sz ?
540 : : worker_info.min_mbuf_headroom_req :
541 : : headroom_sz;
542 : :
543 : : /* Get the max tailroom requirement among worker PMDs */
544 : 0 : tailroom_sz = worker_info.min_mbuf_tailroom_req >
545 : : tailroom_sz ?
546 : : worker_info.min_mbuf_tailroom_req :
547 : : tailroom_sz;
548 : : }
549 : :
550 : 0 : dev_info->driver_id = dev->driver_id;
551 : 0 : dev_info->feature_flags = dev->feature_flags;
552 : 0 : dev_info->capabilities = sched_ctx->capabilities;
553 : 0 : dev_info->max_nb_queue_pairs = sched_ctx->max_nb_queue_pairs;
554 : 0 : dev_info->min_mbuf_headroom_req = headroom_sz;
555 : 0 : dev_info->min_mbuf_tailroom_req = tailroom_sz;
556 : 0 : dev_info->sym.max_nb_sessions = max_nb_sess;
557 : : }
558 : :
559 : : /** Release queue pair */
560 : : static int
561 : 0 : scheduler_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
562 : : {
563 : 0 : struct scheduler_qp_ctx *qp_ctx = dev->data->queue_pairs[qp_id];
564 : :
565 [ # # ]: 0 : if (!qp_ctx)
566 : : return 0;
567 : :
568 : 0 : rte_ring_free(qp_ctx->order_ring);
569 : 0 : rte_free(qp_ctx->private_qp_ctx);
570 : :
571 : 0 : rte_free(qp_ctx);
572 : 0 : dev->data->queue_pairs[qp_id] = NULL;
573 : :
574 : 0 : return 0;
575 : : }
576 : :
577 : : /** Setup a queue pair */
578 : : static int
579 : 0 : scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
580 : : const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
581 : : {
582 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
583 : : struct scheduler_qp_ctx *qp_ctx;
584 : : char name[RTE_CRYPTODEV_NAME_MAX_LEN];
585 : : uint32_t i;
586 : : int ret;
587 : :
588 : 0 : if (snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN,
589 : : "CRYTO_SCHE PMD %u QP %u",
590 [ # # ]: 0 : dev->data->dev_id, qp_id) < 0) {
591 : 0 : CR_SCHED_LOG(ERR, "Failed to create unique queue pair name");
592 : 0 : return -EFAULT;
593 : : }
594 : :
595 : : /* Free memory prior to re-allocation if needed. */
596 [ # # ]: 0 : if (dev->data->queue_pairs[qp_id] != NULL)
597 : 0 : scheduler_pmd_qp_release(dev, qp_id);
598 : :
599 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
600 : 0 : uint8_t worker_id = sched_ctx->workers[i].dev_id;
601 : :
602 : : /*
603 : : * All workers will share the same session mempool
604 : : * for session-less operations, so the objects
605 : : * must be big enough for all the drivers used.
606 : : */
607 : 0 : ret = rte_cryptodev_queue_pair_setup(worker_id, qp_id,
608 : : qp_conf, socket_id);
609 [ # # ]: 0 : if (ret < 0)
610 : 0 : return ret;
611 : : }
612 : :
613 : : /* Allocate the queue pair data structure. */
614 : 0 : qp_ctx = rte_zmalloc_socket(name, sizeof(*qp_ctx), RTE_CACHE_LINE_SIZE,
615 : : socket_id);
616 [ # # ]: 0 : if (qp_ctx == NULL)
617 : : return -ENOMEM;
618 : :
619 : : /* The actual available object number = nb_descriptors - 1 */
620 : 0 : qp_ctx->max_nb_objs = qp_conf->nb_descriptors - 1;
621 : :
622 : 0 : dev->data->queue_pairs[qp_id] = qp_ctx;
623 : :
624 : : /* although scheduler_attach_init_worker presents multiple times,
625 : : * there will be only 1 meaningful execution.
626 : : */
627 : 0 : ret = scheduler_attach_init_worker(dev);
628 [ # # ]: 0 : if (ret < 0) {
629 : 0 : CR_SCHED_LOG(ERR, "Failed to attach worker");
630 : 0 : scheduler_pmd_qp_release(dev, qp_id);
631 : 0 : return ret;
632 : : }
633 : :
634 [ # # ]: 0 : if (*sched_ctx->ops.config_queue_pair) {
635 [ # # ]: 0 : if ((*sched_ctx->ops.config_queue_pair)(dev, qp_id) < 0) {
636 : 0 : CR_SCHED_LOG(ERR, "Unable to configure queue pair");
637 : 0 : return -1;
638 : : }
639 : : }
640 : :
641 : : return 0;
642 : : }
643 : :
644 : : static uint32_t
645 : 0 : scheduler_pmd_sym_session_get_size(struct rte_cryptodev *dev)
646 : : {
647 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
648 : :
649 : 0 : return scheduler_session_size_get(sched_ctx, RTE_CRYPTO_OP_WITH_SESSION);
650 : : }
651 : :
652 : : static int
653 : 0 : scheduler_pmd_sym_session_configure(struct rte_cryptodev *dev,
654 : : struct rte_crypto_sym_xform *xform,
655 : : struct rte_cryptodev_sym_session *sess)
656 : : {
657 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
658 : :
659 : 0 : return scheduler_session_create(sess, xform, sched_ctx, RTE_CRYPTO_OP_WITH_SESSION);
660 : : }
661 : :
662 : : /** Clear the memory of session so it doesn't leave key material behind */
663 : : static void
664 : 0 : scheduler_pmd_sym_session_clear(struct rte_cryptodev *dev,
665 : : struct rte_cryptodev_sym_session *sess)
666 : : {
667 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
668 : :
669 : 0 : scheduler_session_destroy(sess, sched_ctx, RTE_CRYPTO_OP_WITH_SESSION);
670 : 0 : }
671 : :
672 : : static struct rte_cryptodev_ops scheduler_pmd_ops = {
673 : : .dev_configure = scheduler_pmd_config,
674 : : .dev_start = scheduler_pmd_start,
675 : : .dev_stop = scheduler_pmd_stop,
676 : : .dev_close = scheduler_pmd_close,
677 : :
678 : : .stats_get = scheduler_pmd_stats_get,
679 : : .stats_reset = scheduler_pmd_stats_reset,
680 : :
681 : : .dev_infos_get = scheduler_pmd_info_get,
682 : :
683 : : .queue_pair_setup = scheduler_pmd_qp_setup,
684 : : .queue_pair_release = scheduler_pmd_qp_release,
685 : :
686 : : .sym_session_get_size = scheduler_pmd_sym_session_get_size,
687 : : .sym_session_configure = scheduler_pmd_sym_session_configure,
688 : : .sym_session_clear = scheduler_pmd_sym_session_clear,
689 : : };
690 : :
691 : : struct rte_cryptodev_ops *rte_crypto_scheduler_pmd_ops = &scheduler_pmd_ops;
692 : :
693 : : /** Configure a scheduler session from a security session configuration */
694 : : static int
695 : 0 : scheduler_pmd_sec_sess_create(void *dev, struct rte_security_session_conf *conf,
696 : : struct rte_security_session *sess)
697 : : {
698 : : struct rte_cryptodev *cdev = dev;
699 : 0 : struct scheduler_ctx *sched_ctx = cdev->data->dev_private;
700 : :
701 : : /* Check for supported security protocols */
702 [ # # ]: 0 : if (!scheduler_check_sec_proto_supp(conf->action_type, conf->protocol)) {
703 : 0 : CR_SCHED_LOG(ERR, "Unsupported security protocol");
704 : 0 : return -ENOTSUP;
705 : : }
706 : :
707 : 0 : return scheduler_session_create(sess, conf, sched_ctx, RTE_CRYPTO_OP_SECURITY_SESSION);
708 : : }
709 : :
710 : : /** Clear the memory of session so it doesn't leave key material behind */
711 : : static int
712 : 0 : scheduler_pmd_sec_sess_destroy(void *dev,
713 : : struct rte_security_session *sess)
714 : : {
715 : : struct rte_cryptodev *cdev = dev;
716 : 0 : struct scheduler_ctx *sched_ctx = cdev->data->dev_private;
717 : :
718 : 0 : scheduler_session_destroy(sess, sched_ctx, RTE_CRYPTO_OP_SECURITY_SESSION);
719 : :
720 : 0 : return 0;
721 : : }
722 : :
723 : : /** Get sync security capabilities for scheduler pmds */
724 : : static const struct rte_security_capability *
725 : 0 : scheduler_pmd_sec_capa_get(void *dev)
726 : : {
727 : : struct rte_cryptodev *cdev = dev;
728 : 0 : struct scheduler_ctx *sched_ctx = cdev->data->dev_private;
729 : :
730 : 0 : return sched_ctx->sec_capabilities;
731 : : }
732 : :
733 : : static unsigned int
734 : 0 : scheduler_pmd_sec_sess_size_get(void *dev)
735 : : {
736 : : struct rte_cryptodev *cdev = dev;
737 : 0 : struct scheduler_ctx *sched_ctx = cdev->data->dev_private;
738 : :
739 : 0 : return scheduler_session_size_get(sched_ctx,
740 : : RTE_CRYPTO_OP_SECURITY_SESSION);
741 : : }
742 : :
743 : : static struct rte_security_ops scheduler_pmd_sec_ops = {
744 : : .session_create = scheduler_pmd_sec_sess_create,
745 : : .session_update = NULL,
746 : : .session_get_size = scheduler_pmd_sec_sess_size_get,
747 : : .session_stats_get = NULL,
748 : : .session_destroy = scheduler_pmd_sec_sess_destroy,
749 : : .set_pkt_metadata = NULL,
750 : : .capabilities_get = scheduler_pmd_sec_capa_get
751 : : };
752 : :
753 : : struct rte_security_ops *rte_crypto_scheduler_pmd_sec_ops =
754 : : &scheduler_pmd_sec_ops;
|