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 : 0 : priv_sess_size = dev->dev_ops->sym_session_get_size(dev);
199 : : } else {
200 : 0 : priv_sess_size = sec_ctx->ops->session_get_size(dev);
201 : : }
202 : :
203 : 0 : max_priv_sess_size = RTE_MAX(max_priv_sess_size, priv_sess_size);
204 : : }
205 : :
206 : 0 : return max_priv_sess_size;
207 : : }
208 : :
209 : : /** attaching the workers predefined by scheduler's EAL options */
210 : : static int
211 : 0 : scheduler_attach_init_worker(struct rte_cryptodev *dev)
212 : : {
213 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
214 : 0 : uint8_t scheduler_id = dev->data->dev_id;
215 : : int i;
216 : :
217 [ # # ]: 0 : for (i = sched_ctx->nb_init_workers - 1; i >= 0; i--) {
218 : 0 : const char *dev_name = sched_ctx->init_worker_names[i];
219 : : struct rte_cryptodev *worker_dev =
220 : 0 : rte_cryptodev_pmd_get_named_dev(dev_name);
221 : : int status;
222 : :
223 [ # # ]: 0 : if (!worker_dev) {
224 : 0 : CR_SCHED_LOG(ERR, "Failed to locate worker dev %s",
225 : : dev_name);
226 : 0 : return -EINVAL;
227 : : }
228 : :
229 : 0 : status = rte_cryptodev_scheduler_worker_attach(
230 : 0 : scheduler_id, worker_dev->data->dev_id);
231 : :
232 [ # # ]: 0 : if (status < 0) {
233 : 0 : CR_SCHED_LOG(ERR, "Failed to attach worker cryptodev %u",
234 : : worker_dev->data->dev_id);
235 : 0 : return status;
236 : : }
237 : :
238 : 0 : CR_SCHED_LOG(INFO, "Scheduler %s attached worker %s",
239 : : dev->data->name,
240 : : sched_ctx->init_worker_names[i]);
241 : :
242 : 0 : rte_free(sched_ctx->init_worker_names[i]);
243 : 0 : sched_ctx->init_worker_names[i] = NULL;
244 : :
245 : 0 : sched_ctx->nb_init_workers -= 1;
246 : : }
247 : :
248 : : return 0;
249 : : }
250 : : /** Configure device */
251 : : static int
252 : 0 : scheduler_pmd_config(struct rte_cryptodev *dev,
253 : : struct rte_cryptodev_config *config)
254 : : {
255 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
256 : : uint32_t i;
257 : : int ret;
258 : :
259 : : /* although scheduler_attach_init_worker presents multiple times,
260 : : * there will be only 1 meaningful execution.
261 : : */
262 : 0 : ret = scheduler_attach_init_worker(dev);
263 [ # # ]: 0 : if (ret < 0)
264 : : return ret;
265 : :
266 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
267 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
268 : :
269 : 0 : ret = rte_cryptodev_configure(worker_dev_id, config);
270 [ # # ]: 0 : if (ret < 0)
271 : : break;
272 : : }
273 : :
274 : : return ret;
275 : : }
276 : :
277 : : static int
278 : 0 : update_order_ring(struct rte_cryptodev *dev, uint16_t qp_id)
279 : : {
280 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
281 : 0 : struct scheduler_qp_ctx *qp_ctx = dev->data->queue_pairs[qp_id];
282 : :
283 [ # # ]: 0 : if (sched_ctx->reordering_enabled) {
284 : : char order_ring_name[RTE_CRYPTODEV_NAME_MAX_LEN];
285 : 0 : uint32_t buff_size = rte_align32pow2(
286 [ # # ]: 0 : sched_ctx->nb_workers * PER_WORKER_BUFF_SIZE);
287 : :
288 [ # # ]: 0 : if (qp_ctx->order_ring) {
289 : 0 : rte_ring_free(qp_ctx->order_ring);
290 : 0 : qp_ctx->order_ring = NULL;
291 : : }
292 : :
293 [ # # ]: 0 : if (!buff_size)
294 : 0 : return 0;
295 : :
296 : 0 : if (snprintf(order_ring_name, RTE_CRYPTODEV_NAME_MAX_LEN,
297 : : "%s_rb_%u_%u", RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD),
298 [ # # ]: 0 : dev->data->dev_id, qp_id) < 0) {
299 : 0 : CR_SCHED_LOG(ERR, "failed to create unique reorder buffer"
300 : : "name");
301 : 0 : return -ENOMEM;
302 : : }
303 : :
304 : 0 : qp_ctx->order_ring = rte_ring_create(order_ring_name,
305 : 0 : buff_size, rte_socket_id(),
306 : : RING_F_SP_ENQ | RING_F_SC_DEQ);
307 [ # # ]: 0 : if (!qp_ctx->order_ring) {
308 : 0 : CR_SCHED_LOG(ERR, "failed to create order ring");
309 : 0 : return -ENOMEM;
310 : : }
311 : : } else {
312 [ # # ]: 0 : if (qp_ctx->order_ring) {
313 : 0 : rte_ring_free(qp_ctx->order_ring);
314 : 0 : qp_ctx->order_ring = NULL;
315 : : }
316 : : }
317 : :
318 : : return 0;
319 : : }
320 : :
321 : : /** Start device */
322 : : static int
323 : 0 : scheduler_pmd_start(struct rte_cryptodev *dev)
324 : : {
325 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
326 : : uint32_t i;
327 : : int ret;
328 : :
329 [ # # ]: 0 : if (dev->data->dev_started)
330 : : return 0;
331 : :
332 : : /* although scheduler_attach_init_worker presents multiple times,
333 : : * there will be only 1 meaningful execution.
334 : : */
335 : 0 : ret = scheduler_attach_init_worker(dev);
336 [ # # ]: 0 : if (ret < 0)
337 : : return ret;
338 : :
339 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
340 : 0 : ret = update_order_ring(dev, i);
341 [ # # ]: 0 : if (ret < 0) {
342 : 0 : CR_SCHED_LOG(ERR, "Failed to update reorder buffer");
343 : 0 : return ret;
344 : : }
345 : : }
346 : :
347 [ # # ]: 0 : if (sched_ctx->mode == CDEV_SCHED_MODE_NOT_SET) {
348 : 0 : CR_SCHED_LOG(ERR, "Scheduler mode is not set");
349 : 0 : return -1;
350 : : }
351 : :
352 [ # # ]: 0 : if (!sched_ctx->nb_workers) {
353 : 0 : CR_SCHED_LOG(ERR, "No worker in the scheduler");
354 : 0 : return -1;
355 : : }
356 : :
357 [ # # ]: 0 : if (sched_ctx->ops.worker_attach == NULL)
358 : : return -ENOTSUP;
359 : :
360 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
361 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
362 : :
363 [ # # ]: 0 : if (sched_ctx->ops.worker_attach(dev, worker_dev_id) < 0) {
364 : 0 : CR_SCHED_LOG(ERR, "Failed to attach worker");
365 : 0 : return -ENOTSUP;
366 : : }
367 : : }
368 : :
369 [ # # ]: 0 : if (sched_ctx->ops.scheduler_start == NULL)
370 : : return -ENOTSUP;
371 : :
372 [ # # ]: 0 : if (sched_ctx->ops.scheduler_start(dev) < 0) {
373 : 0 : CR_SCHED_LOG(ERR, "Scheduler start failed");
374 : 0 : return -1;
375 : : }
376 : :
377 : : /* start all workers */
378 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
379 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
380 : 0 : ret = rte_cryptodev_start(worker_dev_id);
381 [ # # ]: 0 : if (ret < 0) {
382 : 0 : CR_SCHED_LOG(ERR, "Failed to start worker dev %u",
383 : : worker_dev_id);
384 : 0 : return ret;
385 : : }
386 : : }
387 : :
388 : : return 0;
389 : : }
390 : :
391 : : /** Stop device */
392 : : static void
393 : 0 : scheduler_pmd_stop(struct rte_cryptodev *dev)
394 : : {
395 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
396 : : uint32_t i;
397 : :
398 [ # # ]: 0 : if (!dev->data->dev_started)
399 : : return;
400 : :
401 : : /* stop all workers first */
402 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
403 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
404 : :
405 : 0 : rte_cryptodev_stop(worker_dev_id);
406 : : }
407 : :
408 [ # # ]: 0 : if (sched_ctx->ops.scheduler_stop)
409 : 0 : sched_ctx->ops.scheduler_stop(dev);
410 : :
411 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
412 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
413 : :
414 [ # # ]: 0 : if (sched_ctx->ops.worker_detach)
415 : 0 : sched_ctx->ops.worker_detach(dev, worker_dev_id);
416 : : }
417 : : }
418 : :
419 : : /** Close device */
420 : : static int
421 : 0 : scheduler_pmd_close(struct rte_cryptodev *dev)
422 : : {
423 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
424 : : uint32_t i;
425 : : int ret;
426 : :
427 : : /* the dev should be stopped before being closed */
428 [ # # ]: 0 : if (dev->data->dev_started)
429 : : return -EBUSY;
430 : :
431 : : /* close all workers first */
432 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
433 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
434 : : struct rte_cryptodev *worker_dev =
435 : 0 : rte_cryptodev_pmd_get_dev(worker_dev_id);
436 : :
437 : 0 : ret = (*worker_dev->dev_ops->dev_close)(worker_dev);
438 [ # # ]: 0 : if (ret < 0)
439 : 0 : return ret;
440 : : }
441 : :
442 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
443 : 0 : struct scheduler_qp_ctx *qp_ctx = dev->data->queue_pairs[i];
444 : :
445 [ # # ]: 0 : if (qp_ctx->order_ring) {
446 : 0 : rte_ring_free(qp_ctx->order_ring);
447 : 0 : qp_ctx->order_ring = NULL;
448 : : }
449 : :
450 [ # # ]: 0 : if (qp_ctx->private_qp_ctx) {
451 : 0 : rte_free(qp_ctx->private_qp_ctx);
452 : 0 : qp_ctx->private_qp_ctx = NULL;
453 : : }
454 : : }
455 : :
456 [ # # ]: 0 : if (sched_ctx->private_ctx) {
457 : 0 : rte_free(sched_ctx->private_ctx);
458 : 0 : sched_ctx->private_ctx = NULL;
459 : : }
460 : :
461 : : scheduler_free_capabilities(sched_ctx);
462 : :
463 : 0 : return 0;
464 : : }
465 : :
466 : : /** Get device statistics */
467 : : static void
468 : 0 : scheduler_pmd_stats_get(struct rte_cryptodev *dev,
469 : : struct rte_cryptodev_stats *stats)
470 : : {
471 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
472 : : uint32_t i;
473 : :
474 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
475 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
476 : : struct rte_cryptodev *worker_dev =
477 : 0 : rte_cryptodev_pmd_get_dev(worker_dev_id);
478 : 0 : struct rte_cryptodev_stats worker_stats = {0};
479 : :
480 : 0 : (*worker_dev->dev_ops->stats_get)(worker_dev, &worker_stats);
481 : :
482 : 0 : stats->enqueued_count += worker_stats.enqueued_count;
483 : 0 : stats->dequeued_count += worker_stats.dequeued_count;
484 : :
485 : 0 : stats->enqueue_err_count += worker_stats.enqueue_err_count;
486 : 0 : stats->dequeue_err_count += worker_stats.dequeue_err_count;
487 : : }
488 : 0 : }
489 : :
490 : : /** Reset device statistics */
491 : : static void
492 : 0 : scheduler_pmd_stats_reset(struct rte_cryptodev *dev)
493 : : {
494 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
495 : : uint32_t i;
496 : :
497 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
498 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
499 : : struct rte_cryptodev *worker_dev =
500 : 0 : rte_cryptodev_pmd_get_dev(worker_dev_id);
501 : :
502 : 0 : (*worker_dev->dev_ops->stats_reset)(worker_dev);
503 : : }
504 : 0 : }
505 : :
506 : : /** Get device info */
507 : : static void
508 : 0 : scheduler_pmd_info_get(struct rte_cryptodev *dev,
509 : : struct rte_cryptodev_info *dev_info)
510 : : {
511 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
512 : : uint32_t max_nb_sess = 0;
513 : : uint16_t headroom_sz = 0;
514 : : uint16_t tailroom_sz = 0;
515 : : uint32_t i;
516 : :
517 [ # # ]: 0 : if (!dev_info)
518 : : return;
519 : :
520 : : /* although scheduler_attach_init_worker presents multiple times,
521 : : * there will be only 1 meaningful execution.
522 : : */
523 : 0 : scheduler_attach_init_worker(dev);
524 : :
525 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
526 : 0 : uint8_t worker_dev_id = sched_ctx->workers[i].dev_id;
527 : : struct rte_cryptodev_info worker_info;
528 : :
529 : 0 : rte_cryptodev_info_get(worker_dev_id, &worker_info);
530 : 0 : uint32_t dev_max_sess = worker_info.sym.max_nb_sessions;
531 [ # # ]: 0 : if (dev_max_sess != 0) {
532 [ # # ]: 0 : if (max_nb_sess == 0 || dev_max_sess < max_nb_sess)
533 : : max_nb_sess = worker_info.sym.max_nb_sessions;
534 : : }
535 : :
536 : : /* Get the max headroom requirement among worker PMDs */
537 : 0 : headroom_sz = worker_info.min_mbuf_headroom_req >
538 : : headroom_sz ?
539 : : worker_info.min_mbuf_headroom_req :
540 : : headroom_sz;
541 : :
542 : : /* Get the max tailroom requirement among worker PMDs */
543 : 0 : tailroom_sz = worker_info.min_mbuf_tailroom_req >
544 : : tailroom_sz ?
545 : : worker_info.min_mbuf_tailroom_req :
546 : : tailroom_sz;
547 : : }
548 : :
549 : 0 : dev_info->driver_id = dev->driver_id;
550 : 0 : dev_info->feature_flags = dev->feature_flags;
551 : 0 : dev_info->capabilities = sched_ctx->capabilities;
552 : 0 : dev_info->max_nb_queue_pairs = sched_ctx->max_nb_queue_pairs;
553 : 0 : dev_info->min_mbuf_headroom_req = headroom_sz;
554 : 0 : dev_info->min_mbuf_tailroom_req = tailroom_sz;
555 : 0 : dev_info->sym.max_nb_sessions = max_nb_sess;
556 : : }
557 : :
558 : : /** Release queue pair */
559 : : static int
560 : 0 : scheduler_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
561 : : {
562 : 0 : struct scheduler_qp_ctx *qp_ctx = dev->data->queue_pairs[qp_id];
563 : :
564 [ # # ]: 0 : if (!qp_ctx)
565 : : return 0;
566 : :
567 : 0 : rte_ring_free(qp_ctx->order_ring);
568 : 0 : rte_free(qp_ctx->private_qp_ctx);
569 : :
570 : 0 : rte_free(qp_ctx);
571 : 0 : dev->data->queue_pairs[qp_id] = NULL;
572 : :
573 : 0 : return 0;
574 : : }
575 : :
576 : : /** Setup a queue pair */
577 : : static int
578 : 0 : scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
579 : : const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
580 : : {
581 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
582 : : struct scheduler_qp_ctx *qp_ctx;
583 : : char name[RTE_CRYPTODEV_NAME_MAX_LEN];
584 : : uint32_t i;
585 : : int ret;
586 : :
587 : 0 : if (snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN,
588 : : "CRYTO_SCHE PMD %u QP %u",
589 [ # # ]: 0 : dev->data->dev_id, qp_id) < 0) {
590 : 0 : CR_SCHED_LOG(ERR, "Failed to create unique queue pair name");
591 : 0 : return -EFAULT;
592 : : }
593 : :
594 : : /* Free memory prior to re-allocation if needed. */
595 [ # # ]: 0 : if (dev->data->queue_pairs[qp_id] != NULL)
596 : 0 : scheduler_pmd_qp_release(dev, qp_id);
597 : :
598 [ # # ]: 0 : for (i = 0; i < sched_ctx->nb_workers; i++) {
599 : 0 : uint8_t worker_id = sched_ctx->workers[i].dev_id;
600 : :
601 : : /*
602 : : * All workers will share the same session mempool
603 : : * for session-less operations, so the objects
604 : : * must be big enough for all the drivers used.
605 : : */
606 : 0 : ret = rte_cryptodev_queue_pair_setup(worker_id, qp_id,
607 : : qp_conf, socket_id);
608 [ # # ]: 0 : if (ret < 0)
609 : 0 : return ret;
610 : : }
611 : :
612 : : /* Allocate the queue pair data structure. */
613 : 0 : qp_ctx = rte_zmalloc_socket(name, sizeof(*qp_ctx), RTE_CACHE_LINE_SIZE,
614 : : socket_id);
615 [ # # ]: 0 : if (qp_ctx == NULL)
616 : : return -ENOMEM;
617 : :
618 : : /* The actual available object number = nb_descriptors - 1 */
619 : 0 : qp_ctx->max_nb_objs = qp_conf->nb_descriptors - 1;
620 : :
621 : 0 : dev->data->queue_pairs[qp_id] = qp_ctx;
622 : :
623 : : /* although scheduler_attach_init_worker presents multiple times,
624 : : * there will be only 1 meaningful execution.
625 : : */
626 : 0 : ret = scheduler_attach_init_worker(dev);
627 [ # # ]: 0 : if (ret < 0) {
628 : 0 : CR_SCHED_LOG(ERR, "Failed to attach worker");
629 : 0 : scheduler_pmd_qp_release(dev, qp_id);
630 : 0 : return ret;
631 : : }
632 : :
633 [ # # ]: 0 : if (sched_ctx->ops.config_queue_pair) {
634 [ # # ]: 0 : if (sched_ctx->ops.config_queue_pair(dev, qp_id) < 0) {
635 : 0 : CR_SCHED_LOG(ERR, "Unable to configure queue pair");
636 : 0 : return -1;
637 : : }
638 : : }
639 : :
640 : : return 0;
641 : : }
642 : :
643 : : static uint32_t
644 : 0 : scheduler_pmd_sym_session_get_size(struct rte_cryptodev *dev)
645 : : {
646 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
647 : :
648 : 0 : return scheduler_session_size_get(sched_ctx, RTE_CRYPTO_OP_WITH_SESSION);
649 : : }
650 : :
651 : : static int
652 : 0 : scheduler_pmd_sym_session_configure(struct rte_cryptodev *dev,
653 : : struct rte_crypto_sym_xform *xform,
654 : : struct rte_cryptodev_sym_session *sess)
655 : : {
656 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
657 : :
658 : 0 : return scheduler_session_create(sess, xform, sched_ctx, RTE_CRYPTO_OP_WITH_SESSION);
659 : : }
660 : :
661 : : /** Clear the memory of session so it doesn't leave key material behind */
662 : : static void
663 : 0 : scheduler_pmd_sym_session_clear(struct rte_cryptodev *dev,
664 : : struct rte_cryptodev_sym_session *sess)
665 : : {
666 : 0 : struct scheduler_ctx *sched_ctx = dev->data->dev_private;
667 : :
668 : 0 : scheduler_session_destroy(sess, sched_ctx, RTE_CRYPTO_OP_WITH_SESSION);
669 : 0 : }
670 : :
671 : : static struct rte_cryptodev_ops scheduler_pmd_ops = {
672 : : .dev_configure = scheduler_pmd_config,
673 : : .dev_start = scheduler_pmd_start,
674 : : .dev_stop = scheduler_pmd_stop,
675 : : .dev_close = scheduler_pmd_close,
676 : :
677 : : .stats_get = scheduler_pmd_stats_get,
678 : : .stats_reset = scheduler_pmd_stats_reset,
679 : :
680 : : .dev_infos_get = scheduler_pmd_info_get,
681 : :
682 : : .queue_pair_setup = scheduler_pmd_qp_setup,
683 : : .queue_pair_release = scheduler_pmd_qp_release,
684 : :
685 : : .sym_session_get_size = scheduler_pmd_sym_session_get_size,
686 : : .sym_session_configure = scheduler_pmd_sym_session_configure,
687 : : .sym_session_clear = scheduler_pmd_sym_session_clear,
688 : : };
689 : :
690 : : struct rte_cryptodev_ops *rte_crypto_scheduler_pmd_ops = &scheduler_pmd_ops;
691 : :
692 : : /** Configure a scheduler session from a security session configuration */
693 : : static int
694 : 0 : scheduler_pmd_sec_sess_create(void *dev, struct rte_security_session_conf *conf,
695 : : struct rte_security_session *sess)
696 : : {
697 : : struct rte_cryptodev *cdev = dev;
698 : 0 : struct scheduler_ctx *sched_ctx = cdev->data->dev_private;
699 : :
700 : : /* Check for supported security protocols */
701 [ # # ]: 0 : if (!scheduler_check_sec_proto_supp(conf->action_type, conf->protocol)) {
702 : 0 : CR_SCHED_LOG(ERR, "Unsupported security protocol");
703 : 0 : return -ENOTSUP;
704 : : }
705 : :
706 : 0 : return scheduler_session_create(sess, conf, sched_ctx, RTE_CRYPTO_OP_SECURITY_SESSION);
707 : : }
708 : :
709 : : /** Clear the memory of session so it doesn't leave key material behind */
710 : : static int
711 : 0 : scheduler_pmd_sec_sess_destroy(void *dev,
712 : : struct rte_security_session *sess)
713 : : {
714 : : struct rte_cryptodev *cdev = dev;
715 : 0 : struct scheduler_ctx *sched_ctx = cdev->data->dev_private;
716 : :
717 : 0 : scheduler_session_destroy(sess, sched_ctx, RTE_CRYPTO_OP_SECURITY_SESSION);
718 : :
719 : 0 : return 0;
720 : : }
721 : :
722 : : /** Get sync security capabilities for scheduler pmds */
723 : : static const struct rte_security_capability *
724 : 0 : scheduler_pmd_sec_capa_get(void *dev)
725 : : {
726 : : struct rte_cryptodev *cdev = dev;
727 : 0 : struct scheduler_ctx *sched_ctx = cdev->data->dev_private;
728 : :
729 : 0 : return sched_ctx->sec_capabilities;
730 : : }
731 : :
732 : : static unsigned int
733 : 0 : scheduler_pmd_sec_sess_size_get(void *dev)
734 : : {
735 : : struct rte_cryptodev *cdev = dev;
736 : 0 : struct scheduler_ctx *sched_ctx = cdev->data->dev_private;
737 : :
738 : 0 : return scheduler_session_size_get(sched_ctx,
739 : : RTE_CRYPTO_OP_SECURITY_SESSION);
740 : : }
741 : :
742 : : static struct rte_security_ops scheduler_pmd_sec_ops = {
743 : : .session_create = scheduler_pmd_sec_sess_create,
744 : : .session_update = NULL,
745 : : .session_get_size = scheduler_pmd_sec_sess_size_get,
746 : : .session_stats_get = NULL,
747 : : .session_destroy = scheduler_pmd_sec_sess_destroy,
748 : : .set_pkt_metadata = NULL,
749 : : .capabilities_get = scheduler_pmd_sec_capa_get
750 : : };
751 : :
752 : : struct rte_security_ops *rte_crypto_scheduler_pmd_sec_ops =
753 : : &scheduler_pmd_sec_ops;
|