[dpdk-dev] [RFC PATCH v2 3/3] cryptodev: added asym queue pair and session apis

Trahe, Fiona fiona.trahe at intel.com
Wed May 24 13:48:39 CEST 2017


Hi Umesh,


> -----Original Message-----
> From: Umesh Kartha [mailto:Umesh.Kartha at caviumnetworks.com]
> Sent: Thursday, May 11, 2017 1:36 PM
> To: dev at dpdk.org
> Cc: Jerin Jacob <Jerin.JacobKollanukkaran at cavium.com>; Balasubramanian Manoharan
> <Balasubramanian.Manoharan at cavium.com>; Ram Kumar <Ram.Kumar at cavium.com>; Murthy
> Nidadavolu <Nidadavolu.Murthy at cavium.com>; Doherty, Declan <declan.doherty at intel.com>; De Lara
> Guarch, Pablo <pablo.de.lara.guarch at intel.com>; Trahe, Fiona <fiona.trahe at intel.com>
> Subject: [RFC PATCH v2 3/3] cryptodev: added asym queue pair and session apis
> 
> Added asymmetric operation queue pairs to device file. Added asymmetric
> session creation/initialisation/deletion APIs. Added asymmetric queue
> pair APIs to device ops. Added APIs to attach asym session to queue
> pairs.
> 
> Signed-off-by: Umesh Kartha <Umesh.Kartha at caviumnetworks.com>
> ---
>  lib/librte_cryptodev/rte_cryptodev.c     | 352 ++++++++++++++++++++++++++++++-
>  lib/librte_cryptodev/rte_cryptodev.h     |  80 +++++++
>  lib/librte_cryptodev/rte_cryptodev_pmd.h | 113 ++++++++++
>  3 files changed, 544 insertions(+), 1 deletion(-)
> 
> diff --git lib/librte_cryptodev/rte_cryptodev.c lib/librte_cryptodev/rte_cryptodev.c
> index abcdeb0..d4e943c 100644
> --- lib/librte_cryptodev/rte_cryptodev.c
> +++ lib/librte_cryptodev/rte_cryptodev.c
> @@ -1242,6 +1242,15 @@ struct rte_cryptodev *
>  	return dev->data->nb_queue_pairs;
>  }
> 
> +uint16_t
> +rte_cryptodev_asym_queue_pair_count(uint8_t dev_id)
> +{
> +	struct rte_cryptodev *dev;
> +
> +	dev = &rte_crypto_devices[dev_id];
> +	return dev->data->asym_nb_queue_pairs;
> +}

[Fiona] General comment:
Where duplicating functions and params for asym support I think the existing 
fn/param should be renamed to indicate it's now explicitly used for sym service.
e.g. 
rte_cryptodev_queue_pair_count should be changed to 
rte_cryptodev_sym_queue_pair_count 
rte_cryptodev_config.nb_queue_pairs should be .nb_sym_queue_pairs
etc.
And this should be flagged as an API breakage.

An alternative to duplicating all the APIs would be to create a separate PMD for the
asymmetric crypto service.
The following RFC proposes a way of doing this
http://dpdk.org/ml/archives/dev/2017-May/065515.html
These are not mutually exclusive solutions. 
Duplicating the APIs has the advantage of enabling both sym and asym services to be 
included in same PMD, but there are some indexing issues, see my comments below.

