Browse Source

qce: stability and performance improvements

1. There is no need to vote for high bandwidth for every
ioctl operation, Instead, vote only when a new device
node is opened (which translates to a new session from
a userspace point of view).
2. Fix the way BAM pipes are reset when there is a crypto
operation by initializing it correctly through the SPS
BAM framework.
3. Checking crypto status for every request is performance
heavy. Remove these checks and read status only on
error conditions.

Change-Id: Ibb3607ecb6919f563b00a9a8cd6f5440a8c3940a
Gaurav Kashyap 2 years ago
parent
commit
ab140f0f11
2 changed files with 70 additions and 28 deletions
  1. 67 11
      crypto-qti/qce50.c
  2. 3 17
      crypto-qti/qcedev.c

+ 67 - 11
crypto-qti/qce50.c

@@ -36,7 +36,7 @@
 #define CRYPTO_SMMU_IOVA_START 0x10000000
 #define CRYPTO_SMMU_IOVA_SIZE 0x40000000
 
-#define CRYPTO_CONFIG_RESET 0xE001F
+#define CRYPTO_CONFIG_RESET 0xE01EF
 #define MAX_SPS_DESC_FIFO_SIZE 0xfff0
 #define QCE_MAX_NUM_DSCR    0x200
 #define QCE_SECTOR_SIZE	    0x200
@@ -2233,9 +2233,66 @@ static int _qce_unlock_other_pipes(struct qce_device *pce_dev, int req_info)
 static inline void qce_free_req_info(struct qce_device *pce_dev, int req_info,
 		bool is_complete);
 
+static int qce_sps_pipe_reset(struct qce_device *pce_dev, int op)
+{
+	int rc = -1;
+	struct sps_pipe *sps_pipe_info = NULL;
+	struct sps_connect *sps_connect_info = NULL;
+
+	/* Reset both the pipe sets in the pipe group */
+	sps_pipe_reset(pce_dev->ce_bam_info.bam_handle,
+			pce_dev->ce_bam_info.dest_pipe_index[op]);
+	sps_pipe_reset(pce_dev->ce_bam_info.bam_handle,
+			pce_dev->ce_bam_info.src_pipe_index[op]);
+
+	/* Reconnect to consumer pipe */
+	sps_pipe_info = pce_dev->ce_bam_info.consumer[op].pipe;
+	sps_connect_info = &pce_dev->ce_bam_info.consumer[op].connect;
+	rc = sps_disconnect(sps_pipe_info);
+	if (rc) {
+		pr_err("sps_disconnect() fail pipe=0x%lx, rc = %d\n",
+		(uintptr_t)sps_pipe_info, rc);
+		goto exit;
+	}
+	memset(sps_connect_info->desc.base, 0x00,
+				sps_connect_info->desc.size);
+	rc = sps_connect(sps_pipe_info, sps_connect_info);
+	if (rc) {
+		pr_err("sps_connect() fail pipe=0x%lx, rc = %d\n",
+		(uintptr_t)sps_pipe_info, rc);
+		goto exit;
+	}
+
+	/* Reconnect to producer pipe */
+	sps_pipe_info = pce_dev->ce_bam_info.producer[op].pipe;
+	sps_connect_info = &pce_dev->ce_bam_info.producer[op].connect;
+	rc = sps_disconnect(sps_pipe_info);
+	if (rc) {
+		pr_err("sps_connect() fail pipe=0x%lx, rc = %d\n",
+		(uintptr_t)sps_pipe_info, rc);
+		goto exit;
+	}
+	memset(sps_connect_info->desc.base, 0x00,
+				sps_connect_info->desc.size);
+	rc = sps_connect(sps_pipe_info, sps_connect_info);
+	if (rc) {
+		pr_err("sps_connect() fail pipe=0x%lx, rc = %d\n",
+		(uintptr_t)sps_pipe_info, rc);
+		goto exit;
+	}
+
+	/* Register producer callback */
+	rc = sps_register_event(sps_pipe_info,
+			&pce_dev->ce_bam_info.producer[op].event);
+	if (rc)
+		pr_err("Producer cb registration failed rc = %d\n",
+							rc);
+exit:
+	return rc;
+}
+
 int qce_manage_timeout(void *handle, int req_info)
 {
-	int rc = 0;
 	struct qce_device *pce_dev = (struct qce_device *) handle;
 	struct skcipher_request *areq;
 	struct ce_request_info *preq_info;
@@ -2247,17 +2304,16 @@ int qce_manage_timeout(void *handle, int req_info)
 	areq = (struct skcipher_request *) preq_info->areq;
 
 	pr_info("%s: req info = %d, offload op = %d\n", __func__, req_info,  op);
-	rc = _qce_unlock_other_pipes(pce_dev, req_info);
-	if (rc)
-		pr_err("%s: fail unlock other pipes, rc = %d", __func__, rc);
+
+	if (qce_sps_pipe_reset(pce_dev, op))
+		pr_err("%s: pipe reset failed\n", __func__);
+
+	if (_qce_unlock_other_pipes(pce_dev, req_info))
+		pr_err("%s: fail unlock other pipes\n", __func__);
+
 	qce_free_req_info(pce_dev, req_info, true);
 	qce_callback(areq, NULL, NULL, 0);
-	sps_pipe_reset(pce_dev->ce_bam_info.bam_handle,
-			pce_dev->ce_bam_info.dest_pipe_index[op]);
-	sps_pipe_reset(pce_dev->ce_bam_info.bam_handle,
-			pce_dev->ce_bam_info.src_pipe_index[op]);
-
-	return rc;
+	return 0;
 }
 EXPORT_SYMBOL(qce_manage_timeout);
 

