/** Configure device */ static int scheduler_pmd_config(struct rte_cryptodev *dev, struct rte_cryptodev_config *config) { struct scheduler_ctx *sched_ctx = dev->data->dev_private; uint32_t i; int ret; /* although scheduler_attach_init_slave presents multiple times, * there will be only 1 meaningful execution. */ ret = scheduler_attach_init_slave(dev); if (ret < 0) return ret; for (i = 0; i < sched_ctx->nb_slaves; i++) { uint8_t slave_dev_id = sched_ctx->slaves[i].dev_id; ret = rte_cryptodev_configure(slave_dev_id, config); if (ret < 0) break; } return ret; }
/** Get device info */ static void scheduler_pmd_info_get(struct rte_cryptodev *dev, struct rte_cryptodev_info *dev_info) { struct scheduler_ctx *sched_ctx = dev->data->dev_private; uint32_t max_nb_sessions = sched_ctx->nb_slaves ? UINT32_MAX : RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS; uint32_t i; if (!dev_info) return; /* although scheduler_attach_init_slave presents multiple times, * there will be only 1 meaningful execution. */ scheduler_attach_init_slave(dev); for (i = 0; i < sched_ctx->nb_slaves; i++) { uint8_t slave_dev_id = sched_ctx->slaves[i].dev_id; struct rte_cryptodev_info slave_info; rte_cryptodev_info_get(slave_dev_id, &slave_info); max_nb_sessions = slave_info.sym.max_nb_sessions < max_nb_sessions ? slave_info.sym.max_nb_sessions : max_nb_sessions; } dev_info->driver_id = dev->driver_id; dev_info->feature_flags = dev->feature_flags; dev_info->capabilities = sched_ctx->capabilities; dev_info->max_nb_queue_pairs = sched_ctx->max_nb_queue_pairs; dev_info->sym.max_nb_sessions = max_nb_sessions; }
/** Get device info */ static void scheduler_pmd_info_get(struct rte_cryptodev *dev, struct rte_cryptodev_info *dev_info) { struct scheduler_ctx *sched_ctx = dev->data->dev_private; uint32_t max_nb_sess = 0; uint16_t headroom_sz = 0; uint16_t tailroom_sz = 0; uint32_t i; if (!dev_info) return; /* although scheduler_attach_init_slave presents multiple times, * there will be only 1 meaningful execution. */ scheduler_attach_init_slave(dev); for (i = 0; i < sched_ctx->nb_slaves; i++) { uint8_t slave_dev_id = sched_ctx->slaves[i].dev_id; struct rte_cryptodev_info slave_info; rte_cryptodev_info_get(slave_dev_id, &slave_info); uint32_t dev_max_sess = slave_info.sym.max_nb_sessions; if (dev_max_sess != 0) { if (max_nb_sess == 0 || dev_max_sess < max_nb_sess) max_nb_sess = slave_info.sym.max_nb_sessions; } /* Get the max headroom requirement among slave PMDs */ headroom_sz = slave_info.min_mbuf_headroom_req > headroom_sz ? slave_info.min_mbuf_headroom_req : headroom_sz; /* Get the max tailroom requirement among slave PMDs */ tailroom_sz = slave_info.min_mbuf_tailroom_req > tailroom_sz ? slave_info.min_mbuf_tailroom_req : tailroom_sz; } dev_info->driver_id = dev->driver_id; dev_info->feature_flags = dev->feature_flags; dev_info->capabilities = sched_ctx->capabilities; dev_info->max_nb_queue_pairs = sched_ctx->max_nb_queue_pairs; dev_info->min_mbuf_headroom_req = headroom_sz; dev_info->min_mbuf_tailroom_req = tailroom_sz; dev_info->sym.max_nb_sessions = max_nb_sess; }
/** Setup a queue pair */ static int scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, const struct rte_cryptodev_qp_conf *qp_conf, int socket_id, struct rte_mempool *session_pool) { struct scheduler_ctx *sched_ctx = dev->data->dev_private; struct scheduler_qp_ctx *qp_ctx; char name[RTE_CRYPTODEV_NAME_MAX_LEN]; uint32_t i; int ret; if (snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "CRYTO_SCHE PMD %u QP %u", dev->data->dev_id, qp_id) < 0) { CS_LOG_ERR("Failed to create unique queue pair name"); return -EFAULT; } /* Free memory prior to re-allocation if needed. */ if (dev->data->queue_pairs[qp_id] != NULL) scheduler_pmd_qp_release(dev, qp_id); for (i = 0; i < sched_ctx->nb_slaves; i++) { uint8_t slave_id = sched_ctx->slaves[i].dev_id; /* * All slaves will share the same session mempool * for session-less operations, so the objects * must be big enough for all the drivers used. */ ret = rte_cryptodev_queue_pair_setup(slave_id, qp_id, qp_conf, socket_id, session_pool); if (ret < 0) return ret; } /* Allocate the queue pair data structure. */ qp_ctx = rte_zmalloc_socket(name, sizeof(*qp_ctx), RTE_CACHE_LINE_SIZE, socket_id); if (qp_ctx == NULL) return -ENOMEM; /* The actual available object number = nb_descriptors - 1 */ qp_ctx->max_nb_objs = qp_conf->nb_descriptors - 1; dev->data->queue_pairs[qp_id] = qp_ctx; /* although scheduler_attach_init_slave presents multiple times, * there will be only 1 meaningful execution. */ ret = scheduler_attach_init_slave(dev); if (ret < 0) { CS_LOG_ERR("Failed to attach slave"); scheduler_pmd_qp_release(dev, qp_id); return ret; } if (*sched_ctx->ops.config_queue_pair) { if ((*sched_ctx->ops.config_queue_pair)(dev, qp_id) < 0) { CS_LOG_ERR("Unable to configure queue pair"); return -1; } } return 0; }
/** Start device */ static int scheduler_pmd_start(struct rte_cryptodev *dev) { struct scheduler_ctx *sched_ctx = dev->data->dev_private; uint32_t i; int ret; if (dev->data->dev_started) return 0; /* although scheduler_attach_init_slave presents multiple times, * there will be only 1 meaningful execution. */ ret = scheduler_attach_init_slave(dev); if (ret < 0) return ret; for (i = 0; i < dev->data->nb_queue_pairs; i++) { ret = update_order_ring(dev, i); if (ret < 0) { CS_LOG_ERR("Failed to update reorder buffer"); return ret; } } if (sched_ctx->mode == CDEV_SCHED_MODE_NOT_SET) { CS_LOG_ERR("Scheduler mode is not set"); return -1; } if (!sched_ctx->nb_slaves) { CS_LOG_ERR("No slave in the scheduler"); return -1; } RTE_FUNC_PTR_OR_ERR_RET(*sched_ctx->ops.slave_attach, -ENOTSUP); for (i = 0; i < sched_ctx->nb_slaves; i++) { uint8_t slave_dev_id = sched_ctx->slaves[i].dev_id; if ((*sched_ctx->ops.slave_attach)(dev, slave_dev_id) < 0) { CS_LOG_ERR("Failed to attach slave"); return -ENOTSUP; } } RTE_FUNC_PTR_OR_ERR_RET(*sched_ctx->ops.scheduler_start, -ENOTSUP); if ((*sched_ctx->ops.scheduler_start)(dev) < 0) { CS_LOG_ERR("Scheduler start failed"); return -1; } /* start all slaves */ for (i = 0; i < sched_ctx->nb_slaves; i++) { uint8_t slave_dev_id = sched_ctx->slaves[i].dev_id; struct rte_cryptodev *slave_dev = rte_cryptodev_pmd_get_dev(slave_dev_id); ret = (*slave_dev->dev_ops->dev_start)(slave_dev); if (ret < 0) { CS_LOG_ERR("Failed to start slave dev %u", slave_dev_id); return ret; } } return 0; }