crypto/qat: add handling of multi process

Message ID 20200610190625.18780-1-arkadiuszx.kusztal@intel.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series crypto/qat: add handling of multi process |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/travis-robot success Travis build: passed
ci/iol-nxp-Performance success Performance Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-testing success Testing PASS

Commit Message

Arkadiusz Kusztal June 10, 2020, 7:06 p.m. UTC
  This patch improves handling of multi process applications
using Intel QuickAssist Technology PMD.

Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
---
 drivers/common/qat/qat_device.c     | 103 ++++++++++++++++++++++++------------
 drivers/common/qat/qat_device.h     |  69 +++++++++++++-----------
 drivers/common/qat/qat_qp.c         |  10 ++--
 drivers/compress/qat/qat_comp_pmd.c |  43 +++++++++++----
 drivers/compress/qat/qat_comp_pmd.h |   2 +
 drivers/crypto/qat/qat_asym.c       |   4 +-
 drivers/crypto/qat/qat_asym_pmd.c   |  62 +++++++++++++++++-----
 drivers/crypto/qat/qat_asym_pmd.h   |   4 +-
 drivers/crypto/qat/qat_sym.c        |   2 +-
 drivers/crypto/qat/qat_sym.h        |   2 +-
 drivers/crypto/qat/qat_sym_pmd.c    |  87 +++++++++++++++++++++++-------
 drivers/crypto/qat/qat_sym_pmd.h    |   4 +-
 12 files changed, 277 insertions(+), 115 deletions(-)
  

Comments

Fiona Trahe June 11, 2020, 1:56 p.m. UTC | #1
Hi Arek,

> -----Original Message-----
> From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> Sent: Wednesday, June 10, 2020 8:06 PM
> To: dev@dpdk.org
> Cc: akhil.goyal@nxp.com; Trahe, Fiona <fiona.trahe@intel.com>; Kusztal, ArkadiuszX
> <arkadiuszx.kusztal@intel.com>
> Subject: [PATCH] crypto/qat: add handling of multi process
> 
> This patch improves handling of multi process applications
> using Intel QuickAssist Technology PMD.
> 
> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> ---
>  drivers/common/qat/qat_device.c     | 103 ++++++++++++++++++++++++------------
>  drivers/common/qat/qat_device.h     |  69 +++++++++++++-----------
>  drivers/common/qat/qat_qp.c         |  10 ++--
>  drivers/compress/qat/qat_comp_pmd.c |  43 +++++++++++----
>  drivers/compress/qat/qat_comp_pmd.h |   2 +
>  drivers/crypto/qat/qat_asym.c       |   4 +-
>  drivers/crypto/qat/qat_asym_pmd.c   |  62 +++++++++++++++++-----
>  drivers/crypto/qat/qat_asym_pmd.h   |   4 +-
>  drivers/crypto/qat/qat_sym.c        |   2 +-
>  drivers/crypto/qat/qat_sym.h        |   2 +-
>  drivers/crypto/qat/qat_sym_pmd.c    |  87 +++++++++++++++++++++++-------
>  drivers/crypto/qat/qat_sym_pmd.h    |   4 +-
>  12 files changed, 277 insertions(+), 115 deletions(-)
> 
> diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c
> index 2b41d9a..fc25b02 100644
> --- a/drivers/common/qat/qat_device.c
> +++ b/drivers/common/qat/qat_device.c
> @@ -32,8 +32,8 @@ struct qat_gen_hw_data qat_gen_config[] =  {
>  	},
>  };
> 
> -
> -static struct qat_pci_device qat_pci_devices[RTE_PMD_QAT_MAX_PCI_DEVICES];
> +/* per-process array of device data */
> +struct qat_device_info qat_pci_devs[RTE_PMD_QAT_MAX_PCI_DEVICES];
>  static int qat_nb_pci_devices;
> 
>  /*
> @@ -60,26 +60,20 @@ static const struct rte_pci_id pci_id_qat_map[] = {
>  };
> 
>  static struct qat_pci_device *
> -qat_pci_get_dev(uint8_t dev_id)
> -{
> -	return &qat_pci_devices[dev_id];
> -}
> -
> -static struct qat_pci_device *
>  qat_pci_get_named_dev(const char *name)
>  {
> -	struct qat_pci_device *dev;
>  	unsigned int i;
> 
>  	if (name == NULL)
>  		return NULL;
> 
>  	for (i = 0; i < RTE_PMD_QAT_MAX_PCI_DEVICES; i++) {
> -		dev = &qat_pci_devices[i];
> -
> -		if ((dev->attached == QAT_ATTACHED) &&
> -				(strcmp(dev->name, name) == 0))
> -			return dev;
> +		if (qat_pci_devs[i].mz &&
> +				(strcmp(((struct qat_pci_device *)
> +				qat_pci_devs[i].mz->addr)->name, name)
> +				== 0))
> +			return (struct qat_pci_device *)
> +				qat_pci_devs[i].mz->addr;
>  	}
> 
>  	return NULL;
> @@ -88,13 +82,13 @@ qat_pci_get_named_dev(const char *name)
>  static uint8_t
>  qat_pci_find_free_device_index(void)
>  {
> -	uint8_t dev_id;
> +		uint8_t dev_id;
> 
> -	for (dev_id = 0; dev_id < RTE_PMD_QAT_MAX_PCI_DEVICES; dev_id++) {
> -		if (qat_pci_devices[dev_id].attached == QAT_DETACHED)
> -			break;
> -	}
> -	return dev_id;
> +		for (dev_id = 0; dev_id < RTE_PMD_QAT_MAX_PCI_DEVICES; dev_id++) {
> +			if (qat_pci_devs[dev_id].mz == NULL)
> +				break;
> +		}
> +		return dev_id;
>  }
> 
>  struct qat_pci_device *
> @@ -169,12 +163,29 @@ qat_pci_device_allocate(struct rte_pci_device *pci_dev,
>  		struct qat_dev_cmd_param *qat_dev_cmd_param)
>  {
>  	struct qat_pci_device *qat_dev;
> -	uint8_t qat_dev_id;
> +	uint8_t qat_dev_id = 0;
>  	char name[QAT_DEV_NAME_MAX_LEN];
>  	struct rte_devargs *devargs = pci_dev->device.devargs;
> 
>  	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
>  	snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
> +
> +	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
> +		const struct rte_memzone *mz = rte_memzone_lookup(name);
> +
> +		if (mz == NULL) {
> +			QAT_LOG(ERR, "Error when searching allocated %s", name);
> +			return NULL;
> +		}
> +		qat_dev = mz->addr;
> +		qat_pci_devs[qat_dev->qat_dev_id].mz = mz;
> +		qat_pci_devs[qat_dev->qat_dev_id].pci_dev = pci_dev;
> +		qat_nb_pci_devices++;
> +		QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
> +			qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
> +		return qat_dev;
> +	}
> +
>  	if (qat_pci_get_named_dev(name) != NULL) {
>  		QAT_LOG(ERR, "QAT device with name %s already allocated!",
>  				name);
> @@ -187,12 +198,22 @@ qat_pci_device_allocate(struct rte_pci_device *pci_dev,
>  		return NULL;
>  	}
> 
> -	qat_dev = qat_pci_get_dev(qat_dev_id);
> +	qat_pci_devs[qat_dev_id].mz = rte_memzone_reserve(name,
> +		sizeof(struct qat_pci_device),
> +		rte_socket_id(), 0);
> +
> +	if (qat_pci_devs[qat_dev_id].mz == NULL) {
> +		QAT_LOG(ERR, "Error when allocating memzone for QAT_%d",
> +			qat_dev_id);
> +		return NULL;
> +	}
> +
> +	qat_dev = qat_pci_devs[qat_dev_id].mz->addr;
>  	memset(qat_dev, 0, sizeof(*qat_dev));
>  	strlcpy(qat_dev->name, name, QAT_DEV_NAME_MAX_LEN);
>  	qat_dev->qat_dev_id = qat_dev_id;
> -	qat_dev->pci_dev = pci_dev;
> -	switch (qat_dev->pci_dev->id.device_id) {
> +	qat_pci_devs[qat_dev_id].pci_dev = pci_dev;
> +	switch (pci_dev->id.device_id) {
>  	case 0x0443:
>  		qat_dev->qat_dev_gen = QAT_GEN1;
>  		break;
> @@ -206,6 +227,7 @@ qat_pci_device_allocate(struct rte_pci_device *pci_dev,
>  		break;
>  	default:
>  		QAT_LOG(ERR, "Invalid dev_id, can't determine generation");
> +		rte_memzone_free(qat_pci_devs[qat_dev->qat_dev_id].mz);
>  		return NULL;
>  	}
> 
> @@ -213,22 +235,20 @@ qat_pci_device_allocate(struct rte_pci_device *pci_dev,
>  		qat_dev_parse_cmd(devargs->drv_str, qat_dev_cmd_param);
> 
>  	rte_spinlock_init(&qat_dev->arb_csr_lock);
> -
> -	qat_dev->attached = QAT_ATTACHED;
> -
>  	qat_nb_pci_devices++;
> 
> -	QAT_LOG(DEBUG, "QAT device %d allocated, name %s, total QATs %d",
> +	QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
>  			qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
> 
>  	return qat_dev;
>  }
> 
> -int
> +static int
>  qat_pci_device_release(struct rte_pci_device *pci_dev)
>  {
>  	struct qat_pci_device *qat_dev;
>  	char name[QAT_DEV_NAME_MAX_LEN];
> +	int busy = 0;
> 
>  	if (pci_dev == NULL)
>  		return -EINVAL;
> @@ -238,15 +258,32 @@ qat_pci_device_release(struct rte_pci_device *pci_dev)
>  	qat_dev = qat_pci_get_named_dev(name);
>  	if (qat_dev != NULL) {
> 
> +		struct qat_device_info *inst =
> +				&qat_pci_devs[qat_dev->qat_dev_id];
>  		/* Check that there are no service devs still on pci device */
> -		if (qat_dev->sym_dev != NULL)
> +		if (qat_dev->sym_dev != NULL) {
> +			QAT_LOG(DEBUG, "QAT sym device %s is busy", name);
> +			busy = 1;
> +		}
> +		if (qat_dev->asym_dev != NULL) {
> +			QAT_LOG(DEBUG, "QAT asym device %s is busy", name);
> +			busy = 1;
> +		}
> +		if (qat_dev->comp_dev != NULL) {
> +			QAT_LOG(DEBUG, "QAT comp device %s is busy", name);
> +			busy = 1;
> +		}
> +		if (busy)
>  			return -EBUSY;
[Fiona]  Should the busy check be done on the secondary? I think it'll always be busy if primary is still there?
The secondary should only clean up all the related secondary structures, but not cleanup the shared structures.
See also related comment on destroy below

