Torsten Duwe 4bee9a
From 38682383973280e5be2802ba8a8d4a636d36cb19 Mon Sep 17 00:00:00 2001
Torsten Duwe 4bee9a
From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Torsten Duwe 4bee9a
Date: Mon, 9 May 2022 14:34:10 +0100
Torsten Duwe 4bee9a
Subject: [PATCH] crypto: qat - add backlog mechanism
Torsten Duwe 4bee9a
Git-commit: 38682383973280e5be2802ba8a8d4a636d36cb19
Torsten Duwe 4bee9a
Patch-mainline: v5.19-rc1
Torsten Duwe 4bee9a
References: jsc#PED-1073
Torsten Duwe 4bee9a
Torsten Duwe 4bee9a
The implementations of the crypto algorithms (aead, skcipher, etc) in
Torsten Duwe 4bee9a
the QAT driver do not properly support requests with the
Torsten Duwe 4bee9a
CRYPTO_TFM_REQ_MAY_BACKLOG flag set. If the HW queue is full, the driver
Torsten Duwe 4bee9a
returns -EBUSY but does not enqueue the request. This can result in
Torsten Duwe 4bee9a
applications like dm-crypt waiting indefinitely for the completion of a
Torsten Duwe 4bee9a
request that was never submitted to the hardware.
Torsten Duwe 4bee9a
Torsten Duwe 4bee9a
Fix this by adding a software backlog queue: if the ring buffer is more
Torsten Duwe 4bee9a
than eighty percent full, then the request is enqueued to a backlog
Torsten Duwe 4bee9a
list and the error code -EBUSY is returned back to the caller.
Torsten Duwe 4bee9a
Requests in the backlog queue are resubmitted at a later time, in the
Torsten Duwe 4bee9a
context of the callback of a previously submitted request.
Torsten Duwe 4bee9a
The request for which -EBUSY is returned is then marked as -EINPROGRESS
Torsten Duwe 4bee9a
once submitted to the HW queues.
Torsten Duwe 4bee9a
Torsten Duwe 4bee9a
The submission loop inside the function qat_alg_send_message() has been
Torsten Duwe 4bee9a
modified to decide which submission policy to use based on the request
Torsten Duwe 4bee9a
flags. If the request does not have the CRYPTO_TFM_REQ_MAY_BACKLOG set,
Torsten Duwe 4bee9a
the previous behaviour has been preserved.
Torsten Duwe 4bee9a
Torsten Duwe 4bee9a
Based on a patch by
Torsten Duwe 4bee9a
Vishnu Das Ramachandran <vishnu.dasx.ramachandran@intel.com>
Torsten Duwe 4bee9a
Torsten Duwe 4bee9a
Cc: stable@vger.kernel.org
Torsten Duwe 4bee9a
Fixes: d370cec32194 ("crypto: qat - Intel(R) QAT crypto interface")
Torsten Duwe 4bee9a
Reported-by: Mikulas Patocka <mpatocka@redhat.com>
Torsten Duwe 4bee9a
Reported-by: Kyle Sanderson <kyle.leet@gmail.com>
Torsten Duwe 4bee9a
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Torsten Duwe 4bee9a
Reviewed-by: Marco Chiappero <marco.chiappero@intel.com>
Torsten Duwe 4bee9a
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Torsten Duwe 4bee9a
Signed-off-by: Torsten Duwe <duwe@suse.de>
Torsten Duwe 4bee9a
Torsten Duwe 4bee9a
---
Torsten Duwe 4bee9a
 drivers/crypto/qat/qat_common/adf_transport.c | 11 +++
Torsten Duwe 4bee9a
 drivers/crypto/qat/qat_common/adf_transport.h |  1 +
Torsten Duwe 4bee9a
 .../qat/qat_common/adf_transport_internal.h   |  1 +
Torsten Duwe 4bee9a
 drivers/crypto/qat/qat_common/qat_algs.c      | 24 ++++---