> +
>  static int
>  rte_cryptodev_queue_pairs_config(struct rte_cryptodev *dev, uint16_t nb_qpairs,
>  		int socket_id)
> @@ -1320,6 +1329,87 @@ struct rte_cryptodev *
>  	return 0;
>  }
> 
> +static int
> +rte_cryptodev_asym_queue_pairs_config(struct rte_cryptodev *dev,
> +		uint16_t nb_qpairs, int socket_id)
> +{
> +	struct rte_cryptodev_info dev_info;
> +	void **qp;
> +	unsigned i;
> +	uint16_t sym_nb_qps = dev->data->nb_queue_pairs;
> +
> +	if ((dev == NULL) || (nb_qpairs < 1)) {
> +		CDEV_LOG_ERR("invalid param: dev %p, nb_queues %u",
> +							dev, nb_qpairs);
> +		return -EINVAL;
> +	}
> +
> +	CDEV_LOG_DEBUG("Setup asym %d queues pairs on device %u",
> +			nb_qpairs, dev->data->dev_id);
> +
> +	memset(&dev_info, 0, sizeof(struct rte_cryptodev_info));
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
> +	(*dev->dev_ops->dev_infos_get)(dev, &dev_info);
> +
> +	if ((nb_qpairs + sym_nb_qps) > (dev_info.max_nb_queue_pairs)) {
> +		CDEV_LOG_ERR("Invalid num asym queue_pairs (%u) for dev %u",
> +				nb_qpairs, dev->data->dev_id);
> +		return -EINVAL;
> +	}
> +
[Fiona] This check assumes that the max_nb_queue_pairs on a device can be allocated to any 
mix of sym or asym. This is not necessarily the case. Some may have a fixed max per
service. So there's a need for a max_sym_nb_queues and max_asym_nb_queues
which should also be checked. 


> +	if (dev->data->asym_queue_pairs == NULL) {
> +		/* first time configuration */
> +		dev->data->asym_queue_pairs = rte_zmalloc_socket(
> +			"cryptodev->queue_pairs",
> +			sizeof(dev->data->asym_queue_pairs[0]) * nb_qpairs,
> +			RTE_CACHE_LINE_SIZE, socket_id);
> +
> +		if (dev->data->asym_queue_pairs == NULL) {
> +			dev->data->asym_nb_queue_pairs = 0;
> +			CDEV_LOG_ERR("failed to get memory for asym "
> +				     "qp meta data, "
> +					"nb_queues %u",
> +					nb_qpairs);
> +			return -(ENOMEM);
> +		}
> +	} else { /* re-configure */
> +		int ret;
> +		uint16_t old_nb_queues = dev->data->asym_nb_queue_pairs;
> +
> +		qp = dev->data->asym_queue_pairs;
> +
> +		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_release,
> +				-ENOTSUP);
> +
> +		for (i = nb_qpairs; i < old_nb_queues; i++) {
> +			ret = (*dev->dev_ops->queue_pair_release)(dev, i);
[Fiona] This should call asym_queue_pair_release

> +			if (ret < 0)
> +				return ret;
> +		}
> +
> +		qp = rte_realloc(qp, sizeof(qp[0]) * nb_qpairs,
> +				RTE_CACHE_LINE_SIZE);
> +		if (qp == NULL) {
> +			CDEV_LOG_ERR("failed to realloc asym qp meta data,"
> +						" nb_queues %u", nb_qpairs);
> +			return -(ENOMEM);
> +		}
> +
> +		if (nb_qpairs > old_nb_queues) {
> +			uint16_t new_qs = nb_qpairs - old_nb_queues;
> +
> +			memset(qp + old_nb_queues, 0,
> +				sizeof(qp[0]) * new_qs);
> +		}
> +
> +		dev->data->asym_queue_pairs = qp;
> +
> +	}
> +	dev->data->asym_nb_queue_pairs = nb_qpairs;
> +	return 0;
> +}
> +
>  int
>  rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id)
>  {
> @@ -1368,6 +1458,10 @@ struct rte_cryptodev *
>  rte_cryptodev_sym_session_pool_create(struct rte_cryptodev *dev,
>  		unsigned nb_objs, unsigned obj_cache_size, int socket_id);
> 
> +static int
> +rte_cryptodev_asym_session_pool_create(struct rte_cryptodev *dev,
> +		unsigned nb_objs, unsigned obj_cache_size, int socket_id);
> +
[Fiona] session pool for sym is proposed to change from device-specific pool to 
device-agnostic pool in 17.08 release. It would be better for asym session pool
to follow this model. See
http://dpdk.org/ml/archives/dev/2017-May/065259.html

 

>  int
>  rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
>  {
> @@ -1398,6 +1492,16 @@ struct rte_cryptodev *
>  		return diag;
>  	}
> 
> +	/* Setup new number of asym queue pairs and reconfigure device. */
> +	diag = rte_cryptodev_asym_queue_pairs_config(dev,
> +			config->asym_nb_queue_pairs, config->socket_id);
> +	if (diag != 0) {
> +		CDEV_LOG_ERR("dev%d rte_crypto_dev_asym_queue_pairs_config"
> +				" = %d",
> +				dev_id, diag);
> +		return diag;
> +	}
> +
>  	/* Setup Session mempool for device */
>  	diag = rte_cryptodev_sym_session_pool_create(dev,
>  			config->session_mp.nb_objs,
> @@ -1406,6 +1510,15 @@ struct rte_cryptodev *
>  	if (diag != 0)
>  		return diag;
> 
> +	/* Setup Session mempool for device */
> +	diag = rte_cryptodev_asym_session_pool_create(dev,
> +			config->asym_session_mp.nb_objs,
> +			config->asym_session_mp.cache_size,
> +			config->socket_id);
> +	if (diag != 0)
> +		return diag;
> +
> +
>  	return (*dev->dev_ops->dev_configure)(dev, config);
>  }
> 
> @@ -1496,6 +1609,16 @@ struct rte_cryptodev *
>  			return -EBUSY;
>  		}
>  	}
> +	if (dev->data->asym_session_pool != NULL) {
> +		if (!rte_mempool_full(dev->data->asym_session_pool)) {
> +			CDEV_LOG_ERR("dev_id=%u close failed, session mempool "
> +					"has sessions still in use, free "
> +					"all sessions before calling close",
> +					(unsigned)dev_id);
> +			return -EBUSY;
> +		}
> +	}
> +
> 
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
>  	retval = (*dev->dev_ops->dev_close)(dev);
> @@ -1535,6 +1658,35 @@ struct rte_cryptodev *
>  			socket_id);
>  }
> 
> +int
> +rte_cryptodev_asym_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
> +		const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
> +{
> +	struct rte_cryptodev *dev;
> +
> +	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
> +		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
> +		return -EINVAL;
> +	}
> +
> +	dev = &rte_crypto_devices[dev_id];
> +	if (queue_pair_id >= dev->data->asym_nb_queue_pairs) {
> +		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
> +		return -EINVAL;
> +	}
[Fiona] Doesn't this give a problem with indexing? On the enqueue/dequeue?
i.e. if 2 asym qps and 2 sym qps are created on the same device, the queue_pair_ids
are duplicated. In rte_cryptodev_enqueue_burst(dev_id, qp_id, ....) the lib
uses the qp_id to call the dev_op fn. How do you propose it should route to the
correct qp? Unwrapping the first op to find whether it's a sym or asym op would be 
undesirable as performance impacting. And assumes every op in the burst is the same
type, which is probably valid, but should be stated.