> 
> -		qat_dev->attached = QAT_DETACHED;
> +		memset(inst, 0, sizeof(struct qat_device_info));
> +
> +		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> +			rte_memzone_free(inst->mz);
>  		qat_nb_pci_devices--;
> +		QAT_LOG(DEBUG, "QAT device %s released, total QATs %d",
> +					name, qat_nb_pci_devices);
>  	}
> -	QAT_LOG(DEBUG, "QAT device %s released, total QATs %d",
> -				name, qat_nb_pci_devices);
>  	return 0;
>  }
> 
> diff --git a/drivers/common/qat/qat_device.h b/drivers/common/qat/qat_device.h
> index 09a4c55..70ec587 100644
> --- a/drivers/common/qat/qat_device.h
> +++ b/drivers/common/qat/qat_device.h
> @@ -32,6 +32,37 @@ enum qat_comp_num_im_buffers {
>  	QAT_NUM_INTERM_BUFS_GEN3 = 20
>  };
> 
> +struct qat_device_info {
> +	/**< mz to store the qat_pci_device so it can be
> +	 * shared across processes
> +	 */
> +	const struct rte_memzone *mz;
> +	struct rte_pci_device *pci_dev;
> +	struct rte_device sym_rte_dev;
> +	/**< This represents the crypto sym subset of this pci device.
> +	 * Register with this rather than with the one in
> +	 * pci_dev so that its driver can have a crypto-specific name
> +	 */
> +
> +	struct rte_device asym_rte_dev;
> +	/**< This represents the crypto asym subset of this pci device.
> +	 * Register with this rather than with the one in
> +	 * pci_dev so that its driver can have a crypto-specific name
> +	 */
> +
> +	struct rte_device comp_rte_dev;
> +	/**< This represents the compression subset of this pci device.
> +	 * Register with this rather than with the one in
> +	 * pci_dev so that its driver can have a compression-specific name
> +	 */
> +};
> +
> +extern struct qat_device_info qat_pci_devs[];
> +
> +struct qat_sym_dev_private;
> +struct qat_asym_dev_private;
> +struct qat_comp_dev_private;
> +
>  /*
>   * This struct holds all the data about a QAT pci device
>   * including data about all services it supports.
> @@ -39,27 +70,20 @@ enum qat_comp_num_im_buffers {
>   *  - hw_data
>   *  - config data
>   *  - runtime data
> + * Note: as this data can be shared in a multi-process scenario,
> + * any pointers in it must also point to shared memory.
>   */
> -struct qat_sym_dev_private;
> -struct qat_asym_dev_private;
> -struct qat_comp_dev_private;
> -
>  struct qat_pci_device {
> 
>  	/* Data used by all services */
>  	char name[QAT_DEV_NAME_MAX_LEN];
>  	/**< Name of qat pci device */
>  	uint8_t qat_dev_id;
> -	/**< Device instance for this qat pci device */
> -	struct rte_pci_device *pci_dev;
> -	/**< PCI information. */
> +	/**< Id of device instance for this qat pci device */
>  	enum qat_device_gen qat_dev_gen;
>  	/**< QAT device generation */
>  	rte_spinlock_t arb_csr_lock;
>  	/**< lock to protect accesses to the arbiter CSR */
> -	__extension__
> -	uint8_t attached : 1;
> -	/**< Flag indicating the device is attached */
> 
>  	struct qat_qp *qps_in_use[QAT_MAX_SERVICES][ADF_MAX_QPS_ON_ANY_SERVICE];
>  	/**< links to qps set up for each service, index same as on API */
> @@ -67,32 +91,18 @@ struct qat_pci_device {
>  	/* Data relating to symmetric crypto service */
>  	struct qat_sym_dev_private *sym_dev;
>  	/**< link back to cryptodev private data */
> -	struct rte_device sym_rte_dev;
> -	/**< This represents the crypto sym subset of this pci device.
> -	 * Register with this rather than with the one in
> -	 * pci_dev so that its driver can have a crypto-specific name
> -	 */
> +	int qat_sym_driver_id;
> +	/**< Symmetric driver id used by this device */
> 
>  	/* Data relating to asymmetric crypto service */
>  	struct qat_asym_dev_private *asym_dev;
>  	/**< link back to cryptodev private data */
> -	struct rte_device asym_rte_dev;
> -	/**< This represents the crypto asym subset of this pci device.
> -	 * Register with this rather than with the one in
> -	 * pci_dev so that its driver can have a crypto-specific name
> -	 */
> +	int qat_asym_driver_id;
> +	/**< Symmetric driver id used by this device */
> 
>  	/* Data relating to compression service */
>  	struct qat_comp_dev_private *comp_dev;
>  	/**< link back to compressdev private data */
> -	struct rte_device comp_rte_dev;
> -	/**< This represents the compression subset of this pci device.
> -	 * Register with this rather than with the one in
> -	 * pci_dev so that its driver can have a compression-specific name
> -	 */
> -
> -	/* Data relating to asymmetric crypto service */
> -
>  };
> 
>  struct qat_gen_hw_data {
> @@ -107,9 +117,6 @@ struct qat_pci_device *
>  qat_pci_device_allocate(struct rte_pci_device *pci_dev,
>  		struct qat_dev_cmd_param *qat_dev_cmd_param);
> 
> -int
> -qat_pci_device_release(struct rte_pci_device *pci_dev);
> -
>  struct qat_pci_device *
>  qat_get_qat_dev_from_pci_dev(struct rte_pci_device *pci_dev);
> 
> diff --git a/drivers/common/qat/qat_qp.c b/drivers/common/qat/qat_qp.c
> index 8e6dd04..66eb778 100644
> --- a/drivers/common/qat/qat_qp.c
> +++ b/drivers/common/qat/qat_qp.c
> @@ -193,7 +193,8 @@ int qat_qp_setup(struct qat_pci_device *qat_dev,
> 
>  {
>  	struct qat_qp *qp;
> -	struct rte_pci_device *pci_dev = qat_dev->pci_dev;
> +	struct rte_pci_device *pci_dev =
> +			qat_pci_devs[qat_dev->qat_dev_id].pci_dev;
>  	char op_cookie_pool_name[RTE_RING_NAMESIZE];
>  	uint32_t i;
> 
> @@ -274,7 +275,7 @@ int qat_qp_setup(struct qat_pci_device *qat_dev,
>  				qp->nb_descriptors,
>  				qat_qp_conf->cookie_size, 64, 0,
>  				NULL, NULL, NULL, NULL,
> -				qat_dev->pci_dev->device.numa_node,
> +				pci_dev->device.numa_node,
>  				0);
>  	if (!qp->op_cookie_pool) {
>  		QAT_LOG(ERR, "QAT PMD Cannot create"
> @@ -379,7 +380,8 @@ qat_queue_create(struct qat_pci_device *qat_dev, struct qat_queue *queue,
>  	uint64_t queue_base;
>  	void *io_addr;
>  	const struct rte_memzone *qp_mz;
> -	struct rte_pci_device *pci_dev = qat_dev->pci_dev;
> +	struct rte_pci_device *pci_dev =
> +			qat_pci_devs[qat_dev->qat_dev_id].pci_dev;
>  	int ret = 0;
>  	uint16_t desc_size = (dir == ADF_RING_DIR_TX ?
>  			qp_conf->hw->tx_msg_size : qp_conf->hw->rx_msg_size);
> @@ -403,7 +405,7 @@ qat_queue_create(struct qat_pci_device *qat_dev, struct qat_queue *queue,
>  		qp_conf->service_str, "qp_mem",
>  		queue->hw_bundle_number, queue->hw_queue_number);
>  	qp_mz = queue_dma_zone_reserve(queue->memz_name, queue_size_bytes,
> -			qat_dev->pci_dev->device.numa_node);
> +			pci_dev->device.numa_node);
>  	if (qp_mz == NULL) {
>  		QAT_LOG(ERR, "Failed to allocate ring memzone");
>  		return -ENOMEM;
> diff --git a/drivers/compress/qat/qat_comp_pmd.c b/drivers/compress/qat/qat_comp_pmd.c
> index fe62de5..c08c9a3 100644
> --- a/drivers/compress/qat/qat_comp_pmd.c
> +++ b/drivers/compress/qat/qat_comp_pmd.c
> @@ -655,6 +655,8 @@ qat_comp_dev_create(struct qat_pci_device *qat_pci_dev,
>  		struct qat_dev_cmd_param *qat_dev_cmd_param)
>  {
>  	int i = 0;
> +	struct qat_device_info *qat_dev_instance =
> +			&qat_pci_devs[qat_pci_dev->qat_dev_id];
>  	if (qat_pci_dev->qat_dev_gen == QAT_GEN3) {
>  		QAT_LOG(ERR, "Compression PMD not supported on QAT P5xxx");
>  		return 0;
> @@ -662,24 +664,27 @@ qat_comp_dev_create(struct qat_pci_device *qat_pci_dev,
> 
>  	struct rte_compressdev_pmd_init_params init_params = {
>  		.name = "",
> -		.socket_id = qat_pci_dev->pci_dev->device.numa_node,
> +		.socket_id = qat_dev_instance->pci_dev->device.numa_node,
>  	};
>  	char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
> +	char memz_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
>  	struct rte_compressdev *compressdev;
>  	struct qat_comp_dev_private *comp_dev;
> +	const struct rte_compressdev_capabilities *capabilities;
> +	uint64_t capa_size;
> 
>  	snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s",
>  			qat_pci_dev->name, "comp");
>  	QAT_LOG(DEBUG, "Creating QAT COMP device %s", name);
> 
>  	/* Populate subset device to use in compressdev device creation */
> -	qat_pci_dev->comp_rte_dev.driver = &compdev_qat_driver;
> -	qat_pci_dev->comp_rte_dev.numa_node =
> -					qat_pci_dev->pci_dev->device.numa_node;
> -	qat_pci_dev->comp_rte_dev.devargs = NULL;
> +	qat_dev_instance->comp_rte_dev.driver = &compdev_qat_driver;
> +	qat_dev_instance->comp_rte_dev.numa_node =
> +			qat_dev_instance->pci_dev->device.numa_node;
> +	qat_dev_instance->comp_rte_dev.devargs = NULL;
> 
>  	compressdev = rte_compressdev_pmd_create(name,
> -			&(qat_pci_dev->comp_rte_dev),
> +			&(qat_dev_instance->comp_rte_dev),
>  			sizeof(struct qat_comp_dev_private),
>  			&init_params);
> 
> @@ -694,25 +699,44 @@ qat_comp_dev_create(struct qat_pci_device *qat_pci_dev,
> 
>  	compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
> 
> +	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> +		return 0;
> +
> +	snprintf(memz_name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s_MEMZONE",
> +			qat_pci_dev->name, "comp");
>  	comp_dev = compressdev->data->dev_private;
>  	comp_dev->qat_dev = qat_pci_dev;
>  	comp_dev->compressdev = compressdev;
> -	qat_pci_dev->comp_dev = comp_dev;
> 
>  	switch (qat_pci_dev->qat_dev_gen) {
>  	case QAT_GEN1:
>  	case QAT_GEN2:
>  	case QAT_GEN3:
> -		comp_dev->qat_dev_capabilities = qat_comp_gen_capabilities;
> +		capabilities = qat_comp_gen_capabilities;
> +		capa_size = sizeof(qat_comp_gen_capabilities);
>  		break;
>  	default:
> -		comp_dev->qat_dev_capabilities = qat_comp_gen_capabilities;
> +		capabilities = qat_comp_gen_capabilities;
> +		capa_size = sizeof(qat_comp_gen_capabilities);
>  		QAT_LOG(DEBUG,
>  			"QAT gen %d capabilities unknown, default to GEN1",
>  					qat_pci_dev->qat_dev_gen);
>  		break;
>  	}
> 
> +	comp_dev->mz = rte_memzone_reserve(memz_name,
> +		capa_size,
> +		rte_socket_id(), 0);
> +	if (comp_dev->mz == NULL) {
> +		QAT_LOG(DEBUG, "Error allocating memzone, destroying PMD"
> +				" for %s", name);
> +		rte_compressdev_pmd_destroy(compressdev);
> +		return -EFAULT;
> +	}
> +
> +	memcpy(comp_dev->mz->addr, capabilities, capa_size);
> +	comp_dev->qat_dev_capabilities = comp_dev->mz->addr;
> +
>  	while (1) {
>  		if (qat_dev_cmd_param[i].name == NULL)
>  			break;
> @@ -721,6 +745,7 @@ qat_comp_dev_create(struct qat_pci_device *qat_pci_dev,
>  					qat_dev_cmd_param[i].val;
>  		i++;
>  	}
> +	qat_pci_dev->comp_dev = comp_dev;
> 
>  	QAT_LOG(DEBUG,
>  		    "Created QAT COMP device %s as compressdev instance %d",
> diff --git a/drivers/compress/qat/qat_comp_pmd.h b/drivers/compress/qat/qat_comp_pmd.h
> index 5c7fa9f..24ad572 100644
> --- a/drivers/compress/qat/qat_comp_pmd.h
> +++ b/drivers/compress/qat/qat_comp_pmd.h
> @@ -32,6 +32,8 @@ struct qat_comp_dev_private {
>  	/**< The device's pool for qat_comp_xforms */
>  	struct rte_mempool *streampool;
>  	/**< The device's pool for qat_comp_streams */
> +	const struct rte_memzone *mz;
> +	/* Shared memzone for storing capabilities */
>  	uint16_t min_enq_burst_threshold;
>  };
> 
> diff --git a/drivers/crypto/qat/qat_asym.c b/drivers/crypto/qat/qat_asym.c
> index ae0dd79..8597381 100644
> --- a/drivers/crypto/qat/qat_asym.c
> +++ b/drivers/crypto/qat/qat_asym.c
> @@ -475,7 +475,7 @@ qat_asym_build_request(void *in_op,
>  	if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
>  		ctx = (struct qat_asym_session *)
>  			get_asym_session_private_data(
> -			op->asym->session, cryptodev_qat_asym_driver_id);
> +			op->asym->session, qat_asym_driver_id);
>  		if (unlikely(ctx == NULL)) {
>  			QAT_LOG(ERR, "Session has not been created for this device");
>  			goto error;
> @@ -693,7 +693,7 @@ qat_asym_process_response(void **op, uint8_t *resp,
> 
>  	if (rx_op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
>  		ctx = (struct qat_asym_session *)get_asym_session_private_data(
> -			rx_op->asym->session, cryptodev_qat_asym_driver_id);
> +			rx_op->asym->session, qat_asym_driver_id);
>  		qat_asym_collect_response(rx_op, cookie, ctx->xform);
>  	} else if (rx_op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
>  		qat_asym_collect_response(rx_op, cookie, rx_op->asym->xform);
> diff --git a/drivers/crypto/qat/qat_asym_pmd.c b/drivers/crypto/qat/qat_asym_pmd.c
> index af3cc25..b747a5a 100644
> --- a/drivers/crypto/qat/qat_asym_pmd.c
> +++ b/drivers/crypto/qat/qat_asym_pmd.c
> @@ -11,7 +11,7 @@
>  #include "qat_sym_capabilities.h"
>  #include "qat_asym_capabilities.h"
> 
> -uint8_t cryptodev_qat_asym_driver_id;
> +uint8_t qat_asym_driver_id;
> 
>  static const struct rte_cryptodev_capabilities qat_gen1_asym_capabilities[] = {
>  	QAT_BASE_GEN1_ASYM_CAPABILITIES,
> @@ -63,7 +63,7 @@ static void qat_asym_dev_info_get(struct rte_cryptodev *dev,
>  							QAT_SERVICE_ASYMMETRIC);
>  		info->feature_flags = dev->feature_flags;
>  		info->capabilities = internals->qat_dev_capabilities;
> -		info->driver_id = cryptodev_qat_asym_driver_id;
> +		info->driver_id = qat_asym_driver_id;
>  		/* No limit of number of sessions */
>  		info->sym.max_nb_sessions = 0;
>  	}
> @@ -239,33 +239,49 @@ qat_asym_dev_create(struct qat_pci_device *qat_pci_dev,
>  		struct qat_dev_cmd_param *qat_dev_cmd_param)
>  {
>  	int i = 0;
> +	struct qat_device_info *qat_dev_instance =
> +			&qat_pci_devs[qat_pci_dev->qat_dev_id];
>  	struct rte_cryptodev_pmd_init_params init_params = {
>  			.name = "",
> -			.socket_id = qat_pci_dev->pci_dev->device.numa_node,
> +			.socket_id = qat_dev_instance->pci_dev->device.numa_node,
>  			.private_data_size = sizeof(struct qat_asym_dev_private)
>  	};
>  	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
> +	char memz_name[RTE_CRYPTODEV_NAME_MAX_LEN];
>  	struct rte_cryptodev *cryptodev;
>  	struct qat_asym_dev_private *internals;
> 
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		qat_pci_dev->qat_asym_driver_id =
> +				qat_asym_driver_id;
> +	} else if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
> +		if (qat_pci_dev->qat_asym_driver_id !=
> +				qat_asym_driver_id) {
> +			QAT_LOG(ERR, "Device %s have different driver id than "
> +					"corresponding device in primary process"
> +					, name);
> +			return -(EFAULT);
> +		}
> +	}
> +
>  	snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s",
>  			qat_pci_dev->name, "asym");
>  	QAT_LOG(DEBUG, "Creating QAT ASYM device %s\n", name);
> 
>  	/* Populate subset device to use in cryptodev device creation */
> -	qat_pci_dev->asym_rte_dev.driver = &cryptodev_qat_asym_driver;
> -	qat_pci_dev->asym_rte_dev.numa_node =
> -				qat_pci_dev->pci_dev->device.numa_node;
> -	qat_pci_dev->asym_rte_dev.devargs = NULL;
> +	qat_dev_instance->asym_rte_dev.driver = &cryptodev_qat_asym_driver;
> +	qat_dev_instance->asym_rte_dev.numa_node =
> +			qat_dev_instance->pci_dev->device.numa_node;
> +	qat_dev_instance->asym_rte_dev.devargs = NULL;
> 
>  	cryptodev = rte_cryptodev_pmd_create(name,
> -			&(qat_pci_dev->asym_rte_dev), &init_params);
> +			&(qat_dev_instance->asym_rte_dev), &init_params);
> 
>  	if (cryptodev == NULL)
>  		return -ENODEV;
> 
> -	qat_pci_dev->asym_rte_dev.name = cryptodev->data->name;
> -	cryptodev->driver_id = cryptodev_qat_asym_driver_id;
> +	qat_dev_instance->asym_rte_dev.name = cryptodev->data->name;
> +	cryptodev->driver_id = qat_asym_driver_id;
>  	cryptodev->dev_ops = &crypto_qat_ops;
> 
>  	cryptodev->enqueue_burst = qat_asym_pmd_enqueue_op_burst;
> @@ -276,12 +292,30 @@ qat_asym_dev_create(struct qat_pci_device *qat_pci_dev,
>  			RTE_CRYPTODEV_FF_ASYM_SESSIONLESS |
>  			RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP |
>  			RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT;
> +
> +	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> +		return 0;
> +
> +	snprintf(memz_name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s_MEMZONE",
> +			qat_pci_dev->name, "asym");
>  	internals = cryptodev->data->dev_private;
>  	internals->qat_dev = qat_pci_dev;
> -	qat_pci_dev->asym_dev = internals;
> 
>  	internals->asym_dev_id = cryptodev->data->dev_id;
>  	internals->qat_dev_capabilities = qat_gen1_asym_capabilities;
> +	internals->mz = rte_memzone_reserve(memz_name,
> +		sizeof(qat_gen1_asym_capabilities),
> +		rte_socket_id(), 0);
> +	if (internals->mz == NULL) {
> +		QAT_LOG(DEBUG, "Error allocating memzone, destroying PMD"
> +				" for %s", name);
> +		rte_cryptodev_pmd_destroy(cryptodev);
> +		return -EFAULT;
> +	}
> +
> +	memcpy(internals->mz->addr, qat_gen1_asym_capabilities,
> +			sizeof(qat_gen1_asym_capabilities));
> +	internals->qat_dev_capabilities = internals->mz->addr;
> 
>  	while (1) {
>  		if (qat_dev_cmd_param[i].name == NULL)
> @@ -292,6 +326,7 @@ qat_asym_dev_create(struct qat_pci_device *qat_pci_dev,
>  		i++;
>  	}
> 
> +	qat_pci_dev->asym_dev = internals;
>  	QAT_LOG(DEBUG, "Created QAT ASYM device %s as cryptodev instance %d",
>  			cryptodev->data->name, internals->asym_dev_id);
>  	return 0;
> @@ -307,11 +342,12 @@ qat_asym_dev_destroy(struct qat_pci_device *qat_pci_dev)
>  	if (qat_pci_dev->asym_dev == NULL)
>  		return 0;
> 
> +	rte_memzone_free(qat_pci_dev->asym_dev->mz);
>  	/* free crypto device */
>  	cryptodev = rte_cryptodev_pmd_get_dev(
>  			qat_pci_dev->asym_dev->asym_dev_id);
>  	rte_cryptodev_pmd_destroy(cryptodev);
> -	qat_pci_dev->asym_rte_dev.name = NULL;
> +	qat_pci_devs[qat_pci_dev->qat_dev_id].asym_rte_dev.name = NULL;
>  	qat_pci_dev->asym_dev = NULL;
> 
>  	return 0;
> @@ -320,4 +356,4 @@ qat_asym_dev_destroy(struct qat_pci_device *qat_pci_dev)
>  static struct cryptodev_driver qat_crypto_drv;
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(qat_crypto_drv,
>  		cryptodev_qat_asym_driver,
> -		cryptodev_qat_asym_driver_id);
> +		qat_asym_driver_id);
> diff --git a/drivers/crypto/qat/qat_asym_pmd.h b/drivers/crypto/qat/qat_asym_pmd.h
> index 0535bc6..25ba4c7 100644
> --- a/drivers/crypto/qat/qat_asym_pmd.h
> +++ b/drivers/crypto/qat/qat_asym_pmd.h
> @@ -13,7 +13,7 @@
>  #define CRYPTODEV_NAME_QAT_ASYM_PMD	crypto_qat_asym
> 
> 
> -extern uint8_t cryptodev_qat_asym_driver_id;
> +extern uint8_t qat_asym_driver_id;
> 
>  /** private data structure for a QAT device.
>   * This QAT device is a device offering only asymmetric crypto service,
> @@ -26,6 +26,8 @@ struct qat_asym_dev_private {
>  	/**< Device instance for this rte_cryptodev */
>  	const struct rte_cryptodev_capabilities *qat_dev_capabilities;
>  	/* QAT device asymmetric crypto capabilities */
> +	const struct rte_memzone *mz;
> +	/* Shared memzone for storing capabilities */
>  	uint16_t min_enq_burst_threshold;
>  };
> 
> diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c
> index 25b6dd5..2e4cfec 100644
> --- a/drivers/crypto/qat/qat_sym.c
> +++ b/drivers/crypto/qat/qat_sym.c
> @@ -180,7 +180,7 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg,
>  	}
> 
>  	ctx = (struct qat_sym_session *)get_sym_session_private_data(
> -			op->sym->session, cryptodev_qat_driver_id);
> +			op->sym->session, qat_sym_driver_id);
> 
>  	if (unlikely(ctx == NULL)) {
>  		QAT_DP_LOG(ERR, "Session was not created for this device");
> diff --git a/drivers/crypto/qat/qat_sym.h b/drivers/crypto/qat/qat_sym.h
> index bc6426c..758b06d 100644
> --- a/drivers/crypto/qat/qat_sym.h
> +++ b/drivers/crypto/qat/qat_sym.h
> @@ -155,7 +155,7 @@ qat_sym_process_response(void **op, uint8_t *resp)
>  		struct qat_sym_session *sess = (struct qat_sym_session *)
>  						get_sym_session_private_data(
>  						rx_op->sym->session,
> -						cryptodev_qat_driver_id);
> +						qat_sym_driver_id);
> 
> 
>  		if (sess->bpi_ctx)
> diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
> index e887c88..221f0f6 100644
> --- a/drivers/crypto/qat/qat_sym_pmd.c
> +++ b/drivers/crypto/qat/qat_sym_pmd.c
> @@ -16,7 +16,7 @@
> 
>  #define MIXED_CRYPTO_MIN_FW_VER 0x04090000
> 
> -uint8_t cryptodev_qat_driver_id;
> +uint8_t qat_sym_driver_id;
> 
>  static const struct rte_cryptodev_capabilities qat_gen1_sym_capabilities[] = {
>  	QAT_BASE_GEN1_SYM_CAPABILITIES,
> @@ -29,6 +29,12 @@ static const struct rte_cryptodev_capabilities qat_gen2_sym_capabilities[] = {
>  	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
>  };
> 
> +static const struct rte_cryptodev_capabilities qat_gen3_sym_capabilities[] = {
> +	QAT_BASE_GEN1_SYM_CAPABILITIES,
> +	QAT_EXTRA_GEN2_SYM_CAPABILITIES,
> +	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
> +};
> +
>  static int qat_sym_qp_release(struct rte_cryptodev *dev,
>  	uint16_t queue_pair_id);
> 
> @@ -74,7 +80,7 @@ static void qat_sym_dev_info_get(struct rte_cryptodev *dev,
>  			qat_qps_per_service(sym_hw_qps, QAT_SERVICE_SYMMETRIC);
>  		info->feature_flags = dev->feature_flags;
>  		info->capabilities = internals->qat_dev_capabilities;
> -		info->driver_id = cryptodev_qat_driver_id;
> +		info->driver_id = qat_sym_driver_id;
>  		/* No limit of number of sessions */
>  		info->sym.max_nb_sessions = 0;
>  	}
> @@ -268,33 +274,51 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev,
>  		struct qat_dev_cmd_param *qat_dev_cmd_param __rte_unused)
>  {
>  	int i = 0;
> +	struct qat_device_info *qat_dev_instance =
> +			&qat_pci_devs[qat_pci_dev->qat_dev_id];
>  	struct rte_cryptodev_pmd_init_params init_params = {
>  			.name = "",
> -			.socket_id = qat_pci_dev->pci_dev->device.numa_node,
> +			.socket_id = qat_dev_instance->pci_dev->device.numa_node,
>  			.private_data_size = sizeof(struct qat_sym_dev_private)
>  	};
>  	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
> +	char memz_name[RTE_CRYPTODEV_NAME_MAX_LEN];
>  	struct rte_cryptodev *cryptodev;
>  	struct qat_sym_dev_private *internals;
> +	const struct rte_cryptodev_capabilities *capabilities;
> +	uint64_t capa_size;
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		qat_pci_dev->qat_sym_driver_id =
> +				qat_sym_driver_id;
> +	} else if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
> +		if (qat_pci_dev->qat_sym_driver_id !=
> +				qat_sym_driver_id) {
> +			QAT_LOG(ERR, "Device %s have different driver id than "
> +					"corresponding device in primary process"
> +					, name);
> +			return -(EFAULT);
> +		}
> +	}
> 
>  	snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s",
>  			qat_pci_dev->name, "sym");
>  	QAT_LOG(DEBUG, "Creating QAT SYM device %s", name);
> 
>  	/* Populate subset device to use in cryptodev device creation */
> -	qat_pci_dev->sym_rte_dev.driver = &cryptodev_qat_sym_driver;
> -	qat_pci_dev->sym_rte_dev.numa_node =
> -				qat_pci_dev->pci_dev->device.numa_node;
> -	qat_pci_dev->sym_rte_dev.devargs = NULL;
> +	qat_dev_instance->sym_rte_dev.driver = &cryptodev_qat_sym_driver;
> +	qat_dev_instance->sym_rte_dev.numa_node =
> +			qat_dev_instance->pci_dev->device.numa_node;
> +	qat_dev_instance->sym_rte_dev.devargs = NULL;
> 
>  	cryptodev = rte_cryptodev_pmd_create(name,
> -			&(qat_pci_dev->sym_rte_dev), &init_params);
> +			&(qat_dev_instance->sym_rte_dev), &init_params);
> 
>  	if (cryptodev == NULL)
>  		return -ENODEV;
> 
> -	qat_pci_dev->sym_rte_dev.name = cryptodev->data->name;
> -	cryptodev->driver_id = cryptodev_qat_driver_id;
> +	qat_dev_instance->sym_rte_dev.name = cryptodev->data->name;
> +	cryptodev->driver_id = qat_sym_driver_id;
>  	cryptodev->dev_ops = &crypto_qat_ops;
> 
>  	cryptodev->enqueue_burst = qat_sym_pmd_enqueue_op_burst;
> @@ -310,27 +334,49 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev,
>  			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
>  			RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED;
> 
> +
> +	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> +		return 0;
> +
> +	snprintf(memz_name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s_MEMZONE",
> +			qat_pci_dev->name, "sym");
> +
>  	internals = cryptodev->data->dev_private;
>  	internals->qat_dev = qat_pci_dev;
> -	qat_pci_dev->sym_dev = internals;
> -
>  	internals->sym_dev_id = cryptodev->data->dev_id;
> +
>  	switch (qat_pci_dev->qat_dev_gen) {
>  	case QAT_GEN1:
> -		internals->qat_dev_capabilities = qat_gen1_sym_capabilities;
> +		capabilities = qat_gen1_sym_capabilities;
> +		capa_size = sizeof(qat_gen1_sym_capabilities);
>  		break;
>  	case QAT_GEN2:
> +		capabilities = qat_gen2_sym_capabilities;
> +		capa_size = sizeof(qat_gen2_sym_capabilities);
> +		break;
>  	case QAT_GEN3:
> -		internals->qat_dev_capabilities = qat_gen2_sym_capabilities;
> +		capabilities = qat_gen3_sym_capabilities;
> +		capa_size = sizeof(qat_gen3_sym_capabilities);
>  		break;
>  	default:
> -		internals->qat_dev_capabilities = qat_gen2_sym_capabilities;
>  		QAT_LOG(DEBUG,
> -			"QAT gen %d capabilities unknown, default to GEN2",
> +			"QAT gen %d capabilities unknown	",
>  					qat_pci_dev->qat_dev_gen);
> -		break;
> +		return -(EINVAL);
> +	}
> +
> +	internals->mz = rte_memzone_reserve(memz_name,
> +		capa_size,
> +		rte_socket_id(), 0);
> +	if (internals->mz == NULL) {
> +		QAT_LOG(DEBUG, "Error allocating memzone, destroying PMD"
> +				" for %s", name);
> +		rte_cryptodev_pmd_destroy(cryptodev);
> +		return -EFAULT;
>  	}
> 
> +	memcpy(internals->mz->addr, capabilities, capa_size);
> +	internals->qat_dev_capabilities = internals->mz->addr;
>  	while (1) {
>  		if (qat_dev_cmd_param[i].name == NULL)
>  			break;
> @@ -340,8 +386,10 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev,
>  		i++;
>  	}
> 
> +	qat_pci_dev->sym_dev = internals;
>  	QAT_LOG(DEBUG, "Created QAT SYM device %s as cryptodev instance %d",
>  			cryptodev->data->name, internals->sym_dev_id);
> +
>  	return 0;
>  }
> 
> @@ -355,10 +403,11 @@ qat_sym_dev_destroy(struct qat_pci_device *qat_pci_dev)
>  	if (qat_pci_dev->sym_dev == NULL)
>  		return 0;
> 
> +	rte_memzone_free(qat_pci_dev->sym_dev->mz);
[Fiona] sym_destroy should do the opposite of sym_create.
Only the primary creates the capa memzone, so only the primary should free it.
Same for asym and comp devices.


>  	/* free crypto device */
>  	cryptodev = rte_cryptodev_pmd_get_dev(qat_pci_dev->sym_dev->sym_dev_id);
>  	rte_cryptodev_pmd_destroy(cryptodev);
> -	qat_pci_dev->sym_rte_dev.name = NULL;
> +	qat_pci_devs[qat_pci_dev->qat_dev_id].sym_rte_dev.name = NULL;
>  	qat_pci_dev->sym_dev = NULL;
> 
>  	return 0;
> @@ -367,4 +416,4 @@ qat_sym_dev_destroy(struct qat_pci_device *qat_pci_dev)
>  static struct cryptodev_driver qat_crypto_drv;
>  RTE_PMD_REGISTER_CRYPTO_DRIVER(qat_crypto_drv,
>  		cryptodev_qat_sym_driver,
> -		cryptodev_qat_driver_id);
> +		qat_sym_driver_id);
> diff --git a/drivers/crypto/qat/qat_sym_pmd.h b/drivers/crypto/qat/qat_sym_pmd.h
> index a5a31e5..2c8204c 100644
> --- a/drivers/crypto/qat/qat_sym_pmd.h
> +++ b/drivers/crypto/qat/qat_sym_pmd.h
> @@ -19,7 +19,7 @@
>  #define QAT_SYM_CAP_MIXED_CRYPTO	(1 << 0)
>  #define QAT_SYM_CAP_VALID		(1 << 31)
> 
> -extern uint8_t cryptodev_qat_driver_id;
> +extern uint8_t qat_sym_driver_id;
> 
>  /** private data structure for a QAT device.
>   * This QAT device is a device offering only symmetric crypto service,
> @@ -32,6 +32,8 @@ struct qat_sym_dev_private {
>  	/**< Device instance for this rte_cryptodev */
>  	const struct rte_cryptodev_capabilities *qat_dev_capabilities;
>  	/* QAT device symmetric crypto capabilities */
> +	const struct rte_memzone *mz;
> +	/* Shared memzone for storing capabilities */
>  	uint16_t min_enq_burst_threshold;
>  	uint32_t internal_capabilities; /* see flags QAT_SYM_CAP_xxx */
>  };
> --
> 2.1.0
  

Patch

diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c
index 2b41d9a..fc25b02 100644
--- a/drivers/common/qat/qat_device.c
+++ b/drivers/common/qat/qat_device.c
@@ -32,8 +32,8 @@  struct qat_gen_hw_data qat_gen_config[] =  {
 	},
 };
 
-
-static struct qat_pci_device qat_pci_devices[RTE_PMD_QAT_MAX_PCI_DEVICES];
+/* per-process array of device data */
+struct qat_device_info qat_pci_devs[RTE_PMD_QAT_MAX_PCI_DEVICES];
 static int qat_nb_pci_devices;
 
 /*
@@ -60,26 +60,20 @@  static const struct rte_pci_id pci_id_qat_map[] = {
 };
 
 static struct qat_pci_device *
-qat_pci_get_dev(uint8_t dev_id)
-{
-	return &qat_pci_devices[dev_id];
-}
-
-static struct qat_pci_device *
 qat_pci_get_named_dev(const char *name)
 {
-	struct qat_pci_device *dev;
 	unsigned int i;
 
 	if (name == NULL)
 		return NULL;
 
 	for (i = 0; i < RTE_PMD_QAT_MAX_PCI_DEVICES; i++) {
-		dev = &qat_pci_devices[i];
-
-		if ((dev->attached == QAT_ATTACHED) &&
-				(strcmp(dev->name, name) == 0))
-			return dev;
+		if (qat_pci_devs[i].mz &&
+				(strcmp(((struct qat_pci_device *)
+				qat_pci_devs[i].mz->addr)->name, name)
+				== 0))
+			return (struct qat_pci_device *)
+				qat_pci_devs[i].mz->addr;
 	}
 
 	return NULL;
@@ -88,13 +82,13 @@  qat_pci_get_named_dev(const char *name)
 static uint8_t
 qat_pci_find_free_device_index(void)
 {
-	uint8_t dev_id;
+		uint8_t dev_id;
 
-	for (dev_id = 0; dev_id < RTE_PMD_QAT_MAX_PCI_DEVICES; dev_id++) {
-		if (qat_pci_devices[dev_id].attached == QAT_DETACHED)
-			break;
-	}
-	return dev_id;
+		for (dev_id = 0; dev_id < RTE_PMD_QAT_MAX_PCI_DEVICES; dev_id++) {
+			if (qat_pci_devs[dev_id].mz == NULL)
+				break;
+		}
+		return dev_id;
 }
 
 struct qat_pci_device *
@@ -169,12 +163,29 @@  qat_pci_device_allocate(struct rte_pci_device *pci_dev,
 		struct qat_dev_cmd_param *qat_dev_cmd_param)
 {
 	struct qat_pci_device *qat_dev;
-	uint8_t qat_dev_id;
+	uint8_t qat_dev_id = 0;
 	char name[QAT_DEV_NAME_MAX_LEN];
 	struct rte_devargs *devargs = pci_dev->device.devargs;
 
 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
 	snprintf(name+strlen(name), QAT_DEV_NAME_MAX_LEN-strlen(name), "_qat");
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		const struct rte_memzone *mz = rte_memzone_lookup(name);
+
+		if (mz == NULL) {
+			QAT_LOG(ERR, "Error when searching allocated %s", name);
+			return NULL;
+		}
+		qat_dev = mz->addr;
+		qat_pci_devs[qat_dev->qat_dev_id].mz = mz;
+		qat_pci_devs[qat_dev->qat_dev_id].pci_dev = pci_dev;
+		qat_nb_pci_devices++;
+		QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
+			qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
+		return qat_dev;
+	}
+
 	if (qat_pci_get_named_dev(name) != NULL) {
 		QAT_LOG(ERR, "QAT device with name %s already allocated!",
 				name);
@@ -187,12 +198,22 @@  qat_pci_device_allocate(struct rte_pci_device *pci_dev,
 		return NULL;
 	}
 
-	qat_dev = qat_pci_get_dev(qat_dev_id);
+	qat_pci_devs[qat_dev_id].mz = rte_memzone_reserve(name,
+		sizeof(struct qat_pci_device),
+		rte_socket_id(), 0);
+
+	if (qat_pci_devs[qat_dev_id].mz == NULL) {
+		QAT_LOG(ERR, "Error when allocating memzone for QAT_%d",
+			qat_dev_id);
+		return NULL;
+	}
+
+	qat_dev = qat_pci_devs[qat_dev_id].mz->addr;
 	memset(qat_dev, 0, sizeof(*qat_dev));
 	strlcpy(qat_dev->name, name, QAT_DEV_NAME_MAX_LEN);
 	qat_dev->qat_dev_id = qat_dev_id;
-	qat_dev->pci_dev = pci_dev;
-	switch (qat_dev->pci_dev->id.device_id) {
+	qat_pci_devs[qat_dev_id].pci_dev = pci_dev;
+	switch (pci_dev->id.device_id) {
 	case 0x0443:
 		qat_dev->qat_dev_gen = QAT_GEN1;
 		break;
@@ -206,6 +227,7 @@  qat_pci_device_allocate(struct rte_pci_device *pci_dev,
 		break;
 	default:
 		QAT_LOG(ERR, "Invalid dev_id, can't determine generation");
+		rte_memzone_free(qat_pci_devs[qat_dev->qat_dev_id].mz);
 		return NULL;
 	}
 
@@ -213,22 +235,20 @@  qat_pci_device_allocate(struct rte_pci_device *pci_dev,
 		qat_dev_parse_cmd(devargs->drv_str, qat_dev_cmd_param);
 
 	rte_spinlock_init(&qat_dev->arb_csr_lock);
-
-	qat_dev->attached = QAT_ATTACHED;
-
 	qat_nb_pci_devices++;
 
-	QAT_LOG(DEBUG, "QAT device %d allocated, name %s, total QATs %d",
+	QAT_LOG(DEBUG, "QAT device %d found, name %s, total QATs %d",
 			qat_dev->qat_dev_id, qat_dev->name, qat_nb_pci_devices);
 
 	return qat_dev;
 }
 
-int
+static int
 qat_pci_device_release(struct rte_pci_device *pci_dev)
 {
 	struct qat_pci_device *qat_dev;
 	char name[QAT_DEV_NAME_MAX_LEN];
+	int busy = 0;
 
 	if (pci_dev == NULL)
 		return -EINVAL;
@@ -238,15 +258,32 @@  qat_pci_device_release(struct rte_pci_device *pci_dev)
 	qat_dev = qat_pci_get_named_dev(name);
 	if (qat_dev != NULL) {
 
+		struct qat_device_info *inst =
+				&qat_pci_devs[qat_dev->qat_dev_id];
 		/* Check that there are no service devs still on pci device */
-		if (qat_dev->sym_dev != NULL)
+		if (qat_dev->sym_dev != NULL) {
+			QAT_LOG(DEBUG, "QAT sym device %s is busy", name);
+			busy = 1;
+		}
+		if (qat_dev->asym_dev != NULL) {
+			QAT_LOG(DEBUG, "QAT asym device %s is busy", name);
+			busy = 1;
+		}
+		if (qat_dev->comp_dev != NULL) {
+			QAT_LOG(DEBUG, "QAT comp device %s is busy", name);
+			busy = 1;
+		}
+		if (busy)
 			return -EBUSY;
 
-		qat_dev->attached = QAT_DETACHED;
+		memset(inst, 0, sizeof(struct qat_device_info));
+
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_memzone_free(inst->mz);
 		qat_nb_pci_devices--;
+		QAT_LOG(DEBUG, "QAT device %s released, total QATs %d",
+					name, qat_nb_pci_devices);
 	}
-	QAT_LOG(DEBUG, "QAT device %s released, total QATs %d",
-				name, qat_nb_pci_devices);
 	return 0;
 }
 