Torsten Duwe 4bee9a
 drivers/crypto/qat/qat_common/qat_algs_send.c | 67 ++++++++++++++++++-
Torsten Duwe 4bee9a
 drivers/crypto/qat/qat_common/qat_algs_send.h |  1 +
Torsten Duwe 4bee9a
 drivers/crypto/qat/qat_common/qat_asym_algs.c | 23 ++++---
Torsten Duwe 4bee9a
 drivers/crypto/qat/qat_common/qat_crypto.c    |  3 +
Torsten Duwe 4bee9a
 drivers/crypto/qat/qat_common/qat_crypto.h    | 10 +++
Torsten Duwe 4bee9a
 9 files changed, 123 insertions(+), 18 deletions(-)
Torsten Duwe 4bee9a
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/adf_transport.c b/drivers/crypto/qat/qat_common/adf_transport.c
Torsten Duwe 4bee9a
index 8ba28409fb74b..630d0483c4e0a 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/adf_transport.c
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/adf_transport.c
Torsten Duwe 4bee9a
@@ -8,6 +8,9 @@
Torsten Duwe 4bee9a
 #include "adf_cfg.h"
Torsten Duwe 4bee9a
 #include "adf_common_drv.h"
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
+#define ADF_MAX_RING_THRESHOLD		80
Torsten Duwe 4bee9a
+#define ADF_PERCENT(tot, percent)	(((tot) * (percent)) / 100)
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
 static inline u32 adf_modulo(u32 data, u32 shift)
Torsten Duwe 4bee9a
 {
Torsten Duwe 4bee9a
 	u32 div = data >> shift;
Torsten Duwe 4bee9a
@@ -77,6 +80,11 @@ static void adf_disable_ring_irq(struct adf_etr_bank_data *bank, u32 ring)
Torsten Duwe 4bee9a
 				      bank->irq_mask);
Torsten Duwe 4bee9a
 }
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
+bool adf_ring_nearly_full(struct adf_etr_ring_data *ring)
Torsten Duwe 4bee9a
+{
Torsten Duwe 4bee9a
+	return atomic_read(ring->inflights) > ring->threshold;
Torsten Duwe 4bee9a
+}
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
 int adf_send_message(struct adf_etr_ring_data *ring, u32 *msg)
Torsten Duwe 4bee9a
 {
Torsten Duwe 4bee9a
 	struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(ring->bank->accel_dev);
Torsten Duwe 4bee9a
@@ -217,6 +225,7 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
Torsten Duwe 4bee9a
 	struct adf_etr_bank_data *bank;
Torsten Duwe 4bee9a
 	struct adf_etr_ring_data *ring;
Torsten Duwe 4bee9a
 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
Torsten Duwe 4bee9a
+	int max_inflights;
Torsten Duwe 4bee9a
 	u32 ring_num;
Torsten Duwe 4bee9a
 	int ret;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
@@ -263,6 +272,8 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
Torsten Duwe 4bee9a
 	ring->ring_size = adf_verify_ring_size(msg_size, num_msgs);
Torsten Duwe 4bee9a
 	ring->head = 0;
Torsten Duwe 4bee9a
 	ring->tail = 0;
Torsten Duwe 4bee9a
+	max_inflights = ADF_MAX_INFLIGHTS(ring->ring_size, ring->msg_size);
Torsten Duwe 4bee9a
+	ring->threshold = ADF_PERCENT(max_inflights, ADF_MAX_RING_THRESHOLD);
Torsten Duwe 4bee9a
 	atomic_set(ring->inflights, 0);
Torsten Duwe 4bee9a
 	ret = adf_init_ring(ring);
Torsten Duwe 4bee9a
 	if (ret)
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/adf_transport.h b/drivers/crypto/qat/qat_common/adf_transport.h
Torsten Duwe 4bee9a
index 2c95f1697c76f..e6ef6f9b76913 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/adf_transport.h
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/adf_transport.h
Torsten Duwe 4bee9a
@@ -14,6 +14,7 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
Torsten Duwe 4bee9a
 		    const char *ring_name, adf_callback_fn callback,
Torsten Duwe 4bee9a
 		    int poll_mode, struct adf_etr_ring_data **ring_ptr);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