+ 3 - 17
crypto-qti/qcedev.c

@@ -273,6 +273,8 @@ static int qcedev_open(struct inode *inode, struct file *file)
 	handle->cntl = podev;
 	file->private_data = handle;
 
+	qcedev_ce_high_bw_req(podev, true);
+
 	mutex_init(&handle->registeredbufs.lock);
 	INIT_LIST_HEAD(&handle->registeredbufs.list);
 	return 0;
@@ -290,6 +292,7 @@ static int qcedev_release(struct inode *inode, struct file *file)
 					__func__, podev);
 	}
 
+	qcedev_ce_high_bw_req(podev, false);
 	if (qcedev_unmap_all_buffers(handle))
 		pr_err("%s: failed to unmap all ion buffers\n", __func__);
 
@@ -719,7 +722,6 @@ static void qcedev_check_crypto_status(
 					QCEDEV_OFFLOAD_GENERIC_ERROR;
 		return;
 	}
-
 }
 
 static int submit_req(struct qcedev_async_req *qcedev_areq,
@@ -736,10 +738,6 @@ static int submit_req(struct qcedev_async_req *qcedev_areq,
 	qcedev_areq->err = 0;
 	podev = handle->cntl;
 
-	qcedev_check_crypto_status(qcedev_areq, podev->qce, print_sts);
-	if (qcedev_areq->offload_cipher_op_req.err != QCEDEV_OFFLOAD_NO_ERROR)
-		return 0;
-
 	spin_lock_irqsave(&podev->lock, flags);
 
 	if (podev->active_command == NULL) {
@@ -783,10 +781,6 @@ static int submit_req(struct qcedev_async_req *qcedev_areq,
 	if (ret)
 		qcedev_areq->err = -EIO;
 
-	qcedev_check_crypto_status(qcedev_areq, podev->qce, print_sts);
-	if (qcedev_areq->offload_cipher_op_req.err != QCEDEV_OFFLOAD_NO_ERROR)
-		return 0;
-
 	pstat = &_qcedev_stat;
 	if (qcedev_areq->op_type == QCEDEV_CRYPTO_OPER_CIPHER) {
 		switch (qcedev_areq->cipher_op_req.op) {
@@ -2109,10 +2103,6 @@ long qcedev_ioctl(struct file *file,
 	init_completion(&qcedev_areq->complete);
 	pstat = &_qcedev_stat;
 
-	if (cmd != QCEDEV_IOCTL_MAP_BUF_REQ &&
-		cmd != QCEDEV_IOCTL_UNMAP_BUF_REQ)
-		qcedev_ce_high_bw_req(podev, true);
-
 	switch (cmd) {
 	case QCEDEV_IOCTL_ENC_REQ:
 	case QCEDEV_IOCTL_DEC_REQ:
@@ -2148,7 +2138,6 @@ long qcedev_ioctl(struct file *file,
 			err = -EFAULT;
 			goto exit_free_qcedev_areq;
 		}
-
 		qcedev_areq->op_type = QCEDEV_CRYPTO_OPER_OFFLOAD_CIPHER;
 		if (qcedev_check_offload_cipher_params(
 				&qcedev_areq->offload_cipher_op_req, podev)) {
@@ -2428,9 +2417,6 @@ long qcedev_ioctl(struct file *file,
 	}
 
 exit_free_qcedev_areq:
-	if (cmd != QCEDEV_IOCTL_MAP_BUF_REQ &&
-		cmd != QCEDEV_IOCTL_UNMAP_BUF_REQ && podev != NULL)
-		qcedev_ce_high_bw_req(podev, false);
 	kfree(qcedev_areq);
 	return err;
 }