diff --git a/drivers/common/qat/qat_device.h b/drivers/common/qat/qat_device.h
index 09a4c55..70ec587 100644
--- a/drivers/common/qat/qat_device.h
+++ b/drivers/common/qat/qat_device.h
@@ -32,6 +32,37 @@  enum qat_comp_num_im_buffers {
 	QAT_NUM_INTERM_BUFS_GEN3 = 20
 };
 
+struct qat_device_info {
+	/**< mz to store the qat_pci_device so it can be
+	 * shared across processes
+	 */
+	const struct rte_memzone *mz;
+	struct rte_pci_device *pci_dev;
+	struct rte_device sym_rte_dev;
+	/**< This represents the crypto sym subset of this pci device.
+	 * Register with this rather than with the one in
+	 * pci_dev so that its driver can have a crypto-specific name
+	 */
+
+	struct rte_device asym_rte_dev;
+	/**< This represents the crypto asym subset of this pci device.
+	 * Register with this rather than with the one in
+	 * pci_dev so that its driver can have a crypto-specific name
+	 */
+
+	struct rte_device comp_rte_dev;
+	/**< This represents the compression subset of this pci device.
+	 * Register with this rather than with the one in
+	 * pci_dev so that its driver can have a compression-specific name
+	 */
+};
+
+extern struct qat_device_info qat_pci_devs[];
+
+struct qat_sym_dev_private;
+struct qat_asym_dev_private;
+struct qat_comp_dev_private;
+
 /*
  * This struct holds all the data about a QAT pci device
  * including data about all services it supports.
@@ -39,27 +70,20 @@  enum qat_comp_num_im_buffers {
  *  - hw_data
  *  - config data
  *  - runtime data
+ * Note: as this data can be shared in a multi-process scenario,
+ * any pointers in it must also point to shared memory.
  */