+bool adf_ring_nearly_full(struct adf_etr_ring_data *ring);
Torsten Duwe 4bee9a
 int adf_send_message(struct adf_etr_ring_data *ring, u32 *msg);
Torsten Duwe 4bee9a
 void adf_remove_ring(struct adf_etr_ring_data *ring);
Torsten Duwe 4bee9a
 #endif
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/adf_transport_internal.h b/drivers/crypto/qat/qat_common/adf_transport_internal.h
Torsten Duwe 4bee9a
index 501bcf0f1809a..8b2c92ba7ca1f 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/adf_transport_internal.h
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/adf_transport_internal.h
Torsten Duwe 4bee9a
@@ -22,6 +22,7 @@ struct adf_etr_ring_data {
Torsten Duwe 4bee9a
 	spinlock_t lock;	/* protects ring data struct */
Torsten Duwe 4bee9a
 	u16 head;
Torsten Duwe 4bee9a
 	u16 tail;
Torsten Duwe 4bee9a
+	u32 threshold;
Torsten Duwe 4bee9a
 	u8 ring_number;
Torsten Duwe 4bee9a
 	u8 ring_size;
Torsten Duwe 4bee9a
 	u8 msg_size;
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
Torsten Duwe 4bee9a
index 6017ae82c7133..873533dc43a74 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/qat_algs.c
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/qat_algs.c
Torsten Duwe 4bee9a
@@ -935,19 +935,25 @@ void qat_alg_callback(void *resp)
Torsten Duwe 4bee9a
 	struct icp_qat_fw_la_resp *qat_resp = resp;
Torsten Duwe 4bee9a
 	struct qat_crypto_request *qat_req =
Torsten Duwe 4bee9a
 				(void *)(__force long)qat_resp->opaque_data;
Torsten Duwe 4bee9a
+	struct qat_instance_backlog *backlog = qat_req->alg_req.backlog;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 	qat_req->cb(qat_resp, qat_req);
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	qat_alg_send_backlog(backlog);
Torsten Duwe 4bee9a
 }
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 static int qat_alg_send_sym_message(struct qat_crypto_request *qat_req,
Torsten Duwe 4bee9a
-				    struct qat_crypto_instance *inst)
Torsten Duwe 4bee9a
+				    struct qat_crypto_instance *inst,
Torsten Duwe 4bee9a
+				    struct crypto_async_request *base)
Torsten Duwe 4bee9a
 {
Torsten Duwe 4bee9a
-	struct qat_alg_req req;
Torsten Duwe 4bee9a
+	struct qat_alg_req *alg_req = &qat_req->alg_req;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	req.fw_req = (u32 *)&qat_req->req;
Torsten Duwe 4bee9a
-	req.tx_ring = inst->sym_tx;
Torsten Duwe 4bee9a
+	alg_req->fw_req = (u32 *)&qat_req->req;
Torsten Duwe 4bee9a
+	alg_req->tx_ring = inst->sym_tx;
Torsten Duwe 4bee9a
+	alg_req->base = base;
Torsten Duwe 4bee9a
+	alg_req->backlog = &inst->backlog;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	return qat_alg_send_message(&req;;
Torsten Duwe 4bee9a
+	return qat_alg_send_message(alg_req);
Torsten Duwe 4bee9a
 }
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 static int qat_alg_aead_dec(struct aead_request *areq)
Torsten Duwe 4bee9a
@@ -987,7 +993,7 @@ static int qat_alg_aead_dec(struct aead_request *areq)
Torsten Duwe 4bee9a
 	auth_param->auth_off = 0;
Torsten Duwe 4bee9a
 	auth_param->auth_len = areq->assoclen + cipher_param->cipher_length;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	ret = qat_alg_send_sym_message(qat_req, ctx->inst);
Torsten Duwe 4bee9a
+	ret = qat_alg_send_sym_message(qat_req, ctx->inst, &areq->base);
Torsten Duwe 4bee9a
 	if (ret == -ENOSPC)
Torsten Duwe 4bee9a
 		qat_alg_free_bufl(ctx->inst, qat_req);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
@@ -1031,7 +1037,7 @@ static int qat_alg_aead_enc(struct aead_request *areq)
Torsten Duwe 4bee9a
 	auth_param->auth_off = 0;
Torsten Duwe 4bee9a
 	auth_param->auth_len = areq->assoclen + areq->cryptlen;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	ret = qat_alg_send_sym_message(qat_req, ctx->inst);
Torsten Duwe 4bee9a
+	ret = qat_alg_send_sym_message(qat_req, ctx->inst, &areq->base);
Torsten Duwe 4bee9a
 	if (ret == -ENOSPC)
Torsten Duwe 4bee9a
 		qat_alg_free_bufl(ctx->inst, qat_req);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
@@ -1212,7 +1218,7 @@ static int qat_alg_skcipher_encrypt(struct skcipher_request *req)
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 	qat_alg_set_req_iv(qat_req);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	ret = qat_alg_send_sym_message(qat_req, ctx->inst);
Torsten Duwe 4bee9a
+	ret = qat_alg_send_sym_message(qat_req, ctx->inst, &req->base);
Torsten Duwe 4bee9a
 	if (ret == -ENOSPC)
Torsten Duwe 4bee9a
 		qat_alg_free_bufl(ctx->inst, qat_req);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
@@ -1278,7 +1284,7 @@ static int qat_alg_skcipher_decrypt(struct skcipher_request *req)
Torsten Duwe 4bee9a
 	qat_alg_set_req_iv(qat_req);
Torsten Duwe 4bee9a
 	qat_alg_update_iv(qat_req);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	ret = qat_alg_send_sym_message(qat_req, ctx->inst);
Torsten Duwe 4bee9a
+	ret = qat_alg_send_sym_message(qat_req, ctx->inst, &req->base);
Torsten Duwe 4bee9a
 	if (ret == -ENOSPC)
Torsten Duwe 4bee9a
 		qat_alg_free_bufl(ctx->inst, qat_req);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/qat_algs_send.c b/drivers/crypto/qat/qat_common/qat_algs_send.c
Torsten Duwe 4bee9a
index 78f1bb8c26c08..ff5b4347f7831 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/qat_algs_send.c
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/qat_algs_send.c
Torsten Duwe 4bee9a
@@ -6,7 +6,7 @@
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 #define ADF_MAX_RETRIES		20
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-int qat_alg_send_message(struct qat_alg_req *req)
Torsten Duwe 4bee9a
+static int qat_alg_send_message_retry(struct qat_alg_req *req)
Torsten Duwe 4bee9a
 {
Torsten Duwe 4bee9a
 	int ret = 0, ctr = 0;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
@@ -19,3 +19,68 @@ int qat_alg_send_message(struct qat_alg_req *req)
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 	return -EINPROGRESS;
Torsten Duwe 4bee9a
 }
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+void qat_alg_send_backlog(struct qat_instance_backlog *backlog)
Torsten Duwe 4bee9a
+{
Torsten Duwe 4bee9a
+	struct qat_alg_req *req, *tmp;
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	spin_lock_bh(&backlog->lock);
Torsten Duwe 4bee9a
+	list_for_each_entry_safe(req, tmp, &backlog->list, list) {
Torsten Duwe 4bee9a
+		if (adf_send_message(req->tx_ring, req->fw_req)) {
Torsten Duwe 4bee9a
+			/* The HW ring is full. Do nothing.
Torsten Duwe 4bee9a
+			 * qat_alg_send_backlog() will be invoked again by
Torsten Duwe 4bee9a
+			 * another callback.
Torsten Duwe 4bee9a
+			 */
Torsten Duwe 4bee9a
+			break;
Torsten Duwe 4bee9a
+		}
Torsten Duwe 4bee9a
+		list_del(&req->list);
Torsten Duwe 4bee9a
+		req->base->complete(req->base, -EINPROGRESS);
Torsten Duwe 4bee9a
+	}
Torsten Duwe 4bee9a
+	spin_unlock_bh(&backlog->lock);
Torsten Duwe 4bee9a
+}
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+static void qat_alg_backlog_req(struct qat_alg_req *req,
Torsten Duwe 4bee9a
+				struct qat_instance_backlog *backlog)
Torsten Duwe 4bee9a
+{
Torsten Duwe 4bee9a
+	INIT_LIST_HEAD(&req->list);
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	spin_lock_bh(&backlog->lock);
Torsten Duwe 4bee9a
+	list_add_tail(&req->list, &backlog->list);
Torsten Duwe 4bee9a
+	spin_unlock_bh(&backlog->lock);
Torsten Duwe 4bee9a
+}
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+static int qat_alg_send_message_maybacklog(struct qat_alg_req *req)
Torsten Duwe 4bee9a
+{
Torsten Duwe 4bee9a
+	struct qat_instance_backlog *backlog = req->backlog;
Torsten Duwe 4bee9a
+	struct adf_etr_ring_data *tx_ring = req->tx_ring;
Torsten Duwe 4bee9a
+	u32 *fw_req = req->fw_req;
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	/* If any request is already backlogged, then add to backlog list */
Torsten Duwe 4bee9a
+	if (!list_empty(&backlog->list))
Torsten Duwe 4bee9a
+		goto enqueue;
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	/* If ring is nearly full, then add to backlog list */
Torsten Duwe 4bee9a
+	if (adf_ring_nearly_full(tx_ring))
Torsten Duwe 4bee9a
+		goto enqueue;
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	/* If adding request to HW ring fails, then add to backlog list */
Torsten Duwe 4bee9a
+	if (adf_send_message(tx_ring, fw_req))
Torsten Duwe 4bee9a
+		goto enqueue;
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	return -EINPROGRESS;
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+enqueue:
Torsten Duwe 4bee9a
+	qat_alg_backlog_req(req, backlog);
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	return -EBUSY;
Torsten Duwe 4bee9a
+}
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+int qat_alg_send_message(struct qat_alg_req *req)
Torsten Duwe 4bee9a
+{
Torsten Duwe 4bee9a
+	u32 flags = req->base->flags;
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	if (flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
Torsten Duwe 4bee9a
+		return qat_alg_send_message_maybacklog(req);
Torsten Duwe 4bee9a
+	else
Torsten Duwe 4bee9a
+		return qat_alg_send_message_retry(req);
Torsten Duwe 4bee9a
+}
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/qat_algs_send.h b/drivers/crypto/qat/qat_common/qat_algs_send.h
Torsten Duwe 4bee9a
index 3fa685d0c293a..5ce9f4f69d8ff 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/qat_algs_send.h
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/qat_algs_send.h
Torsten Duwe 4bee9a
@@ -6,5 +6,6 @@
Torsten Duwe 4bee9a
 #include "qat_crypto.h"
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 int qat_alg_send_message(struct qat_alg_req *req);
Torsten Duwe 4bee9a
+void qat_alg_send_backlog(struct qat_instance_backlog *backlog);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 #endif
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
Torsten Duwe 4bee9a
index 08b8d83e070a0..ff7249c093c9b 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
Torsten Duwe 4bee9a
@@ -136,17 +136,21 @@ struct qat_asym_request {
Torsten Duwe 4bee9a
 	} areq;
Torsten Duwe 4bee9a
 	int err;
Torsten Duwe 4bee9a
 	void (*cb)(struct icp_qat_fw_pke_resp *resp);
Torsten Duwe 4bee9a
+	struct qat_alg_req alg_req;
Torsten Duwe 4bee9a
 } __aligned(64);
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 static int qat_alg_send_asym_message(struct qat_asym_request *qat_req,
Torsten Duwe 4bee9a
-				     struct qat_crypto_instance *inst)
Torsten Duwe 4bee9a
+				     struct qat_crypto_instance *inst,
Torsten Duwe 4bee9a
+				     struct crypto_async_request *base)
Torsten Duwe 4bee9a
 {
Torsten Duwe 4bee9a
-	struct qat_alg_req req;
Torsten Duwe 4bee9a
+	struct qat_alg_req *alg_req = &qat_req->alg_req;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	req.fw_req = (u32 *)&qat_req->req;
Torsten Duwe 4bee9a
-	req.tx_ring = inst->pke_tx;
Torsten Duwe 4bee9a
+	alg_req->fw_req = (u32 *)&qat_req->req;
Torsten Duwe 4bee9a
+	alg_req->tx_ring = inst->pke_tx;
Torsten Duwe 4bee9a
+	alg_req->base = base;
Torsten Duwe 4bee9a
+	alg_req->backlog = &inst->backlog;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	return qat_alg_send_message(&req;;
Torsten Duwe 4bee9a
+	return qat_alg_send_message(alg_req);
Torsten Duwe 4bee9a
 }
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 static void qat_dh_cb(struct icp_qat_fw_pke_resp *resp)
Torsten Duwe 4bee9a
@@ -350,7 +354,7 @@ static int qat_dh_compute_value(struct kpp_request *req)
Torsten Duwe 4bee9a
 	msg->input_param_count = n_input_params;
Torsten Duwe 4bee9a
 	msg->output_param_count = 1;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	ret = qat_alg_send_asym_message(qat_req, ctx->inst);
Torsten Duwe 4bee9a
+	ret = qat_alg_send_asym_message(qat_req, inst, &req->base);
Torsten Duwe 4bee9a
 	if (ret == -ENOSPC)
Torsten Duwe 4bee9a
 		goto unmap_all;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
@@ -557,8 +561,11 @@ void qat_alg_asym_callback(void *_resp)
Torsten Duwe 4bee9a
 {
Torsten Duwe 4bee9a
 	struct icp_qat_fw_pke_resp *resp = _resp;
Torsten Duwe 4bee9a
 	struct qat_asym_request *areq = (void *)(__force long)resp->opaque;
Torsten Duwe 4bee9a
+	struct qat_instance_backlog *backlog = areq->alg_req.backlog;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 	areq->cb(resp);
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+	qat_alg_send_backlog(backlog);
Torsten Duwe 4bee9a
 }
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 #define PKE_RSA_EP_512 0x1c161b21
Torsten Duwe 4bee9a
@@ -748,7 +755,7 @@ static int qat_rsa_enc(struct akcipher_request *req)
Torsten Duwe 4bee9a
 	msg->input_param_count = 3;
Torsten Duwe 4bee9a
 	msg->output_param_count = 1;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	ret = qat_alg_send_asym_message(qat_req, ctx->inst);
Torsten Duwe 4bee9a
+	ret = qat_alg_send_asym_message(qat_req, inst, &req->base);
Torsten Duwe 4bee9a
 	if (ret == -ENOSPC)
Torsten Duwe 4bee9a
 		goto unmap_all;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
@@ -901,7 +908,7 @@ static int qat_rsa_dec(struct akcipher_request *req)
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 	msg->output_param_count = 1;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
-	ret = qat_alg_send_asym_message(qat_req, ctx->inst);
Torsten Duwe 4bee9a
+	ret = qat_alg_send_asym_message(qat_req, inst, &req->base);
Torsten Duwe 4bee9a
 	if (ret == -ENOSPC)
Torsten Duwe 4bee9a
 		goto unmap_all;
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/qat_crypto.c b/drivers/crypto/qat/qat_common/qat_crypto.c
Torsten Duwe 4bee9a
index 67c9588e89df9..80d905ed102e3 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/qat_crypto.c
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/qat_crypto.c
Torsten Duwe 4bee9a
@@ -353,6 +353,9 @@ static int qat_crypto_create_instances(struct adf_accel_dev *accel_dev)
Torsten Duwe 4bee9a
 				      &inst->pke_rx);