One alternative is to use different qp_ids for sym and asym.
Remove the queue_pair_id from the xxx_queue_pair_setup fns
and instead return the  id. So e.g. if sym_queue_pair_setup() is called, then
asym_queue_pair_setup(), then sym_queue_pair_setup() qp_id 0 and 2 would be 
sym qps and qp_id 1 would be an asym qp.
Instead of separate dev->data->asym_queue_pairs and dev->data->sym_queue_pairs 
arrays there would be one common array.

Another alternative is to use separate APIs i.e. rte_cryptodev_sym_enqueue_burst
rte_cryptodev_asym_enqueue_burst.

In either case, if each qp can handle only a specific service, i.e. a subset off the capabilities 
Indicated by the device capability list, there's a need for a new API to query
the capability of a qp.

> +
> +	if (dev->data->dev_started) {
> +		CDEV_LOG_ERR(
> +		    "device %d must be stopped to allow configuration", dev_id);
> +		return -EBUSY;
> +	}
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_setup, -ENOTSUP);
> +
> +	return (*dev->dev_ops->asym_queue_pair_setup)(dev, queue_pair_id,
> +			qp_conf, socket_id);
> +}
> +
> 
>  int
>  rte_cryptodev_stats_get(uint8_t dev_id, struct rte_cryptodev_stats *stats)
> @@ -1730,6 +1882,25 @@ struct rte_cryptodev *
>  		(*dev->dev_ops->session_initialize)(mp, sess);
>  }
[Fiona] Should stats be per asym/sym? 
A per-service stat seems like a more useful number.