-struct qat_sym_dev_private;
-struct qat_asym_dev_private;
-struct qat_comp_dev_private;
-
 struct qat_pci_device {
 
 	/* Data used by all services */
 	char name[QAT_DEV_NAME_MAX_LEN];
 	/**< Name of qat pci device */
 	uint8_t qat_dev_id;
-	/**< Device instance for this qat pci device */
-	struct rte_pci_device *pci_dev;
-	/**< PCI information. */
+	/**< Id of device instance for this qat pci device */
 	enum qat_device_gen qat_dev_gen;
 	/**< QAT device generation */
 	rte_spinlock_t arb_csr_lock;
 	/**< lock to protect accesses to the arbiter CSR */
-	__extension__
-	uint8_t attached : 1;
-	/**< Flag indicating the device is attached */
 
 	struct qat_qp *qps_in_use[QAT_MAX_SERVICES][ADF_MAX_QPS_ON_ANY_SERVICE];
 	/**< links to qps set up for each service, index same as on API */
@@ -67,32 +91,18 @@  struct qat_pci_device {
 	/* Data relating to symmetric crypto service */
 	struct qat_sym_dev_private *sym_dev;
 	/**< link back to cryptodev private data */
-	struct rte_device sym_rte_dev;
-	/**< This represents the crypto sym subset of this pci device.
-	 * Register with this rather than with the one in
-	 * pci_dev so that its driver can have a crypto-specific name
-	 */
+	int qat_sym_driver_id;
+	/**< Symmetric driver id used by this device */
 
 	/* Data relating to asymmetric crypto service */
 	struct qat_asym_dev_private *asym_dev;
 	/**< link back to cryptodev private data */
-	struct rte_device asym_rte_dev;
-	/**< This represents the crypto asym subset of this pci device.
-	 * Register with this rather than with the one in
-	 * pci_dev so that its driver can have a crypto-specific name
-	 */
+	int qat_asym_driver_id;
+	/**< Symmetric driver id used by this device */
 
 	/* Data relating to compression service */
 	struct qat_comp_dev_private *comp_dev;
 	/**< link back to compressdev private data */
-	struct rte_device comp_rte_dev;
-	/**< This represents the compression subset of this pci device.
-	 * Register with this rather than with the one in
-	 * pci_dev so that its driver can have a compression-specific name
-	 */
-
-	/* Data relating to asymmetric crypto service */
-
 };
 
 struct qat_gen_hw_data {
@@ -107,9 +117,6 @@  struct qat_pci_device *
 qat_pci_device_allocate(struct rte_pci_device *pci_dev,
 		struct qat_dev_cmd_param *qat_dev_cmd_param);
 
-int
-qat_pci_device_release(struct rte_pci_device *pci_dev);
-
 struct qat_pci_device *
 qat_get_qat_dev_from_pci_dev(struct rte_pci_device *pci_dev);
 
diff --git a/drivers/common/qat/qat_qp.c b/drivers/common/qat/qat_qp.c
index 8e6dd04..66eb778 100644
--- a/drivers/common/qat/qat_qp.c
+++ b/drivers/common/qat/qat_qp.c
@@ -193,7 +193,8 @@  int qat_qp_setup(struct qat_pci_device *qat_dev,
 
 {
 	struct qat_qp *qp;
-	struct rte_pci_device *pci_dev = qat_dev->pci_dev;
+	struct rte_pci_device *pci_dev =
+			qat_pci_devs[qat_dev->qat_dev_id].pci_dev;
 	char op_cookie_pool_name[RTE_RING_NAMESIZE];
 	uint32_t i;
 
@@ -274,7 +275,7 @@  int qat_qp_setup(struct qat_pci_device *qat_dev,
 				qp->nb_descriptors,
 				qat_qp_conf->cookie_size, 64, 0,
 				NULL, NULL, NULL, NULL,
-				qat_dev->pci_dev->device.numa_node,
+				pci_dev->device.numa_node,
 				0);
 	if (!qp->op_cookie_pool) {
 		QAT_LOG(ERR, "QAT PMD Cannot create"
@@ -379,7 +380,8 @@  qat_queue_create(struct qat_pci_device *qat_dev, struct qat_queue *queue,
 	uint64_t queue_base;
 	void *io_addr;
 	const struct rte_memzone *qp_mz;
-	struct rte_pci_device *pci_dev = qat_dev->pci_dev;
+	struct rte_pci_device *pci_dev =
+			qat_pci_devs[qat_dev->qat_dev_id].pci_dev;
 	int ret = 0;
 	uint16_t desc_size = (dir == ADF_RING_DIR_TX ?
 			qp_conf->hw->tx_msg_size : qp_conf->hw->rx_msg_size);
@@ -403,7 +405,7 @@  qat_queue_create(struct qat_pci_device *qat_dev, struct qat_queue *queue,
 		qp_conf->service_str, "qp_mem",
 		queue->hw_bundle_number, queue->hw_queue_number);
 	qp_mz = queue_dma_zone_reserve(queue->memz_name, queue_size_bytes,
-			qat_dev->pci_dev->device.numa_node);
+			pci_dev->device.numa_node);
 	if (qp_mz == NULL) {
 		QAT_LOG(ERR, "Failed to allocate ring memzone");
 		return -ENOMEM;
diff --git a/drivers/compress/qat/qat_comp_pmd.c b/drivers/compress/qat/qat_comp_pmd.c
index fe62de5..c08c9a3 100644
--- a/drivers/compress/qat/qat_comp_pmd.c
+++ b/drivers/compress/qat/qat_comp_pmd.c
@@ -655,6 +655,8 @@  qat_comp_dev_create(struct qat_pci_device *qat_pci_dev,
 		struct qat_dev_cmd_param *qat_dev_cmd_param)
 {
 	int i = 0;
+	struct qat_device_info *qat_dev_instance =
+			&qat_pci_devs[qat_pci_dev->qat_dev_id];
 	if (qat_pci_dev->qat_dev_gen == QAT_GEN3) {
 		QAT_LOG(ERR, "Compression PMD not supported on QAT P5xxx");
 		return 0;
@@ -662,24 +664,27 @@  qat_comp_dev_create(struct qat_pci_device *qat_pci_dev,
 
 	struct rte_compressdev_pmd_init_params init_params = {
 		.name = "",
-		.socket_id = qat_pci_dev->pci_dev->device.numa_node,
+		.socket_id = qat_dev_instance->pci_dev->device.numa_node,
 	};
 	char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+	char memz_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
 	struct rte_compressdev *compressdev;
 	struct qat_comp_dev_private *comp_dev;
+	const struct rte_compressdev_capabilities *capabilities;
+	uint64_t capa_size;
 
 	snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s",
 			qat_pci_dev->name, "comp");
 	QAT_LOG(DEBUG, "Creating QAT COMP device %s", name);
 
 	/* Populate subset device to use in compressdev device creation */
-	qat_pci_dev->comp_rte_dev.driver = &compdev_qat_driver;
-	qat_pci_dev->comp_rte_dev.numa_node =
-					qat_pci_dev->pci_dev->device.numa_node;
-	qat_pci_dev->comp_rte_dev.devargs = NULL;
+	qat_dev_instance->comp_rte_dev.driver = &compdev_qat_driver;
+	qat_dev_instance->comp_rte_dev.numa_node =
+			qat_dev_instance->pci_dev->device.numa_node;
+	qat_dev_instance->comp_rte_dev.devargs = NULL;
 
 	compressdev = rte_compressdev_pmd_create(name,
-			&(qat_pci_dev->comp_rte_dev),
+			&(qat_dev_instance->comp_rte_dev),
 			sizeof(struct qat_comp_dev_private),
 			&init_params);
 
@@ -694,25 +699,44 @@  qat_comp_dev_create(struct qat_pci_device *qat_pci_dev,
 
 	compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
 
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	snprintf(memz_name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s_MEMZONE",
+			qat_pci_dev->name, "comp");
 	comp_dev = compressdev->data->dev_private;
 	comp_dev->qat_dev = qat_pci_dev;
 	comp_dev->compressdev = compressdev;
-	qat_pci_dev->comp_dev = comp_dev;
 
 	switch (qat_pci_dev->qat_dev_gen) {
 	case QAT_GEN1:
 	case QAT_GEN2:
 	case QAT_GEN3:
-		comp_dev->qat_dev_capabilities = qat_comp_gen_capabilities;
+		capabilities = qat_comp_gen_capabilities;
+		capa_size = sizeof(qat_comp_gen_capabilities);
 		break;
 	default:
-		comp_dev->qat_dev_capabilities = qat_comp_gen_capabilities;
+		capabilities = qat_comp_gen_capabilities;
+		capa_size = sizeof(qat_comp_gen_capabilities);
 		QAT_LOG(DEBUG,
 			"QAT gen %d capabilities unknown, default to GEN1",
 					qat_pci_dev->qat_dev_gen);
 		break;
 	}
 
+	comp_dev->mz = rte_memzone_reserve(memz_name,
+		capa_size,
+		rte_socket_id(), 0);
+	if (comp_dev->mz == NULL) {
+		QAT_LOG(DEBUG, "Error allocating memzone, destroying PMD"
+				" for %s", name);
+		rte_compressdev_pmd_destroy(compressdev);
+		return -EFAULT;
+	}
+
+	memcpy(comp_dev->mz->addr, capabilities, capa_size);
+	comp_dev->qat_dev_capabilities = comp_dev->mz->addr;
+
 	while (1) {
 		if (qat_dev_cmd_param[i].name == NULL)
 			break;
@@ -721,6 +745,7 @@  qat_comp_dev_create(struct qat_pci_device *qat_pci_dev,
 					qat_dev_cmd_param[i].val;
 		i++;
 	}
+	qat_pci_dev->comp_dev = comp_dev;
 
 	QAT_LOG(DEBUG,
 		    "Created QAT COMP device %s as compressdev instance %d",
diff --git a/drivers/compress/qat/qat_comp_pmd.h b/drivers/compress/qat/qat_comp_pmd.h
index 5c7fa9f..24ad572 100644
--- a/drivers/compress/qat/qat_comp_pmd.h
+++ b/drivers/compress/qat/qat_comp_pmd.h
@@ -32,6 +32,8 @@  struct qat_comp_dev_private {
 	/**< The device's pool for qat_comp_xforms */
 	struct rte_mempool *streampool;
 	/**< The device's pool for qat_comp_streams */
+	const struct rte_memzone *mz;
+	/* Shared memzone for storing capabilities */
 	uint16_t min_enq_burst_threshold;
 };
 
diff --git a/drivers/crypto/qat/qat_asym.c b/drivers/crypto/qat/qat_asym.c
index ae0dd79..8597381 100644
--- a/drivers/crypto/qat/qat_asym.c
+++ b/drivers/crypto/qat/qat_asym.c
@@ -475,7 +475,7 @@  qat_asym_build_request(void *in_op,
 	if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
 		ctx = (struct qat_asym_session *)
 			get_asym_session_private_data(
-			op->asym->session, cryptodev_qat_asym_driver_id);
+			op->asym->session, qat_asym_driver_id);
 		if (unlikely(ctx == NULL)) {
 			QAT_LOG(ERR, "Session has not been created for this device");
 			goto error;
@@ -693,7 +693,7 @@  qat_asym_process_response(void **op, uint8_t *resp,
 
 	if (rx_op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
 		ctx = (struct qat_asym_session *)get_asym_session_private_data(
-			rx_op->asym->session, cryptodev_qat_asym_driver_id);
+			rx_op->asym->session, qat_asym_driver_id);
 		qat_asym_collect_response(rx_op, cookie, ctx->xform);
 	} else if (rx_op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
 		qat_asym_collect_response(rx_op, cookie, rx_op->asym->xform);
diff --git a/drivers/crypto/qat/qat_asym_pmd.c b/drivers/crypto/qat/qat_asym_pmd.c
index af3cc25..b747a5a 100644
--- a/drivers/crypto/qat/qat_asym_pmd.c
+++ b/drivers/crypto/qat/qat_asym_pmd.c
@@ -11,7 +11,7 @@ 
 #include "qat_sym_capabilities.h"
 #include "qat_asym_capabilities.h"
 
-uint8_t cryptodev_qat_asym_driver_id;
+uint8_t qat_asym_driver_id;
 
 static const struct rte_cryptodev_capabilities qat_gen1_asym_capabilities[] = {
 	QAT_BASE_GEN1_ASYM_CAPABILITIES,
@@ -63,7 +63,7 @@  static void qat_asym_dev_info_get(struct rte_cryptodev *dev,
 							QAT_SERVICE_ASYMMETRIC);
 		info->feature_flags = dev->feature_flags;
 		info->capabilities = internals->qat_dev_capabilities;
-		info->driver_id = cryptodev_qat_asym_driver_id;
+		info->driver_id = qat_asym_driver_id;
 		/* No limit of number of sessions */
 		info->sym.max_nb_sessions = 0;
 	}
@@ -239,33 +239,49 @@  qat_asym_dev_create(struct qat_pci_device *qat_pci_dev,
 		struct qat_dev_cmd_param *qat_dev_cmd_param)
 {
 	int i = 0;
+	struct qat_device_info *qat_dev_instance =
+			&qat_pci_devs[qat_pci_dev->qat_dev_id];
 	struct rte_cryptodev_pmd_init_params init_params = {
 			.name = "",
-			.socket_id = qat_pci_dev->pci_dev->device.numa_node,
+			.socket_id = qat_dev_instance->pci_dev->device.numa_node,
 			.private_data_size = sizeof(struct qat_asym_dev_private)
 	};
 	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	char memz_name[RTE_CRYPTODEV_NAME_MAX_LEN];
 	struct rte_cryptodev *cryptodev;
 	struct qat_asym_dev_private *internals;
 
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		qat_pci_dev->qat_asym_driver_id =
+				qat_asym_driver_id;
+	} else if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		if (qat_pci_dev->qat_asym_driver_id !=
+				qat_asym_driver_id) {
+			QAT_LOG(ERR, "Device %s have different driver id than "
+					"corresponding device in primary process"
+					, name);
+			return -(EFAULT);
+		}
+	}
+
 	snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s",
 			qat_pci_dev->name, "asym");
 	QAT_LOG(DEBUG, "Creating QAT ASYM device %s\n", name);
 
 	/* Populate subset device to use in cryptodev device creation */
-	qat_pci_dev->asym_rte_dev.driver = &cryptodev_qat_asym_driver;
-	qat_pci_dev->asym_rte_dev.numa_node =
-				qat_pci_dev->pci_dev->device.numa_node;
-	qat_pci_dev->asym_rte_dev.devargs = NULL;
+	qat_dev_instance->asym_rte_dev.driver = &cryptodev_qat_asym_driver;
+	qat_dev_instance->asym_rte_dev.numa_node =
+			qat_dev_instance->pci_dev->device.numa_node;
+	qat_dev_instance->asym_rte_dev.devargs = NULL;
 
 	cryptodev = rte_cryptodev_pmd_create(name,
-			&(qat_pci_dev->asym_rte_dev), &init_params);
+			&(qat_dev_instance->asym_rte_dev), &init_params);
 
 	if (cryptodev == NULL)
 		return -ENODEV;
 
-	qat_pci_dev->asym_rte_dev.name = cryptodev->data->name;
-	cryptodev->driver_id = cryptodev_qat_asym_driver_id;
+	qat_dev_instance->asym_rte_dev.name = cryptodev->data->name;
+	cryptodev->driver_id = qat_asym_driver_id;
 	cryptodev->dev_ops = &crypto_qat_ops;
 
 	cryptodev->enqueue_burst = qat_asym_pmd_enqueue_op_burst;
@@ -276,12 +292,30 @@  qat_asym_dev_create(struct qat_pci_device *qat_pci_dev,
 			RTE_CRYPTODEV_FF_ASYM_SESSIONLESS |
 			RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP |
 			RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT;
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	snprintf(memz_name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s_MEMZONE",
+			qat_pci_dev->name, "asym");
 	internals = cryptodev->data->dev_private;
 	internals->qat_dev = qat_pci_dev;
-	qat_pci_dev->asym_dev = internals;
 
 	internals->asym_dev_id = cryptodev->data->dev_id;
 	internals->qat_dev_capabilities = qat_gen1_asym_capabilities;
+	internals->mz = rte_memzone_reserve(memz_name,
+		sizeof(qat_gen1_asym_capabilities),
+		rte_socket_id(), 0);
+	if (internals->mz == NULL) {
+		QAT_LOG(DEBUG, "Error allocating memzone, destroying PMD"
+				" for %s", name);
+		rte_cryptodev_pmd_destroy(cryptodev);
+		return -EFAULT;
+	}
+
+	memcpy(internals->mz->addr, qat_gen1_asym_capabilities,
+			sizeof(qat_gen1_asym_capabilities));
+	internals->qat_dev_capabilities = internals->mz->addr;
 
 	while (1) {
 		if (qat_dev_cmd_param[i].name == NULL)
@@ -292,6 +326,7 @@  qat_asym_dev_create(struct qat_pci_device *qat_pci_dev,
 		i++;
 	}
 
+	qat_pci_dev->asym_dev = internals;
 	QAT_LOG(DEBUG, "Created QAT ASYM device %s as cryptodev instance %d",
 			cryptodev->data->name, internals->asym_dev_id);
 	return 0;
@@ -307,11 +342,12 @@  qat_asym_dev_destroy(struct qat_pci_device *qat_pci_dev)
 	if (qat_pci_dev->asym_dev == NULL)
 		return 0;
 
+	rte_memzone_free(qat_pci_dev->asym_dev->mz);
 	/* free crypto device */
 	cryptodev = rte_cryptodev_pmd_get_dev(
 			qat_pci_dev->asym_dev->asym_dev_id);
 	rte_cryptodev_pmd_destroy(cryptodev);
-	qat_pci_dev->asym_rte_dev.name = NULL;
+	qat_pci_devs[qat_pci_dev->qat_dev_id].asym_rte_dev.name = NULL;
 	qat_pci_dev->asym_dev = NULL;
 
 	return 0;
@@ -320,4 +356,4 @@  qat_asym_dev_destroy(struct qat_pci_device *qat_pci_dev)
 static struct cryptodev_driver qat_crypto_drv;
 RTE_PMD_REGISTER_CRYPTO_DRIVER(qat_crypto_drv,
 		cryptodev_qat_asym_driver,
-		cryptodev_qat_asym_driver_id);
+		qat_asym_driver_id);
diff --git a/drivers/crypto/qat/qat_asym_pmd.h b/drivers/crypto/qat/qat_asym_pmd.h
index 0535bc6..25ba4c7 100644
--- a/drivers/crypto/qat/qat_asym_pmd.h
+++ b/drivers/crypto/qat/qat_asym_pmd.h
@@ -13,7 +13,7 @@ 
 #define CRYPTODEV_NAME_QAT_ASYM_PMD	crypto_qat_asym
 
 
-extern uint8_t cryptodev_qat_asym_driver_id;
+extern uint8_t qat_asym_driver_id;
 
 /** private data structure for a QAT device.
  * This QAT device is a device offering only asymmetric crypto service,
@@ -26,6 +26,8 @@  struct qat_asym_dev_private {
 	/**< Device instance for this rte_cryptodev */
 	const struct rte_cryptodev_capabilities *qat_dev_capabilities;
 	/* QAT device asymmetric crypto capabilities */
+	const struct rte_memzone *mz;
+	/* Shared memzone for storing capabilities */
 	uint16_t min_enq_burst_threshold;
 };
 
diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c
index 25b6dd5..2e4cfec 100644
--- a/drivers/crypto/qat/qat_sym.c
+++ b/drivers/crypto/qat/qat_sym.c
@@ -180,7 +180,7 @@  qat_sym_build_request(void *in_op, uint8_t *out_msg,
 	}
 
 	ctx = (struct qat_sym_session *)get_sym_session_private_data(
-			op->sym->session, cryptodev_qat_driver_id);
+			op->sym->session, qat_sym_driver_id);
 
 	if (unlikely(ctx == NULL)) {
 		QAT_DP_LOG(ERR, "Session was not created for this device");
diff --git a/drivers/crypto/qat/qat_sym.h b/drivers/crypto/qat/qat_sym.h
index bc6426c..758b06d 100644
--- a/drivers/crypto/qat/qat_sym.h
+++ b/drivers/crypto/qat/qat_sym.h
@@ -155,7 +155,7 @@  qat_sym_process_response(void **op, uint8_t *resp)
 		struct qat_sym_session *sess = (struct qat_sym_session *)
 						get_sym_session_private_data(
 						rx_op->sym->session,
-						cryptodev_qat_driver_id);
+						qat_sym_driver_id);
 
 
 		if (sess->bpi_ctx)
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index e887c88..221f0f6 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -16,7 +16,7 @@ 
 
 #define MIXED_CRYPTO_MIN_FW_VER 0x04090000
 
-uint8_t cryptodev_qat_driver_id;
+uint8_t qat_sym_driver_id;
 
 static const struct rte_cryptodev_capabilities qat_gen1_sym_capabilities[] = {
 	QAT_BASE_GEN1_SYM_CAPABILITIES,
@@ -29,6 +29,12 @@  static const struct rte_cryptodev_capabilities qat_gen2_sym_capabilities[] = {
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
 
+static const struct rte_cryptodev_capabilities qat_gen3_sym_capabilities[] = {
+	QAT_BASE_GEN1_SYM_CAPABILITIES,
+	QAT_EXTRA_GEN2_SYM_CAPABILITIES,
+	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
+};
+
 static int qat_sym_qp_release(struct rte_cryptodev *dev,
 	uint16_t queue_pair_id);
 
@@ -74,7 +80,7 @@  static void qat_sym_dev_info_get(struct rte_cryptodev *dev,
 			qat_qps_per_service(sym_hw_qps, QAT_SERVICE_SYMMETRIC);
 		info->feature_flags = dev->feature_flags;
 		info->capabilities = internals->qat_dev_capabilities;
-		info->driver_id = cryptodev_qat_driver_id;
+		info->driver_id = qat_sym_driver_id;
 		/* No limit of number of sessions */
 		info->sym.max_nb_sessions = 0;
 	}
@@ -268,33 +274,51 @@  qat_sym_dev_create(struct qat_pci_device *qat_pci_dev,
 		struct qat_dev_cmd_param *qat_dev_cmd_param __rte_unused)
 {
 	int i = 0;
+	struct qat_device_info *qat_dev_instance =
+			&qat_pci_devs[qat_pci_dev->qat_dev_id];
 	struct rte_cryptodev_pmd_init_params init_params = {
 			.name = "",
-			.socket_id = qat_pci_dev->pci_dev->device.numa_node,
+			.socket_id = qat_dev_instance->pci_dev->device.numa_node,
 			.private_data_size = sizeof(struct qat_sym_dev_private)
 	};
 	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	char memz_name[RTE_CRYPTODEV_NAME_MAX_LEN];
 	struct rte_cryptodev *cryptodev;
 	struct qat_sym_dev_private *internals;
+	const struct rte_cryptodev_capabilities *capabilities;
+	uint64_t capa_size;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		qat_pci_dev->qat_sym_driver_id =
+				qat_sym_driver_id;
+	} else if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		if (qat_pci_dev->qat_sym_driver_id !=
+				qat_sym_driver_id) {
+			QAT_LOG(ERR, "Device %s have different driver id than "
+					"corresponding device in primary process"
+					, name);
+			return -(EFAULT);
+		}
+	}
 
 	snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s",
 			qat_pci_dev->name, "sym");
 	QAT_LOG(DEBUG, "Creating QAT SYM device %s", name);
 
 	/* Populate subset device to use in cryptodev device creation */
-	qat_pci_dev->sym_rte_dev.driver = &cryptodev_qat_sym_driver;
-	qat_pci_dev->sym_rte_dev.numa_node =
-				qat_pci_dev->pci_dev->device.numa_node;
-	qat_pci_dev->sym_rte_dev.devargs = NULL;
+	qat_dev_instance->sym_rte_dev.driver = &cryptodev_qat_sym_driver;
+	qat_dev_instance->sym_rte_dev.numa_node =
+			qat_dev_instance->pci_dev->device.numa_node;
+	qat_dev_instance->sym_rte_dev.devargs = NULL;
 
 	cryptodev = rte_cryptodev_pmd_create(name,
-			&(qat_pci_dev->sym_rte_dev), &init_params);
+			&(qat_dev_instance->sym_rte_dev), &init_params);
 
 	if (cryptodev == NULL)
 		return -ENODEV;
 
-	qat_pci_dev->sym_rte_dev.name = cryptodev->data->name;
-	cryptodev->driver_id = cryptodev_qat_driver_id;
+	qat_dev_instance->sym_rte_dev.name = cryptodev->data->name;
+	cryptodev->driver_id = qat_sym_driver_id;
 	cryptodev->dev_ops = &crypto_qat_ops;
 
 	cryptodev->enqueue_burst = qat_sym_pmd_enqueue_op_burst;
@@ -310,27 +334,49 @@  qat_sym_dev_create(struct qat_pci_device *qat_pci_dev,
 			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
 			RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED;
 
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	snprintf(memz_name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s_MEMZONE",
+			qat_pci_dev->name, "sym");
+
 	internals = cryptodev->data->dev_private;
 	internals->qat_dev = qat_pci_dev;
-	qat_pci_dev->sym_dev = internals;
-
 	internals->sym_dev_id = cryptodev->data->dev_id;
+
 	switch (qat_pci_dev->qat_dev_gen) {
 	case QAT_GEN1:
-		internals->qat_dev_capabilities = qat_gen1_sym_capabilities;
+		capabilities = qat_gen1_sym_capabilities;
+		capa_size = sizeof(qat_gen1_sym_capabilities);
 		break;
 	case QAT_GEN2:
+		capabilities = qat_gen2_sym_capabilities;
+		capa_size = sizeof(qat_gen2_sym_capabilities);
+		break;
 	case QAT_GEN3:
-		internals->qat_dev_capabilities = qat_gen2_sym_capabilities;
+		capabilities = qat_gen3_sym_capabilities;
+		capa_size = sizeof(qat_gen3_sym_capabilities);
 		break;
 	default:
-		internals->qat_dev_capabilities = qat_gen2_sym_capabilities;
 		QAT_LOG(DEBUG,
-			"QAT gen %d capabilities unknown, default to GEN2",
+			"QAT gen %d capabilities unknown	",
 					qat_pci_dev->qat_dev_gen);
-		break;
+		return -(EINVAL);
+	}
+
+	internals->mz = rte_memzone_reserve(memz_name,
+		capa_size,
+		rte_socket_id(), 0);
+	if (internals->mz == NULL) {
+		QAT_LOG(DEBUG, "Error allocating memzone, destroying PMD"
+				" for %s", name);
+		rte_cryptodev_pmd_destroy(cryptodev);
+		return -EFAULT;
 	}
 
+	memcpy(internals->mz->addr, capabilities, capa_size);
+	internals->qat_dev_capabilities = internals->mz->addr;
 	while (1) {
 		if (qat_dev_cmd_param[i].name == NULL)
 			break;
@@ -340,8 +386,10 @@  qat_sym_dev_create(struct qat_pci_device *qat_pci_dev,
 		i++;
 	}
 
+	qat_pci_dev->sym_dev = internals;
 	QAT_LOG(DEBUG, "Created QAT SYM device %s as cryptodev instance %d",
 			cryptodev->data->name, internals->sym_dev_id);
+
 	return 0;
 }
 
@@ -355,10 +403,11 @@  qat_sym_dev_destroy(struct qat_pci_device *qat_pci_dev)
 	if (qat_pci_dev->sym_dev == NULL)
 		return 0;
 
+	rte_memzone_free(qat_pci_dev->sym_dev->mz);
 	/* free crypto device */
 	cryptodev = rte_cryptodev_pmd_get_dev(qat_pci_dev->sym_dev->sym_dev_id);
 	rte_cryptodev_pmd_destroy(cryptodev);
-	qat_pci_dev->sym_rte_dev.name = NULL;
+	qat_pci_devs[qat_pci_dev->qat_dev_id].sym_rte_dev.name = NULL;
 	qat_pci_dev->sym_dev = NULL;
 
 	return 0;
@@ -367,4 +416,4 @@  qat_sym_dev_destroy(struct qat_pci_device *qat_pci_dev)
 static struct cryptodev_driver qat_crypto_drv;
 RTE_PMD_REGISTER_CRYPTO_DRIVER(qat_crypto_drv,
 		cryptodev_qat_sym_driver,
-		cryptodev_qat_driver_id);
+		qat_sym_driver_id);
diff --git a/drivers/crypto/qat/qat_sym_pmd.h b/drivers/crypto/qat/qat_sym_pmd.h
index a5a31e5..2c8204c 100644
--- a/drivers/crypto/qat/qat_sym_pmd.h
+++ b/drivers/crypto/qat/qat_sym_pmd.h
@@ -19,7 +19,7 @@ 
 #define QAT_SYM_CAP_MIXED_CRYPTO	(1 << 0)
 #define QAT_SYM_CAP_VALID		(1 << 31)
 
-extern uint8_t cryptodev_qat_driver_id;
+extern uint8_t qat_sym_driver_id;
 
 /** private data structure for a QAT device.
  * This QAT device is a device offering only symmetric crypto service,
@@ -32,6 +32,8 @@  struct qat_sym_dev_private {
 	/**< Device instance for this rte_cryptodev */
 	const struct rte_cryptodev_capabilities *qat_dev_capabilities;
 	/* QAT device symmetric crypto capabilities */
+	const struct rte_memzone *mz;
+	/* Shared memzone for storing capabilities */
 	uint16_t min_enq_burst_threshold;
 	uint32_t internal_capabilities; /* see flags QAT_SYM_CAP_xxx */
 };