Torsten Duwe 4bee9a
 		if (ret)
Torsten Duwe 4bee9a
 			goto err;
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
+		INIT_LIST_HEAD(&inst->backlog.list);
Torsten Duwe 4bee9a
+		spin_lock_init(&inst->backlog.lock);
Torsten Duwe 4bee9a
 	}
Torsten Duwe 4bee9a
 	return 0;
Torsten Duwe 4bee9a
 err:
Torsten Duwe 4bee9a
diff --git a/drivers/crypto/qat/qat_common/qat_crypto.h b/drivers/crypto/qat/qat_common/qat_crypto.h
Torsten Duwe 4bee9a
index 0dcba6fc358c9..245b6d9a36507 100644
Torsten Duwe 4bee9a
--- a/drivers/crypto/qat/qat_common/qat_crypto.h
Torsten Duwe 4bee9a
+++ b/drivers/crypto/qat/qat_common/qat_crypto.h
Torsten Duwe 4bee9a
@@ -9,9 +9,17 @@
Torsten Duwe 4bee9a
 #include "adf_accel_devices.h"
Torsten Duwe 4bee9a
 #include "icp_qat_fw_la.h"
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
+struct qat_instance_backlog {
Torsten Duwe 4bee9a
+	struct list_head list;
Torsten Duwe 4bee9a
+	spinlock_t lock; /* protects backlog list */
Torsten Duwe 4bee9a
+};
Torsten Duwe 4bee9a
+
Torsten Duwe 4bee9a
 struct qat_alg_req {
Torsten Duwe 4bee9a
 	u32 *fw_req;
Torsten Duwe 4bee9a
 	struct adf_etr_ring_data *tx_ring;
Torsten Duwe 4bee9a
+	struct crypto_async_request *base;
Torsten Duwe 4bee9a
+	struct list_head list;
Torsten Duwe 4bee9a
+	struct qat_instance_backlog *backlog;
Torsten Duwe 4bee9a
 };
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 struct qat_crypto_instance {
Torsten Duwe 4bee9a
@@ -24,6 +32,7 @@ struct qat_crypto_instance {
Torsten Duwe 4bee9a
 	unsigned long state;
Torsten Duwe 4bee9a
 	int id;
Torsten Duwe 4bee9a
 	atomic_t refctr;
Torsten Duwe 4bee9a
+	struct qat_instance_backlog backlog;
Torsten Duwe 4bee9a
 };
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 #define QAT_MAX_BUFF_DESC	4
Torsten Duwe 4bee9a
@@ -82,6 +91,7 @@ struct qat_crypto_request {
Torsten Duwe 4bee9a
 		u8 iv[AES_BLOCK_SIZE];
Torsten Duwe 4bee9a
 	};
Torsten Duwe 4bee9a
 	bool encryption;
Torsten Duwe 4bee9a
+	struct qat_alg_req alg_req;
Torsten Duwe 4bee9a
 };
Torsten Duwe 4bee9a
 
Torsten Duwe 4bee9a
 static inline bool adf_hw_dev_has_crypto(struct adf_accel_dev *accel_dev)
Torsten Duwe 4bee9a
-- 
Torsten Duwe 4bee9a
2.35.3
Torsten Duwe 4bee9a