From patchwork Mon Nov 27 20:01:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fan Zhang X-Patchwork-Id: 31691 X-Patchwork-Delegate: yuanhan.liu@linux.intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id F23047CEA; Mon, 27 Nov 2017 21:03:11 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 071127CBA for ; Mon, 27 Nov 2017 21:03:08 +0100 (CET) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Nov 2017 12:03:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,465,1505804400"; d="scan'208";a="6889901" Received: from silpixa00398673.ir.intel.com (HELO silpixa00398673.ger.corp.intel.com) ([10.237.223.54]) by orsmga003.jf.intel.com with ESMTP; 27 Nov 2017 12:03:05 -0800 From: Fan Zhang To: dev@dpdk.org Cc: roy.fan.zhang@intel.com, yliu@fridaylinux.org, maxime.coquelin@redhat.com, tiwei.bie@intel.com Date: Mon, 27 Nov 2017 20:01:10 +0000 Message-Id: <20171127200115.31049-8-roy.fan.zhang@intel.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20171127200115.31049-1-roy.fan.zhang@intel.com> References: <20171127200115.31049-1-roy.fan.zhang@intel.com> Subject: [dpdk-dev] [PATCH 07/12] lib/librte_vhost: add public function implementation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch adds public API implementation to vhost crypto Signed-off-by: Fan Zhang --- lib/librte_vhost/vhost_crypto.c | 179 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c index d12a449..86e21ad 100644 --- a/lib/librte_vhost/vhost_crypto.c +++ b/lib/librte_vhost/vhost_crypto.c @@ -1133,3 +1133,182 @@ vhost_crypto_complete_one_vm_requests(struct rte_crypto_op **ops, return processed; } + + +int +rte_vhost_crypto_create(int vid, uint8_t cryptodev_id, + struct rte_mempool *sess_pool, int socket_id) +{ + struct virtio_net *dev = get_device(vid); + struct rte_hash_parameters params = {0}; + struct vhost_user_dev_priv *priv; + struct vhost_crypto *vcrypto; + char name[128]; + int ret; + + if (vid >= VIRTIO_CRYPTO_MAX_NUM_DEVS || !dev) { + VC_LOG_ERR("Invalid vid %i", vid); + return -EINVAL; + } + + ret = rte_vhost_driver_set_features(dev->ifname, + VIRTIO_CRYPTO_FEATURES); + if (ret < 0) { + VC_LOG_ERR("Error setting features"); + return -1; + } + + priv = rte_zmalloc_socket(NULL, sizeof(*priv) + sizeof(*vcrypto), + RTE_CACHE_LINE_SIZE, socket_id); + if (!priv) { + VC_LOG_ERR("Insufficient memory"); + return -ENOMEM; + } + + vcrypto = (struct vhost_crypto *)priv->data; + + vcrypto->sess_pool = sess_pool; + vcrypto->cid = cryptodev_id; + vcrypto->cache_session_id = UINT64_MAX; + vcrypto->last_session_id = 1; + + snprintf(name, 127, "HASH_VHOST_CRYPT_%u", (unsigned)vid); + params.name = name; + params.entries = SESSION_MAP_ENTRIES; + params.hash_func = rte_jhash; + params.key_len = sizeof(uint64_t); + params.socket_id = socket_id; + vcrypto->session_map = rte_hash_create(¶ms); + if (!vcrypto->session_map) { + VC_LOG_ERR("Failed to creath session map"); + ret = -ENOMEM; + goto error_exit; + } + + priv->vhost_user_msg_handler = vhost_crypto_msg_handler; + dev->private_data = (void *)priv; + + return 0; + +error_exit: + if (vcrypto->session_map) + rte_hash_free(vcrypto->session_map); + rte_free(priv); + + return ret; +} + +int +rte_vhost_crypto_free(int vid) +{ + struct virtio_net *dev = get_device(vid); + struct vhost_user_dev_priv *priv; + struct vhost_crypto *vcrypto; + + if (unlikely(dev == NULL)) { + VC_LOG_ERR("Invalid vid %i", vid); + return -EINVAL; + } + + priv = dev->private_data; + if (unlikely(priv == NULL)) { + VC_LOG_ERR("Cannot find required data, is it initialized?"); + return -ENOENT; + } + + vcrypto = (struct vhost_crypto *)priv->data; + if (unlikely(vcrypto == NULL)) { + VC_LOG_ERR("Cannot find required data, is it initialized?"); + return -ENOENT; + } + + rte_hash_free(vcrypto->session_map); + rte_free(priv); + dev->private_data = NULL; + + return 0; +} + +struct rte_mempool * +rte_vhost_crypto_create_cop_pool(const char *name, enum rte_crypto_op_type type, + unsigned nb_elts, unsigned cache_size, int socket_id) +{ + return rte_crypto_op_pool_create(name, type, nb_elts, cache_size, + VHOST_CRYPTO_MAX_IV_LEN + + sizeof(struct vhost_crypto_data_req), socket_id); +} + +uint16_t +rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, + struct rte_crypto_op **ops, uint16_t nb_ops) +{ + struct virtio_net *dev = get_device(vid); + struct vhost_user_dev_priv *priv; + struct rte_vhost_memory *mem; + struct vhost_crypto *vcrypto; + struct vhost_virtqueue *vq; + uint16_t avail_idx; + uint16_t start_idx; + uint16_t count; + uint16_t i; + + if (unlikely(dev == NULL)) { + VC_LOG_ERR("Invalid vid %i", vid); + return -EINVAL; + } + + priv = dev->private_data; + if (unlikely(priv == NULL)) { + VC_LOG_ERR("Cannot find required data, is it initialized?"); + return -ENOENT; + } + + vcrypto = (struct vhost_crypto *)priv->data; + if (unlikely(vcrypto == NULL)) { + VC_LOG_ERR("Cannot find required data, is it initialized?"); + return -ENOENT; + } + + vq = dev->virtqueue[qid]; + mem = dev->mem; + + avail_idx = *((volatile uint16_t *)&vq->avail->idx); + start_idx = vq->last_used_idx; + count = avail_idx - start_idx; + count = RTE_MIN(count, nb_ops); + + for (i = 0; i < count; i++) { + uint16_t used_idx = (start_idx + i) & (vq->size - 1); + uint16_t desc_idx = vq->avail->ring[used_idx]; + struct vring_desc *head = &vq->desc[desc_idx]; + uint32_t len; + + len = vhost_crypto_process_cop(vq, vcrypto, ops[i], head, + desc_idx, mem, vid); + if (unlikely(len == 0)) + break; + } + + vq->last_used_idx += i; + + return i; +} + +uint16_t +rte_vhost_crypto_finalize_requests(struct rte_crypto_op **ops, + __rte_unused uint32_t q_id, uint16_t nb_ops) +{ + struct rte_crypto_op **tmp_ops = ops; + uint16_t count = 0, left = nb_ops; + + while (left) { + count = vhost_crypto_complete_one_vm_requests(tmp_ops, left); + tmp_ops = &tmp_ops[count]; + left -= count; + + if (unlikely(count == 0)) + break; + } + + return nb_ops - left; +}