> 
> +static void
> +rte_cryptodev_asym_session_init(struct rte_mempool *mp,
> +		void *opaque_arg,
> +		void *_sess,
> +		__rte_unused unsigned i)
> +{
> +	struct rte_cryptodev_asym_session *sess = _sess;
> +	struct rte_cryptodev *dev = opaque_arg;
> +
> +	memset(sess, 0, mp->elt_size);
> +
> +	sess->dev_id = dev->data->dev_id;
> +	sess->dev_type = dev->dev_type;
> +	sess->mp = mp;
> +
> +	if (dev->dev_ops->asym_session_initialize)
> +		(*dev->dev_ops->asym_session_initialize)(mp, sess);
> +}
> +
>  static int
>  rte_cryptodev_sym_session_pool_create(struct rte_cryptodev *dev,
>  		unsigned nb_objs, unsigned obj_cache_size, int socket_id)
> @@ -1792,6 +1963,70 @@ struct rte_cryptodev *
>  	return 0;
>  }
> 
> +static int
> +rte_cryptodev_asym_session_pool_create(struct rte_cryptodev *dev,
> +		unsigned nb_objs, unsigned obj_cache_size, int socket_id)
> +{
> +	char mp_name[RTE_CRYPTODEV_NAME_MAX_LEN];
> +	unsigned priv_sess_size;
> +
> +	unsigned n = snprintf(mp_name, sizeof(mp_name), "cdev_%d_sess_mp",
> +			dev->data->dev_id);
> +	if (n > sizeof(mp_name)) {
> +		CDEV_LOG_ERR("Unable to create unique name for"
> +			     " session mempool");
> +		return -ENOMEM;
> +	}
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_session_get_size,
> +				-ENOTSUP);
> +	priv_sess_size = (*dev->dev_ops->asym_session_get_size)(dev);
> +	if (priv_sess_size == 0) {
> +		CDEV_LOG_ERR("%s returned and invalid private session size ",
> +						dev->data->name);
> +		return -ENOMEM;
> +	}
> +
> +	unsigned elt_size = sizeof(struct rte_cryptodev_asym_session) +
> +			priv_sess_size;
> +
> +	dev->data->asym_session_pool = rte_mempool_lookup(mp_name);
> +	if (dev->data->asym_session_pool != NULL) {
> +		if ((dev->data->asym_session_pool->elt_size != elt_size) ||
> +			(dev->data->asym_session_pool->cache_size <
> +			obj_cache_size) ||
> +			(dev->data->asym_session_pool->size < nb_objs)) {
> +
> +			CDEV_LOG_ERR("%s mempool already exists with different"
> +					" initialization parameters", mp_name);
> +			dev->data->asym_session_pool = NULL;
> +			return -ENOMEM;
> +		}
> +	} else {
> +		dev->data->asym_session_pool = rte_mempool_create(
> +				mp_name, /* mempool name */
> +				nb_objs, /* number of elements*/
> +				elt_size, /* element size*/
> +				obj_cache_size, /* Cache size*/
> +				0, /* private data size */
> +				NULL, /* obj initialization constructor */
> +				NULL, /* obj initialization constructor arg */
> +				rte_cryptodev_asym_session_init,
> +				/**< obj constructor*/
> +				dev, /* obj constructor arg */
> +				socket_id, /* socket id */
> +				0); /* flags */
> +
> +		if (dev->data->asym_session_pool == NULL) {
> +			CDEV_LOG_ERR("%s mempool allocation failed", mp_name);
> +			return -ENOMEM;
> +		}
> +	}
> +
> +	CDEV_LOG_DEBUG("%s mempool created!", mp_name);
> +	return 0;
> +}
> +
>  struct rte_cryptodev_sym_session *
>  rte_cryptodev_sym_session_create(uint8_t dev_id,
>  		struct rte_crypto_sym_xform *xform)
> @@ -1829,6 +2064,43 @@ struct rte_cryptodev_sym_session *
>  	return sess;
>  }
> 
> +struct rte_cryptodev_asym_session *
> +rte_cryptodev_asym_session_create(uint8_t dev_id,
> +		struct rte_crypto_asym_xform *xform)
> +{
> +	struct rte_cryptodev *dev;
> +	struct rte_cryptodev_asym_session *sess;
> +	void *_sess;
> +
> +	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
> +		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
> +		return NULL;
> +	}
> +
> +	dev = &rte_crypto_devices[dev_id];
> +
> +	/* Allocate a session structure from the session pool */
> +	if (rte_mempool_get(dev->data->asym_session_pool, &_sess)) {
> +		CDEV_LOG_ERR("Couldn't get object from session mempool");
> +		return NULL;
> +	}
> +
> +	sess = (struct rte_cryptodev_asym_session *)_sess;
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->session_configure, NULL);
> +	if (dev->dev_ops->asym_session_configure(dev, xform, sess->_private) ==
> +			NULL) {
> +		CDEV_LOG_ERR("dev_id %d failed to configure session details",
> +				dev_id);
> +
> +		/* Return session to mempool */
> +		rte_mempool_put(sess->mp, _sess);
> +		return NULL;
> +	}
> +
> +	return sess;
> +}
> +
>  int
>  rte_cryptodev_queue_pair_attach_sym_session(uint16_t qp_id,
>  		struct rte_cryptodev_sym_session *sess)
> @@ -1854,6 +2126,30 @@ struct rte_cryptodev_sym_session *
>  }
> 
>  int
> +rte_cryptodev_queue_pair_attach_asym_session(uint16_t qp_id,
> +		struct rte_cryptodev_asym_session *sess)
> +{
> +	struct rte_cryptodev *dev;
> +
> +	if (!rte_cryptodev_pmd_is_valid_dev(sess->dev_id)) {
> +		CDEV_LOG_ERR("Invalid dev_id=%d", sess->dev_id);
> +		return -EINVAL;
> +	}
> +
> +	dev = &rte_crypto_devices[sess->dev_id];
> +
> +	/* The API is optional, not returning error if driver do not suuport */
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_qp_attach_session, 0);
> +	if (dev->dev_ops->asym_qp_attach_session(dev, qp_id, sess->_private)) {
> +		CDEV_LOG_ERR("dev_id %d failed to attach qp: %d with session",
> +				sess->dev_id, qp_id);
> +		return -EPERM;
> +	}
> +
> +	return 0;
> +}
> +
> +int
>  rte_cryptodev_queue_pair_detach_sym_session(uint16_t qp_id,
>  		struct rte_cryptodev_sym_session *sess)
>  {
> @@ -1876,6 +2172,31 @@ struct rte_cryptodev_sym_session *
> 
>  	return 0;
>  }
> +
> +int
> +rte_cryptodev_queue_pair_detach_asym_session(uint16_t qp_id,
> +		struct rte_cryptodev_asym_session *sess)
> +{
> +	struct rte_cryptodev *dev;
> +
> +	if (!rte_cryptodev_pmd_is_valid_dev(sess->dev_id)) {
> +		CDEV_LOG_ERR("Invalid dev_id=%d", sess->dev_id);
> +		return -EINVAL;
> +	}
> +
> +	dev = &rte_crypto_devices[sess->dev_id];
> +
> +	/* The API is optional, not returning error if driver do not suuport */
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_qp_detach_session, 0);
> +	if (dev->dev_ops->asym_qp_detach_session(dev, qp_id, sess->_private)) {
> +		CDEV_LOG_ERR("dev_id %d failed to detach qp: %d from session",
> +				sess->dev_id, qp_id);
> +		return -EPERM;
> +	}
> +
> +	return 0;
> +}
> +
>  struct rte_cryptodev_sym_session *
>  rte_cryptodev_sym_session_free(uint8_t dev_id,
>  		struct rte_cryptodev_sym_session *sess)
> @@ -1903,6 +2224,33 @@ struct rte_cryptodev_sym_session *
>  	return NULL;
>  }
> 
> +struct rte_cryptodev_asym_session *
> +rte_cryptodev_asym_session_free(uint8_t dev_id,
> +		struct rte_cryptodev_asym_session *sess)
> +{
> +	struct rte_cryptodev *dev;
> +
> +	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
> +		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
> +		return sess;
> +	}
> +
> +	dev = &rte_crypto_devices[dev_id];
> +
> +	/* Check the session belongs to this device type */
> +	if (sess->dev_type != dev->dev_type)
> +		return sess;
> +
> +	/* Let device implementation clear session material */
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_session_clear, sess);
> +	dev->dev_ops->asym_session_clear(dev, (void *)sess->_private);
> +
> +	/* Return session to mempool */
> +	rte_mempool_put(sess->mp, (void *)sess);
> +
> +	return NULL;
> +}
> +
>  /** Initialise rte_crypto_op mempool element */
>  static void
>  rte_crypto_op_init(struct rte_mempool *mempool,
> @@ -1930,7 +2278,9 @@ struct rte_mempool *
>  	struct rte_crypto_op_pool_private *priv;
> 
>  	unsigned elt_size = sizeof(struct rte_crypto_op) +
> -			sizeof(struct rte_crypto_sym_op) +
> +			(type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) ?
> +			sizeof(struct rte_crypto_sym_op) :
> +			sizeof(struct rte_crypto_asym_op) +
>  			priv_size;
> 
>  	/* lookup mempool in case already allocated */
> diff --git lib/librte_cryptodev/rte_cryptodev.h lib/librte_cryptodev/rte_cryptodev.h
> index f5f5a73..edfd8fd 100644
> --- lib/librte_cryptodev/rte_cryptodev.h
> +++ lib/librte_cryptodev/rte_cryptodev.h
> @@ -674,6 +674,11 @@ struct rte_cryptodev_info {
>  		 * Default 0 for infinite sessions
>  		 */
>  	} sym;
> +
> +	struct {
> +		unsigned max_nb_sessions;
> +		/**< Maximum number of sessions supported by device. */
> +	} asym;
>  };
> 
>  #define RTE_CRYPTODEV_DETACHED  (0)
> @@ -827,11 +832,18 @@ struct rte_cryptodev_config {
>  	int socket_id;			/**< Socket to allocate resources on */
>  	uint16_t nb_queue_pairs;
>  	/**< Number of queue pairs to configure on device */
> +	uint16_t asym_nb_queue_pairs;
> +	/**< Number of asym_queue pairs to configure on device */
> 
>  	struct {
>  		uint32_t nb_objs;	/**< Number of objects in mempool */
>  		uint32_t cache_size;	/**< l-core object cache size */
>  	} session_mp;		/**< Session mempool configuration */
> +
> +	struct {
> +		uint32_t nb_objs;	/**< Number of objects in mempool */
> +		uint32_t cache_size;	/**< l-core object cache size */
> +	} asym_session_mp;		/**< Session mempool configuration */
>  };
> 
>  /**
> @@ -1098,11 +1110,22 @@ struct rte_cryptodev_data {
> 
>  	struct rte_mempool *session_pool;
>  	/**< Session memory pool */
> +
> +	struct rte_mempool *asym_session_pool;
> +	/**< Asymmetric xform session memory pool */
> +
>  	void **queue_pairs;
>  	/**< Array of pointers to queue pairs. */
> +
> +	void **asym_queue_pairs;
> +	/**< Array of pointers to asymmetric queue pairs */
> +
>  	uint16_t nb_queue_pairs;
>  	/**< Number of device queue pairs. */
> 
> +	uint16_t asym_nb_queue_pairs;
> +	/**< Number of device queue pairs for asym ops */
> +
>  	void *dev_private;
>  	/**< PMD-specific private data */
>  } __rte_cache_aligned;
> @@ -1216,6 +1239,24 @@ struct rte_cryptodev_sym_session {
>  };
> 
> 
> +/** Cryptodev symmetric crypto session */
> +struct rte_cryptodev_asym_session {
> +	RTE_STD_C11
> +	struct {
> +		uint8_t dev_id;
> +		/**< Device Id */
> +		enum rte_cryptodev_type dev_type;
> +		/** Crypto Device type session created on */
> +		struct rte_mempool *mp;
> +		/**< Mempool session allocated from */
> +	} __rte_aligned(8);
> +	/**< Public asymmetric session details */
> +
> +	__extension__ char _private[0];
> +	/**< Private session material */
> +};
> +
> +
>  /**
>   * Initialise a session for symmetric cryptographic operations.
>   *
> @@ -1241,6 +1282,32 @@ struct rte_cryptodev_sym_session {
>  rte_cryptodev_sym_session_create(uint8_t dev_id,
>  		struct rte_crypto_sym_xform *xform);
> 
> +
> +/**
> + * Initialise a session for asymmetric cryptographic operations.
> + *
> + * This function is used by the client to initialize immutable
> + * parameters of asymmetric cryptographic operation.
> + * To perform the operation the rte_cryptodev_enqueue_burst function is
> + * used.  Each mbuf should contain a reference to the session
> + * pointer returned from this function contained within it's crypto_op if a
> + * session-based operation is being provisioned. Memory to contain the session
> + * information is allocated from within mempool managed by the cryptodev.
> + *
> + * The rte_cryptodev_session_free must be called to free allocated
> + * memory when the session is no longer required.
> + *
> + * @param	dev_id		The device identifier.
> + * @param	xform		Crypto transform chain.
> +
> + *
> + * @return
> + *  Pointer to the created session or NULL
> + */
> +extern struct rte_cryptodev_asym_session *
> +rte_cryptodev_asym_session_create(uint8_t dev_id,
> +		struct rte_crypto_asym_xform *xform);
> +
>  /**
>   * Free the memory associated with a previously allocated session.
>   *
> @@ -1257,6 +1324,19 @@ struct rte_cryptodev_sym_session {
>  		struct rte_cryptodev_sym_session *session);
> 
>  /**
> + * Free the memory associated with a previously allocated session.
> + *
> + * @param	dev_id		The device identifier.
> + * @param	session		Session pointer previously allocated by
> + *				*rte_cryptodev_asym_session_create*.
> + *
> + * @return
> + *   NULL on successful freeing of session.
> + *   Session pointer on failure to free session.
> + */
> +extern struct rte_cryptodev_asym_session *
> +rte_cryptodev_asym_session_free(uint8_t dev_id,
> +		struct rte_cryptodev_asym_session *session);
>   * Attach queue pair with sym session.
>   *
>   * @param	qp_id		Queue pair to which session will be attached.
> diff --git lib/librte_cryptodev/rte_cryptodev_pmd.h lib/librte_cryptodev/rte_cryptodev_pmd.h
> index 17ef37c..31c5804 100644
> --- lib/librte_cryptodev/rte_cryptodev_pmd.h
> +++ lib/librte_cryptodev/rte_cryptodev_pmd.h
> @@ -327,6 +327,22 @@ typedef int (*cryptodev_sym_create_session_pool_t)(
>  		struct rte_cryptodev *dev, unsigned nb_objs,
>  		unsigned obj_cache_size, int socket_id);
> 
> +/**
> + * Create asymmetric session mempool to allocate sessions from
> + *
> + * @param	dev		Crypto device pointer
> + * @param	nb_objs		number of sessions objects in mempool
> + * @param	obj_cache	l-core object cache size, see *rte_ring_create*
> + * @param	socket_id	Socket Id to allocate  mempool on.
> + *
> + * @return
> + * - On success returns a pointer to a rte_mempool
> + * - On failure returns a NULL pointer
> + */
> +typedef int (*cryptodev_asym_create_session_pool_t)(
> +		struct rte_cryptodev *dev, unsigned nb_objs,
> +		unsigned obj_cache_size, int socket_id);
> +
> 
>  /**
>   * Get the size of a cryptodev session
> @@ -341,6 +357,18 @@ typedef unsigned (*cryptodev_sym_get_session_private_size_t)(
>  		struct rte_cryptodev *dev);
> 
>  /**
> + * Get the size of an asymmetric cryptodev session
> + *
> + * @param	dev		Crypto device pointer
> + *
> + * @return
> + *  - On success returns the size of the session structure for device
> + *  - On failure returns 0
> + */
> +typedef unsigned (*cryptodev_asym_get_session_private_size_t)(
> +		struct rte_cryptodev *dev);
> +
> +/**
>   * Initialize a Crypto session on a device.
>   *
>   * @param	dev		Crypto device pointer
> @@ -355,6 +383,20 @@ typedef void (*cryptodev_sym_initialize_session_t)(struct rte_mempool
> *mempool,
>  		void *session_private);
> 
>  /**
> + * Initialize an asymmetric  Crypto session on a device.
> + *
> + * @param	dev		Crypto device pointer
> + * @param	xform		Single or chain of crypto xforms
> + * @param	priv_sess	Pointer to cryptodev's private session structure
> + *
> + * @return
> + *  - Returns private session structure on success.
> + *  - Returns NULL on failure.
> + */
> +typedef void (*cryptodev_asym_initialize_session_t)(struct rte_mempool *mempool,
> +		void *session_private);
> +
> +/**
>   * Configure a Crypto session on a device.
>   *
>   * @param	dev		Crypto device pointer
> @@ -369,6 +411,20 @@ typedef void (*cryptodev_sym_initialize_session_t)(struct rte_mempool
> *mempool,
>  		struct rte_crypto_sym_xform *xform, void *session_private);
> 
>  /**
> + * Configure an asymmetric Crypto session on a device.
> + *
> + * @param	dev		Crypto device pointer
> + * @param	xform		Single or chain of asymmetric crypto xforms
> + * @param	priv_sess	Pointer to cryptodev's private session structure
> + *
> + * @return
> + *  - Returns private session structure on success.
> + *  - Returns NULL on failure.
> + */
> +typedef void *(*cryptodev_asym_configure_session_t)(struct rte_cryptodev *dev,
> +		struct rte_crypto_asym_xform *xform, void *session_private);
> +
> +/**
>   * Free Crypto session.
>   * @param	session		Cryptodev session structure to free
>   */
> @@ -376,6 +432,13 @@ typedef void (*cryptodev_sym_free_session_t)(struct rte_cryptodev *dev,
>  		void *session_private);
> 
>  /**
> + * Free asymmetric Crypto session.
> + * @param	session		Cryptodev session structure to free
> + */
> +typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev *dev,
> +		void *session_private);
> +
> +/**
>   * Optional API for drivers to attach sessions with queue pair.
>   * @param	dev		Crypto device pointer
>   * @param	qp_id		queue pair id for attaching session
> @@ -389,6 +452,19 @@ typedef int (*cryptodev_sym_queue_pair_attach_session_t)(
>  		  void *session_private);
> 
>  /**
> + * Optional API for drivers to attach asymmetric sessions with queue pair.
> + * @param	dev		Crypto device pointer
> + * @param	qp_id		queue pair id for attaching session
> + * @param	priv_sess       Pointer to cryptodev's private session structure
> + * @return
> + *  - Return 0 on success
> + */
> +typedef int (*cryptodev_asym_queue_pair_attach_session_t)(
> +		  struct rte_cryptodev *dev,
> +		  uint16_t qp_id,
> +		  void *session_private);
> +
> +/**
>   * Optional API for drivers to detach sessions from queue pair.
>   * @param	dev		Crypto device pointer
>   * @param	qp_id		queue pair id for detaching session
> @@ -401,6 +477,20 @@ typedef int (*cryptodev_sym_queue_pair_detach_session_t)(
>  		  uint16_t qp_id,
>  		  void *session_private);
> 
> +/**
> + * Optional API for drivers to detach asymmetric sessions from queue pair.
> + * @param	dev		Crypto device pointer
> + * @param	qp_id		queue pair id for detaching session
> + * @param	priv_sess       Pointer to cryptodev's private session
> + *				structure.
> + * @return
> + *  - Return 0 on success
> + */
> +typedef int (*cryptodev_asym_queue_pair_detach_session_t)(
> +		  struct rte_cryptodev *dev,
> +		  uint16_t qp_id,
> +		  void *session_private);
> +
>  /** Crypto device operations function pointer table */
>  struct rte_cryptodev_ops {
>  	cryptodev_configure_t dev_configure;	/**< Configure device. */
> @@ -426,18 +516,41 @@ struct rte_cryptodev_ops {
>  	cryptodev_queue_pair_count_t queue_pair_count;
>  	/**< Get count of the queue pairs. */
> 
> +	cryptodev_queue_pair_setup_t asym_queue_pair_setup;
> +	/**< Set up a device queue pair. */
> +	cryptodev_queue_pair_release_t asym_queue_pair_release;
> +	/**< Release a queue pair. */
> +	cryptodev_queue_pair_start_t asym_queue_pair_start;
> +	/**< Start a queue pair. */
> +	cryptodev_queue_pair_stop_t asym_queue_pair_stop;
> +	/**< Stop a queue pair. */
> +	cryptodev_queue_pair_count_t asym_queue_pair_count;
> +	/**< Get count of the queue pairs. */
> +
[Fiona] The count fn isn't used at all for sym - probably no need to add for asym
better instead to remove the sym fn.

>  	cryptodev_sym_get_session_private_size_t session_get_size;
>  	/**< Return private session. */
> +	cryptodev_asym_get_session_private_size_t asym_session_get_size;
> +	/**< Return asymmetric private session. */
>  	cryptodev_sym_initialize_session_t session_initialize;
>  	/**< Initialization function for private session data */
> +	cryptodev_asym_initialize_session_t asym_session_initialize;
> +	/**< Initialization asymmetric function for private session data */
>  	cryptodev_sym_configure_session_t session_configure;
>  	/**< Configure a Crypto session. */
> +	cryptodev_asym_configure_session_t asym_session_configure;
> +	/**< Configure an Asymmetric Crypto session. */
>  	cryptodev_sym_free_session_t session_clear;
>  	/**< Clear a Crypto sessions private data. */
> +	cryptodev_asym_free_session_t asym_session_clear;
> +	/**< Clear an asymmetric  Crypto sessions private data. */
>  	cryptodev_sym_queue_pair_attach_session_t qp_attach_session;
>  	/**< Attach session to queue pair. */
> +	cryptodev_asym_queue_pair_attach_session_t asym_qp_attach_session;
> +	/**< Attach asymmetric session to queue pair. */
>  	cryptodev_sym_queue_pair_attach_session_t qp_detach_session;
>  	/**< Detach session from queue pair. */
> +	cryptodev_asym_queue_pair_attach_session_t asym_qp_detach_session;
> +	/**< Detach asymmetric session from queue pair. */
>  };
> 
> 
> --
> 1.8.3.1



More information about the dev mailing list