2020-05-08 06:59:43

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 00/13] crypto: hisilicon - misc cleanup and optimizations

This patchset includes some misc updates.
patch 1-3: modify the accelerator probe process.
patch 4: refactor module parameter pf_q_num.
patch 5-6: add state machine and FLR support.
patch 7: remove use_dma_api related useless codes.
patch 8-9: QM initialization process and memory management optimization.
patch 10-11: add device error report through abnormal irq.
patch 12-13: tiny change of zip driver.

Longfang Liu (3):
crypto: hisilicon/sec2 - modify the SEC probe process
crypto: hisilicon/hpre - modify the HPRE probe process
crypto: hisilicon/zip - modify the ZIP probe process

Shukun Tan (5):
crypto: hisilicon - refactor module parameter pf_q_num related code
crypto: hisilicon - add FLR support
crypto: hisilicon - remove use_dma_api related codes
crypto: hisilicon - remove codes of directly report device errors
through MSI
crypto: hisilicon - add device error report through abnormal irq

Weili Qian (2):
crypto: hisilicon - unify initial value assignment into QM
crypto: hisilicon - QM memory management optimization

Zhou Wang (3):
crypto: hisilicon/qm - add state machine for QM
crypto: hisilicon/zip - Use temporary sqe when doing work
crypto: hisilicon/zip - Make negative compression not an error

drivers/crypto/hisilicon/hpre/hpre_main.c | 107 ++-
drivers/crypto/hisilicon/qm.c | 1102 +++++++++++++++++++----------
drivers/crypto/hisilicon/qm.h | 75 +-
drivers/crypto/hisilicon/sec2/sec_main.c | 134 ++--
drivers/crypto/hisilicon/zip/zip_crypto.c | 13 +-
drivers/crypto/hisilicon/zip/zip_main.c | 128 ++--
6 files changed, 952 insertions(+), 607 deletions(-)

--
2.7.4


2020-05-08 06:59:43

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 01/13] crypto: hisilicon/sec2 - modify the SEC probe process

From: Longfang Liu <[email protected]>

Adjust the position of SMMU status check and
SEC queue initialization in SEC probe

Signed-off-by: Longfang Liu <[email protected]>
Signed-off-by: Zaibo Xu <[email protected]>
Signed-off-by: Shukun Tan <[email protected]>
Reviewed-by: Zhou Wang <[email protected]>
---
drivers/crypto/hisilicon/sec2/sec_main.c | 67 ++++++++++++++------------------
1 file changed, 30 insertions(+), 37 deletions(-)

diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 07a5f4e..ea029e3 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -765,6 +765,21 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->dev_name = sec_name;
qm->fun_type = (pdev->device == SEC_PF_PCI_DEVICE_ID) ?
QM_HW_PF : QM_HW_VF;
+ if (qm->fun_type == QM_HW_PF) {
+ qm->qp_base = SEC_PF_DEF_Q_BASE;
+ qm->qp_num = pf_q_num;
+ qm->debug.curr_qm_qp_num = pf_q_num;
+ qm->qm_list = &sec_devices;
+ } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
+ /*
+ * have no way to get qm configure in VM in v1 hardware,
+ * so currently force PF to uses SEC_PF_DEF_Q_NUM, and force
+ * to trigger only one VF in v1 hardware.
+ * v2 hardware has no such problem.
+ */
+ qm->qp_base = SEC_PF_DEF_Q_NUM;
+ qm->qp_num = SEC_QUEUE_NUM_V1 - SEC_PF_DEF_Q_NUM;
+ }
qm->use_dma_api = true;

return hisi_qm_init(qm);
@@ -775,8 +790,9 @@ static void sec_qm_uninit(struct hisi_qm *qm)
hisi_qm_uninit(qm);
}

-static int sec_probe_init(struct hisi_qm *qm, struct sec_dev *sec)
+static int sec_probe_init(struct sec_dev *sec)
{
+ struct hisi_qm *qm = &sec->qm;
int ret;

/*
@@ -793,40 +809,18 @@ static int sec_probe_init(struct hisi_qm *qm, struct sec_dev *sec)
return -ENOMEM;
}

- if (qm->fun_type == QM_HW_PF) {
- qm->qp_base = SEC_PF_DEF_Q_BASE;
- qm->qp_num = pf_q_num;
- qm->debug.curr_qm_qp_num = pf_q_num;
- qm->qm_list = &sec_devices;
-
+ if (qm->fun_type == QM_HW_PF)
ret = sec_pf_probe_init(sec);
- if (ret)
- goto err_probe_uninit;
- } else if (qm->fun_type == QM_HW_VF) {
- /*
- * have no way to get qm configure in VM in v1 hardware,
- * so currently force PF to uses SEC_PF_DEF_Q_NUM, and force
- * to trigger only one VF in v1 hardware.
- * v2 hardware has no such problem.
- */
- if (qm->ver == QM_HW_V1) {
- qm->qp_base = SEC_PF_DEF_Q_NUM;
- qm->qp_num = SEC_QUEUE_NUM_V1 - SEC_PF_DEF_Q_NUM;
- } else if (qm->ver == QM_HW_V2) {
- /* v2 starts to support get vft by mailbox */
- ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
- if (ret)
- goto err_probe_uninit;
- }
- } else {
- ret = -ENODEV;
- goto err_probe_uninit;
+ else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2)
+ /* v2 starts to support get vft by mailbox */
+ ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
+
+ if (ret) {
+ destroy_workqueue(qm->wq);
+ return ret;
}

return 0;
-err_probe_uninit:
- destroy_workqueue(qm->wq);
- return ret;
}

static void sec_probe_uninit(struct hisi_qm *qm)
@@ -865,18 +859,17 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id)

pci_set_drvdata(pdev, sec);

- sec->ctx_q_num = ctx_q_num;
- sec_iommu_used_check(sec);
-
qm = &sec->qm;
-
ret = sec_qm_init(qm, pdev);
if (ret) {
- pci_err(pdev, "Failed to pre init qm!\n");
+ pci_err(pdev, "Failed to init SEC QM (%d)!\n", ret);
return ret;
}

- ret = sec_probe_init(qm, sec);
+ sec->ctx_q_num = ctx_q_num;
+ sec_iommu_used_check(sec);
+
+ ret = sec_probe_init(sec);
if (ret) {
pci_err(pdev, "Failed to probe!\n");
goto err_qm_uninit;
--
2.7.4

2020-05-08 06:59:43

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 04/13] crypto: hisilicon - refactor module parameter pf_q_num related code

put q_num_set similar code into qm to reduce the redundancy.

Signed-off-by: Shukun Tan <[email protected]>
Reviewed-by: Zhou Wang <[email protected]>
---
drivers/crypto/hisilicon/hpre/hpre_main.c | 39 ++++++-------------------------
drivers/crypto/hisilicon/qm.h | 39 +++++++++++++++++++++++++++++++
drivers/crypto/hisilicon/sec2/sec_main.c | 35 ++-------------------------
drivers/crypto/hisilicon/zip/zip_main.c | 33 +-------------------------
4 files changed, 49 insertions(+), 97 deletions(-)

diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index f3859de..f1bb626 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -159,44 +159,19 @@ static struct debugfs_reg32 hpre_com_dfx_regs[] = {
{"INT_STATUS ", HPRE_INT_STATUS},
};

-static int hpre_pf_q_num_set(const char *val, const struct kernel_param *kp)
+static int pf_q_num_set(const char *val, const struct kernel_param *kp)
{
- struct pci_dev *pdev;
- u32 n, q_num;
- u8 rev_id;
- int ret;
-
- if (!val)
- return -EINVAL;
-
- pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, HPRE_PCI_DEVICE_ID, NULL);
- if (!pdev) {
- q_num = HPRE_QUEUE_NUM_V2;
- pr_info("No device found currently, suppose queue number is %d\n",
- q_num);
- } else {
- rev_id = pdev->revision;
- if (rev_id != QM_HW_V2)
- return -EINVAL;
-
- q_num = HPRE_QUEUE_NUM_V2;
- }
-
- ret = kstrtou32(val, 10, &n);
- if (ret != 0 || n == 0 || n > q_num)
- return -EINVAL;
-
- return param_set_int(val, kp);
+ return q_num_set(val, kp, HPRE_PCI_DEVICE_ID);
}

static const struct kernel_param_ops hpre_pf_q_num_ops = {
- .set = hpre_pf_q_num_set,
+ .set = pf_q_num_set,
.get = param_get_int,
};

-static u32 hpre_pf_q_num = HPRE_PF_DEF_Q_NUM;
-module_param_cb(hpre_pf_q_num, &hpre_pf_q_num_ops, &hpre_pf_q_num, 0444);
-MODULE_PARM_DESC(hpre_pf_q_num, "Number of queues in PF of CS(1-1024)");
+static u32 pf_q_num = HPRE_PF_DEF_Q_NUM;
+module_param_cb(pf_q_num, &hpre_pf_q_num_ops, &pf_q_num, 0444);
+MODULE_PARM_DESC(pf_q_num, "Number of queues in PF of CS(1-1024)");

static const struct kernel_param_ops vfs_num_ops = {
.set = vfs_num_set,
@@ -688,7 +663,7 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)

if (pdev->is_physfn) {
qm->qp_base = HPRE_PF_DEF_Q_BASE;
- qm->qp_num = hpre_pf_q_num;
+ qm->qp_num = pf_q_num;
}
qm->use_dma_api = true;

diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index 9d17167..d1be8cd 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -8,6 +8,8 @@
#include <linux/module.h>
#include <linux/pci.h>

+#define QM_QNUM_V1 4096
+#define QM_QNUM_V2 1024
#define QM_MAX_VFS_NUM_V2 63

/* qm user domain */
@@ -252,6 +254,43 @@ struct hisi_qp {
struct uacce_queue *uacce_q;
};

+static inline int q_num_set(const char *val, const struct kernel_param *kp,
+ unsigned int device)
+{
+ struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
+ device, NULL);
+ u32 n, q_num;
+ u8 rev_id;
+ int ret;
+
+ if (!val)
+ return -EINVAL;
+
+ if (!pdev) {
+ q_num = min_t(u32, QM_QNUM_V1, QM_QNUM_V2);
+ pr_info("No device found currently, suppose queue number is %d\n",
+ q_num);
+ } else {
+ rev_id = pdev->revision;
+ switch (rev_id) {
+ case QM_HW_V1:
+ q_num = QM_QNUM_V1;
+ break;
+ case QM_HW_V2:
+ q_num = QM_QNUM_V2;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ ret = kstrtou32(val, 10, &n);
+ if (ret || !n || n > q_num)
+ return -EINVAL;
+
+ return param_set_int(val, kp);
+}
+
static inline int vfs_num_set(const char *val, const struct kernel_param *kp)
{
u32 n;
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index ea029e3..5aba775 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -136,45 +136,14 @@ static struct debugfs_reg32 sec_dfx_regs[] = {

static int sec_pf_q_num_set(const char *val, const struct kernel_param *kp)
{
- struct pci_dev *pdev;
- u32 n, q_num;
- u8 rev_id;
- int ret;
-
- if (!val)
- return -EINVAL;
-
- pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
- SEC_PF_PCI_DEVICE_ID, NULL);
- if (!pdev) {
- q_num = min_t(u32, SEC_QUEUE_NUM_V1, SEC_QUEUE_NUM_V2);
- pr_info("No device, suppose queue number is %d!\n", q_num);
- } else {
- rev_id = pdev->revision;
-
- switch (rev_id) {
- case QM_HW_V1:
- q_num = SEC_QUEUE_NUM_V1;
- break;
- case QM_HW_V2:
- q_num = SEC_QUEUE_NUM_V2;
- break;
- default:
- return -EINVAL;
- }
- }
-
- ret = kstrtou32(val, 10, &n);
- if (ret || !n || n > q_num)
- return -EINVAL;
-
- return param_set_int(val, kp);
+ return q_num_set(val, kp, SEC_PF_PCI_DEVICE_ID);
}

static const struct kernel_param_ops sec_pf_q_num_ops = {
.set = sec_pf_q_num_set,
.get = param_get_int,
};
+
static u32 pf_q_num = SEC_PF_DEF_Q_NUM;
module_param_cb(pf_q_num, &sec_pf_q_num_ops, &pf_q_num, 0444);
MODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 0-4096, v2 0-1024)");
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 4672eaa..3c838e2 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -192,38 +192,7 @@ static struct debugfs_reg32 hzip_dfx_regs[] = {

static int pf_q_num_set(const char *val, const struct kernel_param *kp)
{
- struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
- PCI_DEVICE_ID_ZIP_PF, NULL);
- u32 n, q_num;
- u8 rev_id;
- int ret;
-
- if (!val)
- return -EINVAL;
-
- if (!pdev) {
- q_num = min_t(u32, HZIP_QUEUE_NUM_V1, HZIP_QUEUE_NUM_V2);
- pr_info("No device found currently, suppose queue number is %d\n",
- q_num);
- } else {
- rev_id = pdev->revision;
- switch (rev_id) {
- case QM_HW_V1:
- q_num = HZIP_QUEUE_NUM_V1;
- break;
- case QM_HW_V2:
- q_num = HZIP_QUEUE_NUM_V2;
- break;
- default:
- return -EINVAL;
- }
- }
-
- ret = kstrtou32(val, 10, &n);
- if (ret != 0 || n > q_num || n == 0)
- return -EINVAL;
-
- return param_set_int(val, kp);
+ return q_num_set(val, kp, PCI_DEVICE_ID_ZIP_PF);
}

static const struct kernel_param_ops pf_q_num_ops = {
--
2.7.4

2020-05-08 06:59:53

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 02/13] crypto: hisilicon/hpre - modify the HPRE probe process

From: Longfang Liu <[email protected]>

Misc fixes on coding style:
1.Merge pre-initialization and initialization of QM
2.Package the initialization of QM's PF and VF into a function

Signed-off-by: Longfang Liu <[email protected]>
Signed-off-by: Zaibo Xu <[email protected]>
Signed-off-by: Shukun Tan <[email protected]>
---
drivers/crypto/hisilicon/hpre/hpre_main.c | 42 ++++++++++++++++++-------------
1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index 0d63666..f3859de 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -666,7 +666,7 @@ static void hpre_debugfs_exit(struct hpre *hpre)
debugfs_remove_recursive(qm->debug.debug_root);
}

-static int hpre_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev)
+static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
enum qm_hw_ver rev_id;

@@ -685,13 +685,14 @@ static int hpre_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->dev_name = hpre_name;
qm->fun_type = (pdev->device == HPRE_PCI_DEVICE_ID) ?
QM_HW_PF : QM_HW_VF;
+
if (pdev->is_physfn) {
qm->qp_base = HPRE_PF_DEF_Q_BASE;
qm->qp_num = hpre_pf_q_num;
}
qm->use_dma_api = true;

- return 0;
+ return hisi_qm_init(qm);
}

static void hpre_log_hw_error(struct hisi_qm *qm, u32 err_sts)
@@ -766,6 +767,20 @@ static int hpre_pf_probe_init(struct hpre *hpre)
return 0;
}

+static int hpre_probe_init(struct hpre *hpre)
+{
+ struct hisi_qm *qm = &hpre->qm;
+ int ret = -ENODEV;
+
+ if (qm->fun_type == QM_HW_PF)
+ ret = hpre_pf_probe_init(hpre);
+ else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2)
+ /* v2 starts to support get vft by mailbox */
+ ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
+
+ return ret;
+}
+
static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hisi_qm *qm;
@@ -779,23 +794,16 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, hpre);

qm = &hpre->qm;
- ret = hpre_qm_pre_init(qm, pdev);
- if (ret)
- return ret;
-
- ret = hisi_qm_init(qm);
- if (ret)
+ ret = hpre_qm_init(qm, pdev);
+ if (ret) {
+ pci_err(pdev, "Failed to init HPRE QM (%d)!\n", ret);
return ret;
+ }

- if (pdev->is_physfn) {
- ret = hpre_pf_probe_init(hpre);
- if (ret)
- goto err_with_qm_init;
- } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2) {
- /* v2 starts to support get vft by mailbox */
- ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
- if (ret)
- goto err_with_qm_init;
+ ret = hpre_probe_init(hpre);
+ if (ret) {
+ pci_err(pdev, "Failed to probe (%d)!\n", ret);
+ goto err_with_qm_init;
}

ret = hisi_qm_start(qm);
--
2.7.4

2020-05-08 07:00:06

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 06/13] crypto: hisilicon - add FLR support

Add callback reset_prepare and reset_done in QM, The callback
reset_prepare will uninit device error configuration and stop
the QM, the callback reset_done will init the device error
configuration and restart the QM.

Uninit the error configuration will disable device block master OOO
when Multi-bit ECC error occurs to avoid the request of FLR will not
return.

Signed-off-by: Shukun Tan <[email protected]>
Reviewed-by: Zhou Wang <[email protected]>
---
drivers/crypto/hisilicon/hpre/hpre_main.c | 16 ++++
drivers/crypto/hisilicon/qm.c | 133 +++++++++++++++++++++++++++++-
drivers/crypto/hisilicon/qm.h | 2 +
drivers/crypto/hisilicon/sec2/sec_main.c | 2 +
drivers/crypto/hisilicon/zip/zip_main.c | 16 ++++
5 files changed, 165 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index f1bb626..1948fd3 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -310,12 +310,21 @@ static void hpre_cnt_regs_clear(struct hisi_qm *qm)

static void hpre_hw_error_disable(struct hisi_qm *qm)
{
+ u32 val;
+
/* disable hpre hw error interrupts */
writel(HPRE_CORE_INT_DISABLE, qm->io_base + HPRE_INT_MASK);
+
+ /* disable HPRE block master OOO when m-bit error occur */
+ val = readl(qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
+ val &= ~HPRE_AM_OOO_SHUTDOWN_ENABLE;
+ writel(val, qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
}

static void hpre_hw_error_enable(struct hisi_qm *qm)
{
+ u32 val;
+
/* clear HPRE hw error source if having */
writel(HPRE_CORE_INT_DISABLE, qm->io_base + HPRE_HAC_SOURCE_INT);

@@ -324,6 +333,11 @@ static void hpre_hw_error_enable(struct hisi_qm *qm)
writel(HPRE_HAC_RAS_CE_ENABLE, qm->io_base + HPRE_RAS_CE_ENB);
writel(HPRE_HAC_RAS_NFE_ENABLE, qm->io_base + HPRE_RAS_NFE_ENB);
writel(HPRE_HAC_RAS_FE_ENABLE, qm->io_base + HPRE_RAS_FE_ENB);
+
+ /* enable HPRE block master OOO when m-bit error occur */
+ val = readl(qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
+ val |= HPRE_AM_OOO_SHUTDOWN_ENABLE;
+ writel(val, qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
}

static inline struct hisi_qm *hpre_file_to_qm(struct hpre_debugfs_file *file)
@@ -851,6 +865,8 @@ static void hpre_remove(struct pci_dev *pdev)
static const struct pci_error_handlers hpre_err_handler = {
.error_detected = hisi_qm_dev_err_detected,
.slot_reset = hisi_qm_dev_slot_reset,
+ .reset_prepare = hisi_qm_reset_prepare,
+ .reset_done = hisi_qm_reset_done,
};

static struct pci_driver hpre_pci_driver = {
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index e42097e..c30df08 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -175,6 +175,7 @@
#define QMC_ALIGN(sz) ALIGN(sz, 32)

#define QM_DBG_TMP_BUF_LEN 22
+#define QM_PCI_COMMAND_INVALID ~0

#define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \
(((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \
@@ -2874,6 +2875,11 @@ pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_err_detected);

+static int qm_get_hw_error_status(struct hisi_qm *qm)
+{
+ return readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
+}
+
static int qm_check_req_recv(struct hisi_qm *qm)
{
struct pci_dev *pdev = qm->pdev;
@@ -3166,9 +3172,7 @@ static int qm_vf_reset_done(struct hisi_qm *qm)

static int qm_get_dev_err_status(struct hisi_qm *qm)
{
-
- return(qm->err_ini->get_dev_hw_err_status(qm) &
- qm->err_ini->err_info.ecc_2bits_mask);
+ return qm->err_ini->get_dev_hw_err_status(qm);
}

static int qm_dev_hw_init(struct hisi_qm *qm)
@@ -3190,7 +3194,8 @@ static void qm_restart_prepare(struct hisi_qm *qm)
qm->io_base + ACC_AM_CFG_PORT_WR_EN);

/* clear dev ecc 2bit error source if having */
- value = qm_get_dev_err_status(qm);
+ value = qm_get_dev_err_status(qm) &
+ qm->err_ini->err_info.ecc_2bits_mask;
if (value && qm->err_ini->clear_dev_hw_err_status)
qm->err_ini->clear_dev_hw_err_status(qm, value);

@@ -3336,6 +3341,126 @@ pci_ers_result_t hisi_qm_dev_slot_reset(struct pci_dev *pdev)
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_slot_reset);

+/* check the interrupt is ecc-mbit error or not */
+static int qm_check_dev_error(struct hisi_qm *qm)
+{
+ int ret;
+
+ if (qm->fun_type == QM_HW_VF)
+ return 0;
+
+ ret = qm_get_hw_error_status(qm) & QM_ECC_MBIT;
+ if (ret)
+ return ret;
+
+ return (qm_get_dev_err_status(qm) &
+ qm->err_ini->err_info.ecc_2bits_mask);
+}
+
+void hisi_qm_reset_prepare(struct pci_dev *pdev)
+{
+ struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev));
+ struct hisi_qm *qm = pci_get_drvdata(pdev);
+ u32 delay = 0;
+ int ret;
+
+ hisi_qm_dev_err_uninit(pf_qm);
+
+ /*
+ * Check whether there is an ECC mbit error, If it occurs, need to
+ * wait for soft reset to fix it.
+ */
+ while (qm_check_dev_error(pf_qm)) {
+ msleep(++delay);
+ if (delay > QM_RESET_WAIT_TIMEOUT)
+ return;
+ }
+
+ ret = qm_reset_prepare_ready(qm);
+ if (ret) {
+ pci_err(pdev, "FLR not ready!\n");
+ return;
+ }
+
+ if (qm->vfs_num) {
+ ret = qm_vf_reset_prepare(qm);
+ if (ret) {
+ pci_err(pdev, "Failed to prepare reset, ret = %d.\n",
+ ret);
+ return;
+ }
+ }
+
+ ret = hisi_qm_stop(qm);
+ if (ret) {
+ pci_err(pdev, "Failed to stop QM, ret = %d.\n", ret);
+ return;
+ }
+
+ pci_info(pdev, "FLR resetting...\n");
+}
+EXPORT_SYMBOL_GPL(hisi_qm_reset_prepare);
+
+static bool qm_flr_reset_complete(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = pci_physfn(pdev);
+ struct hisi_qm *qm = pci_get_drvdata(pf_pdev);
+ u32 id;
+
+ pci_read_config_dword(qm->pdev, PCI_COMMAND, &id);
+ if (id == QM_PCI_COMMAND_INVALID) {
+ pci_err(pdev, "Device can not be used!\n");
+ return false;
+ }
+
+ clear_bit(QM_DEV_RESET_FLAG, &qm->reset_flag);
+
+ return true;
+}
+
+void hisi_qm_reset_done(struct pci_dev *pdev)
+{
+ struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev));
+ struct hisi_qm *qm = pci_get_drvdata(pdev);
+ int ret;
+
+ hisi_qm_dev_err_init(pf_qm);
+
+ ret = qm_restart(qm);
+ if (ret) {
+ pci_err(pdev, "Failed to start QM, ret = %d.\n", ret);
+ goto flr_done;
+ }
+
+ if (qm->fun_type == QM_HW_PF) {
+ ret = qm_dev_hw_init(qm);
+ if (ret) {
+ pci_err(pdev, "Failed to init PF, ret = %d.\n", ret);
+ goto flr_done;
+ }
+
+ if (!qm->vfs_num)
+ goto flr_done;
+
+ ret = qm_vf_q_assign(qm, qm->vfs_num);
+ if (ret) {
+ pci_err(pdev, "Failed to assign VFs, ret = %d.\n", ret);
+ goto flr_done;
+ }
+
+ ret = qm_vf_reset_done(qm);
+ if (ret) {
+ pci_err(pdev, "Failed to start VFs, ret = %d.\n", ret);
+ goto flr_done;
+ }
+ }
+
+flr_done:
+ if (qm_flr_reset_complete(pdev))
+ pci_info(pdev, "FLR reset complete\n");
+}
+EXPORT_SYMBOL_GPL(hisi_qm_reset_done);
+
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Zhou Wang <[email protected]>");
MODULE_DESCRIPTION("HiSilicon Accelerator queue manager driver");
diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index eff156a..25934e3 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -371,6 +371,8 @@ void hisi_qm_dev_err_uninit(struct hisi_qm *qm);
pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
pci_channel_state_t state);
pci_ers_result_t hisi_qm_dev_slot_reset(struct pci_dev *pdev);
+void hisi_qm_reset_prepare(struct pci_dev *pdev);
+void hisi_qm_reset_done(struct pci_dev *pdev);

struct hisi_acc_sgl_pool;
struct hisi_acc_hw_sgl *hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 5aba775..437e8788 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -914,6 +914,8 @@ static void sec_remove(struct pci_dev *pdev)
static const struct pci_error_handlers sec_err_handler = {
.error_detected = hisi_qm_dev_err_detected,
.slot_reset = hisi_qm_dev_slot_reset,
+ .reset_prepare = hisi_qm_reset_prepare,
+ .reset_done = hisi_qm_reset_done,
};

static struct pci_driver sec_pci_driver = {
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 3c838e2..a7f0c6a 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -278,6 +278,8 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm)

static void hisi_zip_hw_error_enable(struct hisi_qm *qm)
{
+ u32 val;
+
if (qm->ver == QM_HW_V1) {
writel(HZIP_CORE_INT_MASK_ALL,
qm->io_base + HZIP_CORE_INT_MASK_REG);
@@ -296,12 +298,24 @@ static void hisi_zip_hw_error_enable(struct hisi_qm *qm)

/* enable ZIP hw error interrupts */
writel(0, qm->io_base + HZIP_CORE_INT_MASK_REG);
+
+ /* enable ZIP block master OOO when m-bit error occur */
+ val = readl(qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
+ val = val | HZIP_AXI_SHUTDOWN_ENABLE;
+ writel(val, qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
}

static void hisi_zip_hw_error_disable(struct hisi_qm *qm)
{
+ u32 val;
+
/* disable ZIP hw error interrupts */
writel(HZIP_CORE_INT_MASK_ALL, qm->io_base + HZIP_CORE_INT_MASK_REG);
+
+ /* disable ZIP block master OOO when m-bit error occur */
+ val = readl(qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
+ val = val & ~HZIP_AXI_SHUTDOWN_ENABLE;
+ writel(val, qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
}

static inline struct hisi_qm *file_to_qm(struct ctrl_debug_file *file)
@@ -802,6 +816,8 @@ static void hisi_zip_remove(struct pci_dev *pdev)
static const struct pci_error_handlers hisi_zip_err_handler = {
.error_detected = hisi_qm_dev_err_detected,
.slot_reset = hisi_qm_dev_slot_reset,
+ .reset_prepare = hisi_qm_reset_prepare,
+ .reset_done = hisi_qm_reset_done,
};

static struct pci_driver hisi_zip_pci_driver = {
--
2.7.4

2020-05-08 07:00:30

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 09/13] crypto: hisilicon - QM memory management optimization

From: Weili Qian <[email protected]>

Put all the code for the memory allocation into the QM initialization
process. Before, The qp memory was allocated when the qp was created,
and released when the qp was released, It is now changed to allocate
all the qp memory once.

Signed-off-by: Weili Qian <[email protected]>
Signed-off-by: Shukun Tan <[email protected]>
Reviewed-by: Zhou Wang <[email protected]>
---
drivers/crypto/hisilicon/qm.c | 265 ++++++++++++++++++++----------------------
drivers/crypto/hisilicon/qm.h | 4 +-
2 files changed, 128 insertions(+), 141 deletions(-)

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index e401638..e988124 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -6,6 +6,7 @@
#include <linux/bitmap.h>
#include <linux/debugfs.h>
#include <linux/dma-mapping.h>
+#include <linux/idr.h>
#include <linux/io.h>
#include <linux/irqreturn.h>
#include <linux/log2.h>
@@ -575,7 +576,7 @@ static struct hisi_qp *qm_to_hisi_qp(struct hisi_qm *qm, struct qm_eqe *eqe)
{
u16 cqn = le32_to_cpu(eqe->dw0) & QM_EQE_CQN_MASK;

- return qm->qp_array[cqn];
+ return &qm->qp_array[cqn];
}

static void qm_cq_head_update(struct hisi_qp *qp)
@@ -625,8 +626,7 @@ static void qm_work_process(struct work_struct *work)
while (QM_EQE_PHASE(eqe) == qm->status.eqc_phase) {
eqe_num++;
qp = qm_to_hisi_qp(qm, eqe);
- if (qp)
- qm_poll_qp(qp, qm);
+ qm_poll_qp(qp, qm);

if (qm->status.eq_head == QM_Q_DEPTH - 1) {
qm->status.eqc_phase = !qm->status.eqc_phase;
@@ -1247,50 +1247,36 @@ static struct hisi_qp *qm_create_qp_nolock(struct hisi_qm *qm, u8 alg_type)
{
struct device *dev = &qm->pdev->dev;
struct hisi_qp *qp;
- int qp_id, ret;
+ int qp_id;

if (!qm_qp_avail_state(qm, NULL, QP_INIT))
return ERR_PTR(-EPERM);

- qp = kzalloc(sizeof(*qp), GFP_KERNEL);
- if (!qp)
- return ERR_PTR(-ENOMEM);
-
- qp_id = find_first_zero_bit(qm->qp_bitmap, qm->qp_num);
- if (qp_id >= qm->qp_num) {
- dev_info(&qm->pdev->dev, "QM all queues are busy!\n");
- ret = -EBUSY;
- goto err_free_qp;
+ if (qm->qp_in_used == qm->qp_num) {
+ dev_info_ratelimited(dev, "All %u queues of QM are busy!\n",
+ qm->qp_num);
+ return ERR_PTR(-EBUSY);
}
- set_bit(qp_id, qm->qp_bitmap);
- qm->qp_array[qp_id] = qp;
- qm->qp_in_used++;
- qp->qm = qm;

- qp->qdma.size = qm->sqe_size * QM_Q_DEPTH +
- sizeof(struct qm_cqe) * QM_Q_DEPTH;
- qp->qdma.va = dma_alloc_coherent(dev, qp->qdma.size,
- &qp->qdma.dma, GFP_KERNEL);
- if (!qp->qdma.va) {
- ret = -ENOMEM;
- goto err_clear_bit;
+ qp_id = idr_alloc_cyclic(&qm->qp_idr, NULL, 0, qm->qp_num, GFP_ATOMIC);
+ if (qp_id < 0) {
+ dev_info_ratelimited(dev, "All %u queues of QM are busy!\n",
+ qm->qp_num);
+ return ERR_PTR(-EBUSY);
}

- dev_dbg(dev, "allocate qp dma buf(va=%pK, dma=%pad, size=%zx)\n",
- qp->qdma.va, &qp->qdma.dma, qp->qdma.size);
+ qp = &qm->qp_array[qp_id];
+
+ memset(qp->cqe, 0, sizeof(struct qm_cqe) * QM_Q_DEPTH);

+ qp->event_cb = NULL;
+ qp->req_cb = NULL;
qp->qp_id = qp_id;
qp->alg_type = alg_type;
+ qm->qp_in_used++;
atomic_set(&qp->qp_status.flags, QP_INIT);

return qp;
-
-err_clear_bit:
- qm->qp_array[qp_id] = NULL;
- clear_bit(qp_id, qm->qp_bitmap);
-err_free_qp:
- kfree(qp);
- return ERR_PTR(ret);
}

/**
@@ -1322,8 +1308,6 @@ EXPORT_SYMBOL_GPL(hisi_qm_create_qp);
void hisi_qm_release_qp(struct hisi_qp *qp)
{
struct hisi_qm *qm = qp->qm;
- struct qm_dma *qdma = &qp->qdma;
- struct device *dev = &qm->pdev->dev;

down_write(&qm->qps_lock);

@@ -1332,14 +1316,8 @@ void hisi_qm_release_qp(struct hisi_qp *qp)
return;
}

- if (qdma->va)
- dma_free_coherent(dev, qdma->size, qdma->va, qdma->dma);
-
- qm->qp_array[qp->qp_id] = NULL;
- clear_bit(qp->qp_id, qm->qp_bitmap);
qm->qp_in_used--;
-
- kfree(qp);
+ idr_remove(&qm->qp_idr, qp->qp_id);

up_write(&qm->qps_lock);
}
@@ -1416,41 +1394,13 @@ static int qm_start_qp_nolock(struct hisi_qp *qp, unsigned long arg)
{
struct hisi_qm *qm = qp->qm;
struct device *dev = &qm->pdev->dev;
- enum qm_hw_ver ver = qm->ver;
int qp_id = qp->qp_id;
int pasid = arg;
- size_t off = 0;
int ret;

if (!qm_qp_avail_state(qm, qp, QP_START))
return -EPERM;

-#define QP_INIT_BUF(qp, type, size) do { \
- (qp)->type = ((qp)->qdma.va + (off)); \
- (qp)->type##_dma = (qp)->qdma.dma + (off); \
- off += (size); \
-} while (0)
-
- if (!qp->qdma.dma) {
- dev_err(dev, "cannot get qm dma buffer\n");
- return -EINVAL;
- }
-
- /* sq need 128 bytes alignment */
- if (qp->qdma.dma & QM_SQE_DATA_ALIGN_MASK) {
- dev_err(dev, "qm sq is not aligned to 128 byte\n");
- return -EINVAL;
- }
-
- QP_INIT_BUF(qp, sqe, qm->sqe_size * QM_Q_DEPTH);
- QP_INIT_BUF(qp, cqe, sizeof(struct qm_cqe) * QM_Q_DEPTH);
-
- dev_dbg(dev, "init qp buffer(v%d):\n"
- " sqe (%pK, %lx)\n"
- " cqe (%pK, %lx)\n",
- ver, qp->sqe, (unsigned long)qp->sqe_dma,
- qp->cqe, (unsigned long)qp->cqe_dma);
-
ret = qm_qp_ctx_cfg(qp, qp_id, pasid);
if (ret)
return ret;
@@ -1697,16 +1647,7 @@ static void qm_qp_event_notifier(struct hisi_qp *qp)

static int hisi_qm_get_available_instances(struct uacce_device *uacce)
{
- int i, ret;
- struct hisi_qm *qm = uacce->priv;
-
- down_read(&qm->qps_lock);
- for (i = 0, ret = 0; i < qm->qp_num; i++)
- if (!qm->qp_array[i])
- ret++;
- up_read(&qm->qps_lock);
-
- return ret;
+ return hisi_qm_get_free_qp_num(uacce->priv);
}

static int hisi_qm_uacce_get_queue(struct uacce_device *uacce,
@@ -1916,6 +1857,99 @@ int hisi_qm_get_free_qp_num(struct hisi_qm *qm)
}
EXPORT_SYMBOL_GPL(hisi_qm_get_free_qp_num);

+static void hisi_qp_memory_uninit(struct hisi_qm *qm, int num)
+{
+ struct device *dev = &qm->pdev->dev;
+ struct qm_dma *qdma;
+ int i;
+
+ for (i = num - 1; i >= 0; i--) {
+ qdma = &qm->qp_array[i].qdma;
+ dma_free_coherent(dev, qdma->size, qdma->va, qdma->dma);
+ }
+
+ kfree(qm->qp_array);
+}
+
+static int hisi_qp_memory_init(struct hisi_qm *qm, size_t dma_size, int id)
+{
+ struct device *dev = &qm->pdev->dev;
+ size_t off = qm->sqe_size * QM_Q_DEPTH;
+ struct hisi_qp *qp;
+
+ qp = &qm->qp_array[id];
+ qp->qdma.va = dma_alloc_coherent(dev, dma_size, &qp->qdma.dma,
+ GFP_KERNEL);
+ if (!qp->qdma.va)
+ return -ENOMEM;
+
+ qp->sqe = qp->qdma.va;
+ qp->sqe_dma = qp->qdma.dma;
+ qp->cqe = qp->qdma.va + off;
+ qp->cqe_dma = qp->qdma.dma + off;
+ qp->qdma.size = dma_size;
+ qp->qm = qm;
+ qp->qp_id = id;
+
+ return 0;
+}
+
+static int hisi_qm_memory_init(struct hisi_qm *qm)
+{
+ struct device *dev = &qm->pdev->dev;
+ size_t qp_dma_size, off = 0;
+ int i, ret = 0;
+
+#define QM_INIT_BUF(qm, type, num) do { \
+ (qm)->type = ((qm)->qdma.va + (off)); \
+ (qm)->type##_dma = (qm)->qdma.dma + (off); \
+ off += QMC_ALIGN(sizeof(struct qm_##type) * (num)); \
+} while (0)
+
+ idr_init(&qm->qp_idr);
+ qm->qdma.size = QMC_ALIGN(sizeof(struct qm_eqe) * QM_Q_DEPTH) +
+ QMC_ALIGN(sizeof(struct qm_aeqe) * QM_Q_DEPTH) +
+ QMC_ALIGN(sizeof(struct qm_sqc) * qm->qp_num) +
+ QMC_ALIGN(sizeof(struct qm_cqc) * qm->qp_num);
+ qm->qdma.va = dma_alloc_coherent(dev, qm->qdma.size, &qm->qdma.dma,
+ GFP_ATOMIC);
+ dev_dbg(dev, "allocate qm dma buf size=%zx)\n", qm->qdma.size);
+ if (!qm->qdma.va)
+ return -ENOMEM;
+
+ QM_INIT_BUF(qm, eqe, QM_Q_DEPTH);
+ QM_INIT_BUF(qm, aeqe, QM_Q_DEPTH);
+ QM_INIT_BUF(qm, sqc, qm->qp_num);
+ QM_INIT_BUF(qm, cqc, qm->qp_num);
+
+ qm->qp_array = kcalloc(qm->qp_num, sizeof(struct hisi_qp), GFP_KERNEL);
+ if (!qm->qp_array) {
+ ret = -ENOMEM;
+ goto err_alloc_qp_array;
+ }
+
+ /* one more page for device or qp statuses */
+ qp_dma_size = qm->sqe_size * QM_Q_DEPTH +
+ sizeof(struct qm_cqe) * QM_Q_DEPTH;
+ qp_dma_size = PAGE_ALIGN(qp_dma_size);
+ for (i = 0; i < qm->qp_num; i++) {
+ ret = hisi_qp_memory_init(qm, qp_dma_size, i);
+ if (ret)
+ goto err_init_qp_mem;
+
+ dev_dbg(dev, "allocate qp dma buf size=%zx)\n", qp_dma_size);
+ }
+
+ return ret;
+
+err_init_qp_mem:
+ hisi_qp_memory_uninit(qm, i);
+err_alloc_qp_array:
+ dma_free_coherent(dev, qm->qdma.size, qm->qdma.va, qm->qdma.dma);
+
+ return ret;
+}
+
static void hisi_qm_pre_init(struct hisi_qm *qm)
{
struct pci_dev *pdev = qm->pdev;
@@ -2003,6 +2037,10 @@ int hisi_qm_init(struct hisi_qm *qm)
goto err_irq_unregister;
}

+ ret = hisi_qm_memory_init(qm);
+ if (ret)
+ goto err_irq_unregister;
+
INIT_WORK(&qm->work, qm_work_process);

atomic_set(&qm->status.flags, QM_INIT);
@@ -2048,6 +2086,9 @@ void hisi_qm_uninit(struct hisi_qm *qm)
uacce_remove(qm->uacce);
qm->uacce = NULL;

+ hisi_qp_memory_uninit(qm, qm->qp_num);
+ idr_destroy(&qm->qp_idr);
+
if (qm->qdma.va) {
hisi_qm_cache_wb(qm);
dma_free_coherent(dev, qm->qdma.size,
@@ -2176,22 +2217,10 @@ static int qm_eq_ctx_cfg(struct hisi_qm *qm)

static int __hisi_qm_start(struct hisi_qm *qm)
{
- struct pci_dev *pdev = qm->pdev;
- struct device *dev = &pdev->dev;
- size_t off = 0;
int ret;

-#define QM_INIT_BUF(qm, type, num) do { \
- (qm)->type = ((qm)->qdma.va + (off)); \
- (qm)->type##_dma = (qm)->qdma.dma + (off); \
- off += QMC_ALIGN(sizeof(struct qm_##type) * (num)); \
-} while (0)
-
WARN_ON(!qm->qdma.dma);

- if (qm->qp_num == 0)
- return -EINVAL;
-
if (qm->fun_type == QM_HW_PF) {
ret = qm_dev_mem_reset(qm);
if (ret)
@@ -2202,21 +2231,6 @@ static int __hisi_qm_start(struct hisi_qm *qm)
return ret;
}

- QM_INIT_BUF(qm, eqe, QM_Q_DEPTH);
- QM_INIT_BUF(qm, aeqe, QM_Q_DEPTH);
- QM_INIT_BUF(qm, sqc, qm->qp_num);
- QM_INIT_BUF(qm, cqc, qm->qp_num);
-
- dev_dbg(dev, "init qm buffer:\n"
- " eqe (%pK, %lx)\n"
- " aeqe (%pK, %lx)\n"
- " sqc (%pK, %lx)\n"
- " cqc (%pK, %lx)\n",
- qm->eqe, (unsigned long)qm->eqe_dma,
- qm->aeqe, (unsigned long)qm->aeqe_dma,
- qm->sqc, (unsigned long)qm->sqc_dma,
- qm->cqc, (unsigned long)qm->cqc_dma);
-
ret = qm_eq_ctx_cfg(qm);
if (ret)
return ret;
@@ -2261,33 +2275,6 @@ int hisi_qm_start(struct hisi_qm *qm)
goto err_unlock;
}

- if (!qm->qp_bitmap) {
- qm->qp_bitmap = devm_kcalloc(dev, BITS_TO_LONGS(qm->qp_num),
- sizeof(long), GFP_KERNEL);
- qm->qp_array = devm_kcalloc(dev, qm->qp_num,
- sizeof(struct hisi_qp *),
- GFP_KERNEL);
- if (!qm->qp_bitmap || !qm->qp_array) {
- ret = -ENOMEM;
- goto err_unlock;
- }
- }
-
- if (!qm->qdma.va) {
- qm->qdma.size = QMC_ALIGN(sizeof(struct qm_eqe) * QM_Q_DEPTH) +
- QMC_ALIGN(sizeof(struct qm_aeqe) * QM_Q_DEPTH) +
- QMC_ALIGN(sizeof(struct qm_sqc) * qm->qp_num) +
- QMC_ALIGN(sizeof(struct qm_cqc) * qm->qp_num);
- qm->qdma.va = dma_alloc_coherent(dev, qm->qdma.size,
- &qm->qdma.dma, GFP_KERNEL);
- dev_dbg(dev, "allocate qm dma buf(va=%pK, dma=%pad, size=%zx)\n",
- qm->qdma.va, &qm->qdma.dma, qm->qdma.size);
- if (!qm->qdma.va) {
- ret = -ENOMEM;
- goto err_unlock;
- }
- }
-
ret = __hisi_qm_start(qm);
if (!ret)
atomic_set(&qm->status.flags, QM_START);
@@ -2310,8 +2297,8 @@ static int qm_restart(struct hisi_qm *qm)

down_write(&qm->qps_lock);
for (i = 0; i < qm->qp_num; i++) {
- qp = qm->qp_array[i];
- if (qp && atomic_read(&qp->qp_status.flags) == QP_STOP &&
+ qp = &qm->qp_array[i];
+ if (atomic_read(&qp->qp_status.flags) == QP_STOP &&
qp->is_resetting == true) {
ret = qm_start_qp_nolock(qp, 0);
if (ret < 0) {
@@ -2336,7 +2323,7 @@ static int qm_stop_started_qp(struct hisi_qm *qm)
int i, ret;

for (i = 0; i < qm->qp_num; i++) {
- qp = qm->qp_array[i];
+ qp = &qm->qp_array[i];
if (qp && atomic_read(&qp->qp_status.flags) == QP_START) {
qp->is_resetting = true;
ret = qm_stop_qp_nolock(qp);
@@ -2360,8 +2347,8 @@ static void qm_clear_queues(struct hisi_qm *qm)
int i;

for (i = 0; i < qm->qp_num; i++) {
- qp = qm->qp_array[i];
- if (qp && qp->is_resetting)
+ qp = &qm->qp_array[i];
+ if (qp->is_resetting)
memset(qp->qdma.va, 0, qp->qdma.size);
}

diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index 743cb63..80b9746 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -214,8 +214,8 @@ struct hisi_qm {
unsigned long reset_flag;

struct rw_semaphore qps_lock;
- unsigned long *qp_bitmap;
- struct hisi_qp **qp_array;
+ struct idr qp_idr;
+ struct hisi_qp *qp_array;

struct mutex mailbox_lock;

--
2.7.4

2020-05-08 07:00:38

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 13/13] crypto: hisilicon/zip - Make negative compression not an error

From: Zhou Wang <[email protected]>

Users can decide whether to use negative compression result, so it
should not be reported as an error by driver.

Signed-off-by: Zhou Wang <[email protected]>
Signed-off-by: Shukun Tan <[email protected]>
---
drivers/crypto/hisilicon/zip/zip_crypto.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
index 5fb9d4b..0f158d4 100644
--- a/drivers/crypto/hisilicon/zip/zip_crypto.c
+++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
@@ -341,7 +341,7 @@ static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data)

status = sqe->dw3 & HZIP_BD_STATUS_M;

- if (status != 0 && status != HZIP_NC_ERR) {
+ if (status != 0) {
dev_err(dev, "%scompress fail in qp%u: %u, output: %u\n",
(qp->alg_type == 0) ? "" : "de", qp->qp_id, status,
sqe->produced);
--
2.7.4

2020-05-08 07:00:39

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 07/13] crypto: hisilicon - remove use_dma_api related codes

The codes related use_dma_api is useless which should be removed.

Signed-off-by: Shukun Tan <[email protected]>
Reviewed-by: Zhou Wang <[email protected]>
---
drivers/crypto/hisilicon/hpre/hpre_main.c | 1 -
drivers/crypto/hisilicon/qm.c | 34 ++++++++++++-------------------
drivers/crypto/hisilicon/qm.h | 1 -
drivers/crypto/hisilicon/sec2/sec_main.c | 1 -
drivers/crypto/hisilicon/zip/zip_main.c | 1 -
5 files changed, 13 insertions(+), 25 deletions(-)

diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index 1948fd3..7662a8f 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -679,7 +679,6 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->qp_base = HPRE_PF_DEF_Q_BASE;
qm->qp_num = pf_q_num;
}
- qm->use_dma_api = true;

return hisi_qm_init(qm);
}
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index c30df08..800beef 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -1267,20 +1267,18 @@ static struct hisi_qp *qm_create_qp_nolock(struct hisi_qm *qm, u8 alg_type)
qm->qp_in_used++;
qp->qm = qm;

- if (qm->use_dma_api) {
- qp->qdma.size = qm->sqe_size * QM_Q_DEPTH +
- sizeof(struct qm_cqe) * QM_Q_DEPTH;
- qp->qdma.va = dma_alloc_coherent(dev, qp->qdma.size,
- &qp->qdma.dma, GFP_KERNEL);
- if (!qp->qdma.va) {
- ret = -ENOMEM;
- goto err_clear_bit;
- }
-
- dev_dbg(dev, "allocate qp dma buf(va=%pK, dma=%pad, size=%zx)\n",
- qp->qdma.va, &qp->qdma.dma, qp->qdma.size);
+ qp->qdma.size = qm->sqe_size * QM_Q_DEPTH +
+ sizeof(struct qm_cqe) * QM_Q_DEPTH;
+ qp->qdma.va = dma_alloc_coherent(dev, qp->qdma.size,
+ &qp->qdma.dma, GFP_KERNEL);
+ if (!qp->qdma.va) {
+ ret = -ENOMEM;
+ goto err_clear_bit;
}

+ dev_dbg(dev, "allocate qp dma buf(va=%pK, dma=%pad, size=%zx)\n",
+ qp->qdma.va, &qp->qdma.dma, qp->qdma.size);
+
qp->qp_id = qp_id;
qp->alg_type = alg_type;
atomic_set(&qp->qp_status.flags, QP_INIT);
@@ -1334,7 +1332,7 @@ void hisi_qm_release_qp(struct hisi_qp *qp)
return;
}

- if (qm->use_dma_api && qdma->va)
+ if (qdma->va)
dma_free_coherent(dev, qdma->size, qdma->va, qdma->dma);

qm->qp_array[qp->qp_id] = NULL;
@@ -1992,8 +1990,6 @@ int hisi_qm_init(struct hisi_qm *qm)
INIT_WORK(&qm->work, qm_work_process);

atomic_set(&qm->status.flags, QM_INIT);
- dev_dbg(dev, "init qm %s with %s\n", pdev->is_physfn ? "pf" : "vf",
- qm->use_dma_api ? "dma api" : "iommu api");

return 0;

@@ -2034,7 +2030,7 @@ void hisi_qm_uninit(struct hisi_qm *qm)
uacce_remove(qm->uacce);
qm->uacce = NULL;

- if (qm->use_dma_api && qm->qdma.va) {
+ if (qm->qdma.va) {
hisi_qm_cache_wb(qm);
dma_free_coherent(dev, qm->qdma.size,
qm->qdma.va, qm->qdma.dma);
@@ -2259,11 +2255,7 @@ int hisi_qm_start(struct hisi_qm *qm)
}
}

- if (!qm->use_dma_api) {
- dev_dbg(&qm->pdev->dev, "qm delay start\n");
- up_write(&qm->qps_lock);
- return 0;
- } else if (!qm->qdma.va) {
+ if (!qm->qdma.va) {
qm->qdma.size = QMC_ALIGN(sizeof(struct qm_eqe) * QM_Q_DEPTH) +
QMC_ALIGN(sizeof(struct qm_aeqe) * QM_Q_DEPTH) +
QMC_ALIGN(sizeof(struct qm_sqc) * qm->qp_num) +
diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index 25934e3..743cb63 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -230,7 +230,6 @@ struct hisi_qm {
struct work_struct work;

const char *algs;
- bool use_dma_api;
bool use_sva;
resource_size_t phys_base;
resource_size_t phys_size;
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 437e8788..499c554 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -749,7 +749,6 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->qp_base = SEC_PF_DEF_Q_NUM;
qm->qp_num = SEC_QUEUE_NUM_V1 - SEC_PF_DEF_Q_NUM;
}
- qm->use_dma_api = true;

return hisi_qm_init(qm);
}
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index a7f0c6a..6a1a824 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -692,7 +692,6 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
if (rev_id == QM_HW_UNKNOWN)
return -EINVAL;

- qm->use_dma_api = true;
qm->pdev = pdev;
qm->ver = rev_id;

--
2.7.4

2020-05-08 07:00:39

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 10/13] crypto: hisilicon - remove codes of directly report device errors through MSI

The hardware device can be configured to report directly through MSI, but
this method will not go through RAS, configure all hardware errors that
should be processed by driver to NFE.

Signed-off-by: Shukun Tan <[email protected]>
---
drivers/crypto/hisilicon/hpre/hpre_main.c | 1 -
drivers/crypto/hisilicon/qm.c | 54 +++++++------------------------
drivers/crypto/hisilicon/qm.h | 4 +--
drivers/crypto/hisilicon/sec2/sec_main.c | 1 -
drivers/crypto/hisilicon/zip/zip_main.c | 1 -
5 files changed, 13 insertions(+), 48 deletions(-)

diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index 93df31a..5eedd3c 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -730,7 +730,6 @@ static const struct hisi_qm_err_ini hpre_err_ini = {
.ce = QM_BASE_CE,
.nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT,
.fe = 0,
- .msi = QM_DB_RANDOM_INVALID,
.ecc_2bits_mask = HPRE_CORE_ECC_2BIT_ERR |
HPRE_OOO_ECC_2BIT_ERR,
.msi_wr_port = HPRE_WR_MSI_PORT,
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index e988124..80935d6 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -313,8 +313,7 @@ struct hisi_qm_hw_ops {
u8 cmd, u16 index, u8 priority);
u32 (*get_irq_num)(struct hisi_qm *qm);
int (*debug_init)(struct hisi_qm *qm);
- void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe,
- u32 msi);
+ void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe);
void (*hw_error_uninit)(struct hisi_qm *qm);
pci_ers_result_t (*hw_error_handle)(struct hisi_qm *qm);
};
@@ -707,26 +706,6 @@ static irqreturn_t qm_aeq_irq(int irq, void *data)

static irqreturn_t qm_abnormal_irq(int irq, void *data)
{
- const struct hisi_qm_hw_error *err = qm_hw_error;
- struct hisi_qm *qm = data;
- struct device *dev = &qm->pdev->dev;
- u32 error_status, tmp;
-
- /* read err sts */
- tmp = readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
- error_status = qm->msi_mask & tmp;
-
- while (err->msg) {
- if (err->int_msk & error_status)
- dev_err(dev, "%s [error status=0x%x] found\n",
- err->msg, err->int_msk);
-
- err++;
- }
-
- /* clear err sts */
- writel(error_status, qm->io_base + QM_ABNORMAL_INT_SOURCE);
-
return IRQ_HANDLED;
}

@@ -1116,28 +1095,21 @@ static int qm_create_debugfs_file(struct hisi_qm *qm, enum qm_debug_file index)
return 0;
}

-static void qm_hw_error_init_v1(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe,
- u32 msi)
+static void qm_hw_error_init_v1(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe)
{
writel(QM_ABNORMAL_INT_MASK_VALUE, qm->io_base + QM_ABNORMAL_INT_MASK);
}

-static void qm_hw_error_init_v2(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe,
- u32 msi)
+static void qm_hw_error_init_v2(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe)
{
- u32 irq_enable = ce | nfe | fe | msi;
+ u32 irq_enable = ce | nfe | fe;
u32 irq_unmask = ~irq_enable;
- u32 error_status;

qm->error_mask = ce | nfe | fe;
- qm->msi_mask = msi;

/* clear QM hw residual error source */
- error_status = readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
- if (error_status) {
- error_status &= qm->error_mask;
- writel(error_status, qm->io_base + QM_ABNORMAL_INT_SOURCE);
- }
+ writel(QM_ABNORMAL_INT_SOURCE_CLR,
+ qm->io_base + QM_ABNORMAL_INT_SOURCE);

/* configure error type */
writel(ce, qm->io_base + QM_RAS_CE_ENABLE);
@@ -1145,9 +1117,6 @@ static void qm_hw_error_init_v2(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe,
writel(nfe, qm->io_base + QM_RAS_NFE_ENABLE);
writel(fe, qm->io_base + QM_RAS_FE_ENABLE);

- /* use RAS irq default, so only set QM_RAS_MSI_INT_SEL for MSI */
- writel(msi, qm->io_base + QM_RAS_MSI_INT_SEL);
-
irq_unmask &= readl(qm->io_base + QM_ABNORMAL_INT_MASK);
writel(irq_unmask, qm->io_base + QM_ABNORMAL_INT_MASK);
}
@@ -1207,9 +1176,11 @@ static pci_ers_result_t qm_hw_error_handle_v2(struct hisi_qm *qm)
qm->err_status.is_qm_ecc_mbit = true;

qm_log_hw_error(qm, error_status);
-
- /* clear err sts */
- writel(error_status, qm->io_base + QM_ABNORMAL_INT_SOURCE);
+ if (error_status == QM_DB_RANDOM_INVALID) {
+ writel(error_status, qm->io_base +
+ QM_ABNORMAL_INT_SOURCE);
+ return PCI_ERS_RESULT_RECOVERED;
+ }

return PCI_ERS_RESULT_NEED_RESET;
}
@@ -2476,8 +2447,7 @@ static void qm_hw_error_init(struct hisi_qm *qm)
return;
}

- qm->ops->hw_error_init(qm, err_info->ce, err_info->nfe,
- err_info->fe, err_info->msi);
+ qm->ops->hw_error_init(qm, err_info->ce, err_info->nfe, err_info->fe);
}

static void qm_hw_error_uninit(struct hisi_qm *qm)
diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index 80b9746..fc5e96a 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -74,7 +74,7 @@

#define QM_BASE_NFE (QM_AXI_RRESP | QM_AXI_BRESP | QM_ECC_MBIT | \
QM_ACC_GET_TASK_TIMEOUT | QM_DB_TIMEOUT | \
- QM_OF_FIFO_OF)
+ QM_OF_FIFO_OF | QM_DB_RANDOM_INVALID)
#define QM_BASE_CE QM_ECC_1BIT

#define QM_Q_DEPTH 1024
@@ -158,7 +158,6 @@ struct hisi_qm_err_info {
u32 ce;
u32 nfe;
u32 fe;
- u32 msi;
};

struct hisi_qm_err_status {
@@ -224,7 +223,6 @@ struct hisi_qm {
struct qm_debug debug;

u32 error_mask;
- u32 msi_mask;

struct workqueue_struct *wq;
struct work_struct work;
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 703b8b1..28c73bb 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -682,7 +682,6 @@ static const struct hisi_qm_err_ini sec_err_ini = {
.nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT |
QM_ACC_WB_NOT_READY_TIMEOUT,
.fe = 0,
- .msi = QM_DB_RANDOM_INVALID,
.ecc_2bits_mask = SEC_CORE_INT_STATUS_M_ECC,
.msi_wr_port = BIT(0),
.acpi_rst = "SRST",
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 1a5a6e3..226d398 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -643,7 +643,6 @@ static const struct hisi_qm_err_ini hisi_zip_err_ini = {
.nfe = QM_BASE_NFE |
QM_ACC_WB_NOT_READY_TIMEOUT,
.fe = 0,
- .msi = QM_DB_RANDOM_INVALID,
.ecc_2bits_mask = HZIP_CORE_INT_STATUS_M_ECC,
.msi_wr_port = HZIP_WR_PORT,
.acpi_rst = "ZRST",
--
2.7.4

2020-05-08 07:00:39

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 11/13] crypto: hisilicon - add device error report through abnormal irq

By configuring the device error in firmware to report through abnormal
interruption, process all NFE errors in irq handler.

Signed-off-by: Shukun Tan <[email protected]>
Reviewed-by: Zhou Wang <[email protected]>
---
drivers/crypto/hisilicon/qm.c | 340 +++++++++++++++++++++++-------------------
drivers/crypto/hisilicon/qm.h | 1 +
2 files changed, 188 insertions(+), 153 deletions(-)

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 80935d6..2117a54 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -219,6 +219,12 @@ enum vft_type {
CQC_VFT,
};

+enum acc_err_result {
+ ACC_ERR_NONE,
+ ACC_ERR_NEED_RESET,
+ ACC_ERR_RECOVERED,
+};
+
struct qm_cqe {
__le32 rsvd0;
__le16 cmd_id;
@@ -315,7 +321,7 @@ struct hisi_qm_hw_ops {
int (*debug_init)(struct hisi_qm *qm);
void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe);
void (*hw_error_uninit)(struct hisi_qm *qm);
- pci_ers_result_t (*hw_error_handle)(struct hisi_qm *qm);
+ enum acc_err_result (*hw_error_handle)(struct hisi_qm *qm);
};

static const char * const qm_debug_file_name[] = {
@@ -704,46 +710,6 @@ static irqreturn_t qm_aeq_irq(int irq, void *data)
return IRQ_HANDLED;
}

-static irqreturn_t qm_abnormal_irq(int irq, void *data)
-{
- return IRQ_HANDLED;
-}
-
-static int qm_irq_register(struct hisi_qm *qm)
-{
- struct pci_dev *pdev = qm->pdev;
- int ret;
-
- ret = request_irq(pci_irq_vector(pdev, QM_EQ_EVENT_IRQ_VECTOR),
- qm_irq, IRQF_SHARED, qm->dev_name, qm);
- if (ret)
- return ret;
-
- if (qm->ver == QM_HW_V2) {
- ret = request_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR),
- qm_aeq_irq, IRQF_SHARED, qm->dev_name, qm);
- if (ret)
- goto err_aeq_irq;
-
- if (qm->fun_type == QM_HW_PF) {
- ret = request_irq(pci_irq_vector(pdev,
- QM_ABNORMAL_EVENT_IRQ_VECTOR),
- qm_abnormal_irq, IRQF_SHARED,
- qm->dev_name, qm);
- if (ret)
- goto err_abonormal_irq;
- }
- }
-
- return 0;
-
-err_abonormal_irq:
- free_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR), qm);
-err_aeq_irq:
- free_irq(pci_irq_vector(pdev, QM_EQ_EVENT_IRQ_VECTOR), qm);
- return ret;
-}
-
static void qm_irq_unregister(struct hisi_qm *qm)
{
struct pci_dev *pdev = qm->pdev;
@@ -1163,7 +1129,7 @@ static void qm_log_hw_error(struct hisi_qm *qm, u32 error_status)
}
}

-static pci_ers_result_t qm_hw_error_handle_v2(struct hisi_qm *qm)
+static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm)
{
u32 error_status, tmp;

@@ -1179,13 +1145,13 @@ static pci_ers_result_t qm_hw_error_handle_v2(struct hisi_qm *qm)
if (error_status == QM_DB_RANDOM_INVALID) {
writel(error_status, qm->io_base +
QM_ABNORMAL_INT_SOURCE);
- return PCI_ERS_RESULT_RECOVERED;
+ return ACC_ERR_RECOVERED;
}

- return PCI_ERS_RESULT_NEED_RESET;
+ return ACC_ERR_NEED_RESET;
}

- return PCI_ERS_RESULT_RECOVERED;
+ return ACC_ERR_RECOVERED;
}

static const struct hisi_qm_hw_ops qm_hw_ops_v1 = {
@@ -1943,100 +1909,6 @@ static void hisi_qm_pre_init(struct hisi_qm *qm)
}

/**
- * hisi_qm_init() - Initialize configures about qm.
- * @qm: The qm needing init.
- *
- * This function init qm, then we can call hisi_qm_start to put qm into work.
- */
-int hisi_qm_init(struct hisi_qm *qm)
-{
- struct pci_dev *pdev = qm->pdev;
- struct device *dev = &pdev->dev;
- unsigned int num_vec;
- int ret;
-
- hisi_qm_pre_init(qm);
-
- ret = qm_alloc_uacce(qm);
- if (ret < 0)
- dev_warn(&pdev->dev, "fail to alloc uacce (%d)\n", ret);
-
- ret = pci_enable_device_mem(pdev);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to enable device mem!\n");
- goto err_remove_uacce;
- }
-
- ret = pci_request_mem_regions(pdev, qm->dev_name);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to request mem regions!\n");
- goto err_disable_pcidev;
- }
-
- qm->phys_base = pci_resource_start(pdev, PCI_BAR_2);
- qm->phys_size = pci_resource_len(qm->pdev, PCI_BAR_2);
- qm->io_base = ioremap(qm->phys_base, qm->phys_size);
- if (!qm->io_base) {
- ret = -EIO;
- goto err_release_mem_regions;
- }
-
- ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
- if (ret < 0)
- goto err_iounmap;
- pci_set_master(pdev);
-
- if (!qm->ops->get_irq_num) {
- ret = -EOPNOTSUPP;
- goto err_iounmap;
- }
- num_vec = qm->ops->get_irq_num(qm);
- ret = pci_alloc_irq_vectors(pdev, num_vec, num_vec, PCI_IRQ_MSI);
- if (ret < 0) {
- dev_err(dev, "Failed to enable MSI vectors!\n");
- goto err_iounmap;
- }
-
- ret = qm_irq_register(qm);
- if (ret)
- goto err_free_irq_vectors;
-
- if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2) {
- /* v2 starts to support get vft by mailbox */
- ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
- if (ret)
- goto err_irq_unregister;
- }
-
- ret = hisi_qm_memory_init(qm);
- if (ret)
- goto err_irq_unregister;
-
- INIT_WORK(&qm->work, qm_work_process);
-
- atomic_set(&qm->status.flags, QM_INIT);
-
- return 0;
-
-err_irq_unregister:
- qm_irq_unregister(qm);
-err_free_irq_vectors:
- pci_free_irq_vectors(pdev);
-err_iounmap:
- iounmap(qm->io_base);
-err_release_mem_regions:
- pci_release_mem_regions(pdev);
-err_disable_pcidev:
- pci_disable_device(pdev);
-err_remove_uacce:
- uacce_remove(qm->uacce);
- qm->uacce = NULL;
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(hisi_qm_init);
-
-/**
* hisi_qm_uninit() - Uninitialize qm.
* @qm: The qm needed uninit.
*
@@ -2460,11 +2332,11 @@ static void qm_hw_error_uninit(struct hisi_qm *qm)
qm->ops->hw_error_uninit(qm);
}

-static pci_ers_result_t qm_hw_error_handle(struct hisi_qm *qm)
+static enum acc_err_result qm_hw_error_handle(struct hisi_qm *qm)
{
if (!qm->ops->hw_error_handle) {
dev_err(&qm->pdev->dev, "QM doesn't support hw error report!\n");
- return PCI_ERS_RESULT_NONE;
+ return ACC_ERR_NONE;
}

return qm->ops->hw_error_handle(qm);
@@ -2777,13 +2649,13 @@ int hisi_qm_sriov_configure(struct pci_dev *pdev, int num_vfs)
}
EXPORT_SYMBOL_GPL(hisi_qm_sriov_configure);

-static pci_ers_result_t qm_dev_err_handle(struct hisi_qm *qm)
+static enum acc_err_result qm_dev_err_handle(struct hisi_qm *qm)
{
u32 err_sts;

if (!qm->err_ini->get_dev_hw_err_status) {
dev_err(&qm->pdev->dev, "Device doesn't support get hw error status!\n");
- return PCI_ERS_RESULT_NONE;
+ return ACC_ERR_NONE;
}

/* get device hardware error status */
@@ -2794,20 +2666,19 @@ static pci_ers_result_t qm_dev_err_handle(struct hisi_qm *qm)

if (!qm->err_ini->log_dev_hw_err) {
dev_err(&qm->pdev->dev, "Device doesn't support log hw error!\n");
- return PCI_ERS_RESULT_NEED_RESET;
+ return ACC_ERR_NEED_RESET;
}

qm->err_ini->log_dev_hw_err(qm, err_sts);
- return PCI_ERS_RESULT_NEED_RESET;
+ return ACC_ERR_NEED_RESET;
}

- return PCI_ERS_RESULT_RECOVERED;
+ return ACC_ERR_RECOVERED;
}

-static pci_ers_result_t qm_process_dev_error(struct pci_dev *pdev)
+static enum acc_err_result qm_process_dev_error(struct hisi_qm *qm)
{
- struct hisi_qm *qm = pci_get_drvdata(pdev);
- pci_ers_result_t qm_ret, dev_ret;
+ enum acc_err_result qm_ret, dev_ret;

/* log qm error */
qm_ret = qm_hw_error_handle(qm);
@@ -2815,9 +2686,9 @@ static pci_ers_result_t qm_process_dev_error(struct pci_dev *pdev)
/* log device error */
dev_ret = qm_dev_err_handle(qm);

- return (qm_ret == PCI_ERS_RESULT_NEED_RESET ||
- dev_ret == PCI_ERS_RESULT_NEED_RESET) ?
- PCI_ERS_RESULT_NEED_RESET : PCI_ERS_RESULT_RECOVERED;
+ return (qm_ret == ACC_ERR_NEED_RESET ||
+ dev_ret == ACC_ERR_NEED_RESET) ?
+ ACC_ERR_NEED_RESET : ACC_ERR_RECOVERED;
}

/**
@@ -2831,6 +2702,9 @@ static pci_ers_result_t qm_process_dev_error(struct pci_dev *pdev)
pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
+ struct hisi_qm *qm = pci_get_drvdata(pdev);
+ enum acc_err_result ret;
+
if (pdev->is_virtfn)
return PCI_ERS_RESULT_NONE;

@@ -2838,7 +2712,11 @@ pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT;

- return qm_process_dev_error(pdev);
+ ret = qm_process_dev_error(qm);
+ if (ret == ACC_ERR_NEED_RESET)
+ return PCI_ERS_RESULT_NEED_RESET;
+
+ return PCI_ERS_RESULT_RECOVERED;
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_err_detected);

@@ -3428,6 +3306,162 @@ void hisi_qm_reset_done(struct pci_dev *pdev)
}
EXPORT_SYMBOL_GPL(hisi_qm_reset_done);

+static irqreturn_t qm_abnormal_irq(int irq, void *data)
+{
+ struct hisi_qm *qm = (struct hisi_qm *)data;
+ enum acc_err_result ret;
+
+ ret = qm_process_dev_error(qm);
+ if (ret == ACC_ERR_NEED_RESET)
+ schedule_work(&qm->rst_work);
+
+ return IRQ_HANDLED;
+}
+
+static int qm_irq_register(struct hisi_qm *qm)
+{
+ struct pci_dev *pdev = qm->pdev;
+ int ret;
+
+ ret = request_irq(pci_irq_vector(pdev, QM_EQ_EVENT_IRQ_VECTOR),
+ qm_irq, IRQF_SHARED, qm->dev_name, qm);
+ if (ret)
+ return ret;
+
+ if (qm->ver == QM_HW_V2) {
+ ret = request_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR),
+ qm_aeq_irq, IRQF_SHARED, qm->dev_name, qm);
+ if (ret)
+ goto err_aeq_irq;
+
+ if (qm->fun_type == QM_HW_PF) {
+ ret = request_irq(pci_irq_vector(pdev,
+ QM_ABNORMAL_EVENT_IRQ_VECTOR),
+ qm_abnormal_irq, IRQF_SHARED,
+ qm->dev_name, qm);
+ if (ret)
+ goto err_abonormal_irq;
+ }
+ }
+
+ return 0;
+
+err_abonormal_irq:
+ free_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR), qm);
+err_aeq_irq:
+ free_irq(pci_irq_vector(pdev, QM_EQ_EVENT_IRQ_VECTOR), qm);
+ return ret;
+}
+
+static void hisi_qm_controller_reset(struct work_struct *rst_work)
+{
+ struct hisi_qm *qm = container_of(rst_work, struct hisi_qm, rst_work);
+ int ret;
+
+ /* reset pcie device controller */
+ ret = qm_controller_reset(qm);
+ if (ret)
+ dev_err(&qm->pdev->dev, "controller reset failed (%d)\n", ret);
+
+}
+
+/**
+ * hisi_qm_init() - Initialize configures about qm.
+ * @qm: The qm needing init.
+ *
+ * This function init qm, then we can call hisi_qm_start to put qm into work.
+ */
+int hisi_qm_init(struct hisi_qm *qm)
+{
+ struct pci_dev *pdev = qm->pdev;
+ struct device *dev = &pdev->dev;
+ unsigned int num_vec;
+ int ret;
+
+ hisi_qm_pre_init(qm);
+
+ ret = qm_alloc_uacce(qm);
+ if (ret < 0)
+ dev_warn(&pdev->dev, "fail to alloc uacce (%d)\n", ret);
+
+ ret = pci_enable_device_mem(pdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to enable device mem!\n");
+ goto err_remove_uacce;
+ }
+
+ ret = pci_request_mem_regions(pdev, qm->dev_name);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to request mem regions!\n");
+ goto err_disable_pcidev;
+ }
+
+ qm->phys_base = pci_resource_start(pdev, PCI_BAR_2);
+ qm->phys_size = pci_resource_len(qm->pdev, PCI_BAR_2);
+ qm->io_base = ioremap(qm->phys_base, qm->phys_size);
+ if (!qm->io_base) {
+ ret = -EIO;
+ goto err_release_mem_regions;
+ }
+
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+ if (ret < 0)
+ goto err_iounmap;
+ pci_set_master(pdev);
+
+ if (!qm->ops->get_irq_num) {
+ ret = -EOPNOTSUPP;
+ goto err_iounmap;
+ }
+ num_vec = qm->ops->get_irq_num(qm);
+ ret = pci_alloc_irq_vectors(pdev, num_vec, num_vec, PCI_IRQ_MSI);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable MSI vectors!\n");
+ goto err_iounmap;
+ }
+
+ ret = qm_irq_register(qm);
+ if (ret)
+ goto err_free_irq_vectors;
+
+ if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2) {
+ /* v2 starts to support get vft by mailbox */
+ ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
+ if (ret)
+ goto err_irq_unregister;
+ }
+
+ ret = hisi_qm_memory_init(qm);
+ if (ret)
+ goto err_irq_unregister;
+
+ INIT_WORK(&qm->work, qm_work_process);
+ if (qm->fun_type == QM_HW_PF)
+ INIT_WORK(&qm->rst_work, hisi_qm_controller_reset);
+
+ atomic_set(&qm->status.flags, QM_INIT);
+
+ return 0;
+
+err_irq_unregister:
+ qm_irq_unregister(qm);
+err_free_irq_vectors:
+ pci_free_irq_vectors(pdev);
+err_iounmap:
+ iounmap(qm->io_base);
+err_release_mem_regions:
+ pci_release_mem_regions(pdev);
+err_disable_pcidev:
+ pci_disable_device(pdev);
+err_remove_uacce:
+ uacce_remove(qm->uacce);
+ qm->uacce = NULL;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(hisi_qm_init);
+
+
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Zhou Wang <[email protected]>");
MODULE_DESCRIPTION("HiSilicon Accelerator queue manager driver");
diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index fc5e96a..a431ff2 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -226,6 +226,7 @@ struct hisi_qm {

struct workqueue_struct *wq;
struct work_struct work;
+ struct work_struct rst_work;

const char *algs;
bool use_sva;
--
2.7.4

2020-05-08 07:01:15

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 03/13] crypto: hisilicon/zip - modify the ZIP probe process

From: Longfang Liu <[email protected]>

Misc fixes on coding style:
1.Merge QM initialization code into a function
2.Merge QM's PF and VF initialization into a function

Signed-off-by: Longfang Liu <[email protected]>
Signed-off-by: Zaibo Xu <[email protected]>
Signed-off-by: Shukun Tan <[email protected]>
Reviewed-by: Zhou Wang <[email protected]>
---
drivers/crypto/hisilicon/zip/zip_main.c | 60 +++++++++++++++++++++++----------
1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 37db11f..4672eaa 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -701,23 +701,14 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
return 0;
}

-static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
- struct hisi_zip *hisi_zip;
enum qm_hw_ver rev_id;
- struct hisi_qm *qm;
- int ret;

rev_id = hisi_qm_get_hw_version(pdev);
if (rev_id == QM_HW_UNKNOWN)
return -EINVAL;

- hisi_zip = devm_kzalloc(&pdev->dev, sizeof(*hisi_zip), GFP_KERNEL);
- if (!hisi_zip)
- return -ENOMEM;
- pci_set_drvdata(pdev, hisi_zip);
-
- qm = &hisi_zip->qm;
qm->use_dma_api = true;
qm->pdev = pdev;
qm->ver = rev_id;
@@ -725,13 +716,16 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
qm->algs = "zlib\ngzip";
qm->sqe_size = HZIP_SQE_SIZE;
qm->dev_name = hisi_zip_name;
- qm->fun_type = (pdev->device == PCI_DEVICE_ID_ZIP_PF) ? QM_HW_PF :
- QM_HW_VF;
- ret = hisi_qm_init(qm);
- if (ret) {
- dev_err(&pdev->dev, "Failed to init qm!\n");
- return ret;
- }
+ qm->fun_type = (pdev->device == PCI_DEVICE_ID_ZIP_PF) ?
+ QM_HW_PF : QM_HW_VF;
+
+ return hisi_qm_init(qm);
+}
+
+static int hisi_zip_probe_init(struct hisi_zip *hisi_zip)
+{
+ struct hisi_qm *qm = &hisi_zip->qm;
+ int ret;

if (qm->fun_type == QM_HW_PF) {
ret = hisi_zip_pf_probe_init(hisi_zip);
@@ -754,7 +748,36 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
qm->qp_num = HZIP_QUEUE_NUM_V1 - HZIP_PF_DEF_Q_NUM;
} else if (qm->ver == QM_HW_V2)
/* v2 starts to support get vft by mailbox */
- hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
+ return hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
+ }
+
+ return 0;
+}
+
+static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct hisi_zip *hisi_zip;
+ struct hisi_qm *qm;
+ int ret;
+
+ hisi_zip = devm_kzalloc(&pdev->dev, sizeof(*hisi_zip), GFP_KERNEL);
+ if (!hisi_zip)
+ return -ENOMEM;
+
+ pci_set_drvdata(pdev, hisi_zip);
+
+ qm = &hisi_zip->qm;
+
+ ret = hisi_zip_qm_init(qm, pdev);
+ if (ret) {
+ pci_err(pdev, "Failed to init ZIP QM (%d)!\n", ret);
+ return ret;
+ }
+
+ ret = hisi_zip_probe_init(hisi_zip);
+ if (ret) {
+ pci_err(pdev, "Failed to probe (%d)!\n", ret);
+ goto err_qm_uninit;
}

ret = hisi_qm_start(qm);
@@ -787,6 +810,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hisi_qm_stop(qm);
err_qm_uninit:
hisi_qm_uninit(qm);
+
return ret;
}

--
2.7.4

2020-05-08 07:01:20

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 05/13] crypto: hisilicon/qm - add state machine for QM

From: Zhou Wang <[email protected]>

Add specific states for qm and qp, every state change under critical region
to prevent from race condition. Meanwhile, qp state change will also depend
on qm state.

Due to the introduction of these states, it is necessary to pay attention
to the calls of public logic, such as concurrent scenarios resetting and
releasing queue will call hisi_qm_stop, which needs to add additional
status to distinguish and process.

Signed-off-by: Zhou Wang <[email protected]>
Signed-off-by: Shukun Tan <[email protected]>
---
drivers/crypto/hisilicon/qm.c | 366 +++++++++++++++++++++++++++++++++---------
drivers/crypto/hisilicon/qm.h | 24 ++-
2 files changed, 307 insertions(+), 83 deletions(-)

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 69d02cb..e42097e 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -352,6 +352,93 @@ static const char * const qm_fifo_overflow[] = {
"cq", "eq", "aeq",
};

+static const char * const qm_s[] = {
+ "init", "start", "close", "stop",
+};
+
+static const char * const qp_s[] = {
+ "none", "init", "start", "stop", "close",
+};
+
+static bool qm_avail_state(struct hisi_qm *qm, enum qm_state new)
+{
+ enum qm_state curr = atomic_read(&qm->status.flags);
+ bool avail = false;
+
+ switch (curr) {
+ case QM_INIT:
+ if (new == QM_START || new == QM_CLOSE)
+ avail = true;
+ break;
+ case QM_START:
+ if (new == QM_STOP)
+ avail = true;
+ break;
+ case QM_STOP:
+ if (new == QM_CLOSE || new == QM_START)
+ avail = true;
+ break;
+ default:
+ break;
+ }
+
+ dev_dbg(&qm->pdev->dev, "change qm state from %s to %s\n",
+ qm_s[curr], qm_s[new]);
+
+ if (!avail)
+ dev_warn(&qm->pdev->dev, "Can not change qm state from %s to %s\n",
+ qm_s[curr], qm_s[new]);
+
+ return avail;
+}
+
+static bool qm_qp_avail_state(struct hisi_qm *qm, struct hisi_qp *qp,
+ enum qp_state new)
+{
+ enum qm_state qm_curr = atomic_read(&qm->status.flags);
+ enum qp_state qp_curr = 0;
+ bool avail = false;
+
+ if (qp)
+ qp_curr = atomic_read(&qp->qp_status.flags);
+
+ switch (new) {
+ case QP_INIT:
+ if (qm_curr == QM_START || qm_curr == QM_INIT)
+ avail = true;
+ break;
+ case QP_START:
+ if ((qm_curr == QM_START && qp_curr == QP_INIT) ||
+ (qm_curr == QM_START && qp_curr == QP_STOP))
+ avail = true;
+ break;
+ case QP_STOP:
+ if ((qm_curr == QM_START && qp_curr == QP_START) ||
+ (qp_curr == QP_INIT))
+ avail = true;
+ break;
+ case QP_CLOSE:
+ if ((qm_curr == QM_START && qp_curr == QP_INIT) ||
+ (qm_curr == QM_START && qp_curr == QP_STOP) ||
+ (qm_curr == QM_STOP && qp_curr == QP_STOP) ||
+ (qm_curr == QM_STOP && qp_curr == QP_INIT))
+ avail = true;
+ break;
+ default:
+ break;
+ }
+
+ dev_dbg(&qm->pdev->dev, "change qp state from %s to %s in QM %s\n",
+ qp_s[qp_curr], qp_s[new], qm_s[qm_curr]);
+
+ if (!avail)
+ dev_warn(&qm->pdev->dev,
+ "Can not change qp state from %s to %s in QM %s\n",
+ qp_s[qp_curr], qp_s[new], qm_s[qm_curr]);
+
+ return avail;
+}
+
/* return 0 mailbox ready, -ETIMEDOUT hardware timeout */
static int qm_wait_mb_ready(struct hisi_qm *qm)
{
@@ -699,7 +786,7 @@ static void qm_init_qp_status(struct hisi_qp *qp)
qp_status->sq_tail = 0;
qp_status->cq_head = 0;
qp_status->cqc_phase = true;
- qp_status->flags = 0;
+ atomic_set(&qp_status->flags, 0);
}

static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base,
@@ -1155,29 +1242,21 @@ static void *qm_get_avail_sqe(struct hisi_qp *qp)
return qp->sqe + sq_tail * qp->qm->sqe_size;
}

-/**
- * hisi_qm_create_qp() - Create a queue pair from qm.
- * @qm: The qm we create a qp from.
- * @alg_type: Accelerator specific algorithm type in sqc.
- *
- * return created qp, -EBUSY if all qps in qm allocated, -ENOMEM if allocating
- * qp memory fails.
- */
-struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type)
+static struct hisi_qp *qm_create_qp_nolock(struct hisi_qm *qm, u8 alg_type)
{
struct device *dev = &qm->pdev->dev;
struct hisi_qp *qp;
int qp_id, ret;

+ if (!qm_qp_avail_state(qm, NULL, QP_INIT))
+ return ERR_PTR(-EPERM);
+
qp = kzalloc(sizeof(*qp), GFP_KERNEL);
if (!qp)
return ERR_PTR(-ENOMEM);

- write_lock(&qm->qps_lock);
-
qp_id = find_first_zero_bit(qm->qp_bitmap, qm->qp_num);
if (qp_id >= qm->qp_num) {
- write_unlock(&qm->qps_lock);
dev_info(&qm->pdev->dev, "QM all queues are busy!\n");
ret = -EBUSY;
goto err_free_qp;
@@ -1185,9 +1264,6 @@ struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type)
set_bit(qp_id, qm->qp_bitmap);
qm->qp_array[qp_id] = qp;
qm->qp_in_used++;
-
- write_unlock(&qm->qps_lock);
-
qp->qm = qm;

if (qm->use_dma_api) {
@@ -1206,18 +1282,36 @@ struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type)

qp->qp_id = qp_id;
qp->alg_type = alg_type;
+ atomic_set(&qp->qp_status.flags, QP_INIT);

return qp;

err_clear_bit:
- write_lock(&qm->qps_lock);
qm->qp_array[qp_id] = NULL;
clear_bit(qp_id, qm->qp_bitmap);
- write_unlock(&qm->qps_lock);
err_free_qp:
kfree(qp);
return ERR_PTR(ret);
}
+
+/**
+ * hisi_qm_create_qp() - Create a queue pair from qm.
+ * @qm: The qm we create a qp from.
+ * @alg_type: Accelerator specific algorithm type in sqc.
+ *
+ * return created qp, -EBUSY if all qps in qm allocated, -ENOMEM if allocating
+ * qp memory fails.
+ */
+struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type)
+{
+ struct hisi_qp *qp;
+
+ down_write(&qm->qps_lock);
+ qp = qm_create_qp_nolock(qm, alg_type);
+ up_write(&qm->qps_lock);
+
+ return qp;
+}
EXPORT_SYMBOL_GPL(hisi_qm_create_qp);

/**
@@ -1232,16 +1326,23 @@ void hisi_qm_release_qp(struct hisi_qp *qp)
struct qm_dma *qdma = &qp->qdma;
struct device *dev = &qm->pdev->dev;

+ down_write(&qm->qps_lock);
+
+ if (!qm_qp_avail_state(qm, qp, QP_CLOSE)) {
+ up_write(&qm->qps_lock);
+ return;
+ }
+
if (qm->use_dma_api && qdma->va)
dma_free_coherent(dev, qdma->size, qdma->va, qdma->dma);

- write_lock(&qm->qps_lock);
qm->qp_array[qp->qp_id] = NULL;
clear_bit(qp->qp_id, qm->qp_bitmap);
qm->qp_in_used--;
- write_unlock(&qm->qps_lock);

kfree(qp);
+
+ up_write(&qm->qps_lock);
}
EXPORT_SYMBOL_GPL(hisi_qm_release_qp);

@@ -1312,15 +1413,7 @@ static int qm_qp_ctx_cfg(struct hisi_qp *qp, int qp_id, int pasid)
return ret;
}

-/**
- * hisi_qm_start_qp() - Start a qp into running.
- * @qp: The qp we want to start to run.
- * @arg: Accelerator specific argument.
- *
- * After this function, qp can receive request from user. Return 0 if
- * successful, Return -EBUSY if failed.
- */
-int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg)
+static int qm_start_qp_nolock(struct hisi_qp *qp, unsigned long arg)
{
struct hisi_qm *qm = qp->qm;
struct device *dev = &qm->pdev->dev;
@@ -1330,6 +1423,9 @@ int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg)
size_t off = 0;
int ret;

+ if (!qm_qp_avail_state(qm, qp, QP_START))
+ return -EPERM;
+
#define QP_INIT_BUF(qp, type, size) do { \
(qp)->type = ((qp)->qdma.va + (off)); \
(qp)->type##_dma = (qp)->qdma.dma + (off); \
@@ -1360,10 +1456,31 @@ int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg)
if (ret)
return ret;

+ atomic_set(&qp->qp_status.flags, QP_START);
dev_dbg(dev, "queue %d started\n", qp_id);

return 0;
}
+
+/**
+ * hisi_qm_start_qp() - Start a qp into running.
+ * @qp: The qp we want to start to run.
+ * @arg: Accelerator specific argument.
+ *
+ * After this function, qp can receive request from user. Return 0 if
+ * successful, Return -EBUSY if failed.
+ */
+int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg)
+{
+ struct hisi_qm *qm = qp->qm;
+ int ret;
+
+ down_write(&qm->qps_lock);
+ ret = qm_start_qp_nolock(qp, arg);
+ up_write(&qm->qps_lock);
+
+ return ret;
+}
EXPORT_SYMBOL_GPL(hisi_qm_start_qp);

static void *qm_ctx_alloc(struct hisi_qm *qm, size_t ctx_size,
@@ -1467,20 +1584,26 @@ static int qm_drain_qp(struct hisi_qp *qp)
return ret;
}

-/**
- * hisi_qm_stop_qp() - Stop a qp in qm.
- * @qp: The qp we want to stop.
- *
- * This function is reverse of hisi_qm_start_qp. Return 0 if successful.
- */
-int hisi_qm_stop_qp(struct hisi_qp *qp)
+static int qm_stop_qp_nolock(struct hisi_qp *qp)
{
struct device *dev = &qp->qm->pdev->dev;
int ret;

- /* it is stopped */
- if (test_bit(QP_STOP, &qp->qp_status.flags))
+ /*
+ * It is allowed to stop and release qp when reset, If the qp is
+ * stopped when reset but still want to be released then, the
+ * is_resetting flag should be set negative so that this qp will not
+ * be restarted after reset.
+ */
+ if (atomic_read(&qp->qp_status.flags) == QP_STOP) {
+ qp->is_resetting = false;
return 0;
+ }
+
+ if (!qm_qp_avail_state(qp->qm, qp, QP_STOP))
+ return -EPERM;
+
+ atomic_set(&qp->qp_status.flags, QP_STOP);

ret = qm_drain_qp(qp);
if (ret)
@@ -1491,12 +1614,27 @@ int hisi_qm_stop_qp(struct hisi_qp *qp)
else
flush_work(&qp->qm->work);

- set_bit(QP_STOP, &qp->qp_status.flags);
-
dev_dbg(dev, "stop queue %u!", qp->qp_id);

return 0;
}
+
+/**
+ * hisi_qm_stop_qp() - Stop a qp in qm.
+ * @qp: The qp we want to stop.
+ *
+ * This function is reverse of hisi_qm_start_qp. Return 0 if successful.
+ */
+int hisi_qm_stop_qp(struct hisi_qp *qp)
+{
+ int ret;
+
+ down_write(&qp->qm->qps_lock);
+ ret = qm_stop_qp_nolock(qp);
+ up_write(&qp->qm->qps_lock);
+
+ return ret;
+}
EXPORT_SYMBOL_GPL(hisi_qm_stop_qp);

/**
@@ -1506,6 +1644,13 @@ EXPORT_SYMBOL_GPL(hisi_qm_stop_qp);
*
* This function will return -EBUSY if qp is currently full, and -EAGAIN
* if qp related qm is resetting.
+ *
+ * Note: This function may run with qm_irq_thread and ACC reset at same time.
+ * It has no race with qm_irq_thread. However, during hisi_qp_send, ACC
+ * reset may happen, we have no lock here considering performance. This
+ * causes current qm_db sending fail or can not receive sended sqe. QM
+ * sync/async receive function should handle the error sqe. ACC reset
+ * done function should clear used sqe to 0.
*/
int hisi_qp_send(struct hisi_qp *qp, const void *msg)
{
@@ -1514,7 +1659,9 @@ int hisi_qp_send(struct hisi_qp *qp, const void *msg)
u16 sq_tail_next = (sq_tail + 1) % QM_Q_DEPTH;
void *sqe = qm_get_avail_sqe(qp);

- if (unlikely(test_bit(QP_STOP, &qp->qp_status.flags))) {
+ if (unlikely(atomic_read(&qp->qp_status.flags) == QP_STOP ||
+ atomic_read(&qp->qm->status.flags) == QM_STOP ||
+ qp->is_resetting)) {
dev_info(&qp->qm->pdev->dev, "QP is stopped or resetting\n");
return -EAGAIN;
}
@@ -1554,11 +1701,11 @@ static int hisi_qm_get_available_instances(struct uacce_device *uacce)
int i, ret;
struct hisi_qm *qm = uacce->priv;

- read_lock(&qm->qps_lock);
+ down_read(&qm->qps_lock);
for (i = 0, ret = 0; i < qm->qp_num; i++)
if (!qm->qp_array[i])
ret++;
- read_unlock(&qm->qps_lock);
+ up_read(&qm->qps_lock);

return ret;
}
@@ -1658,9 +1805,9 @@ static int qm_set_sqctype(struct uacce_queue *q, u16 type)
struct hisi_qm *qm = q->uacce->priv;
struct hisi_qp *qp = q->priv;

- write_lock(&qm->qps_lock);
+ down_write(&qm->qps_lock);
qp->alg_type = type;
- write_unlock(&qm->qps_lock);
+ up_write(&qm->qps_lock);

return 0;
}
@@ -1762,9 +1909,9 @@ int hisi_qm_get_free_qp_num(struct hisi_qm *qm)
{
int ret;

- read_lock(&qm->qps_lock);
+ down_read(&qm->qps_lock);
ret = qm->qp_num - qm->qp_in_used;
- read_unlock(&qm->qps_lock);
+ up_read(&qm->qps_lock);

return ret;
}
@@ -1840,9 +1987,10 @@ int hisi_qm_init(struct hisi_qm *qm)

qm->qp_in_used = 0;
mutex_init(&qm->mailbox_lock);
- rwlock_init(&qm->qps_lock);
+ init_rwsem(&qm->qps_lock);
INIT_WORK(&qm->work, qm_work_process);

+ atomic_set(&qm->status.flags, QM_INIT);
dev_dbg(dev, "init qm %s with %s\n", pdev->is_physfn ? "pf" : "vf",
qm->use_dma_api ? "dma api" : "iommu api");

@@ -1875,6 +2023,13 @@ void hisi_qm_uninit(struct hisi_qm *qm)
struct pci_dev *pdev = qm->pdev;
struct device *dev = &pdev->dev;

+ down_write(&qm->qps_lock);
+
+ if (!qm_avail_state(qm, QM_CLOSE)) {
+ up_write(&qm->qps_lock);
+ return;
+ }
+
uacce_remove(qm->uacce);
qm->uacce = NULL;

@@ -1890,6 +2045,8 @@ void hisi_qm_uninit(struct hisi_qm *qm)
iounmap(qm->io_base);
pci_release_mem_regions(pdev);
pci_disable_device(pdev);
+
+ up_write(&qm->qps_lock);
}
EXPORT_SYMBOL_GPL(hisi_qm_uninit);

@@ -2072,12 +2229,21 @@ static int __hisi_qm_start(struct hisi_qm *qm)
int hisi_qm_start(struct hisi_qm *qm)
{
struct device *dev = &qm->pdev->dev;
+ int ret = 0;
+
+ down_write(&qm->qps_lock);
+
+ if (!qm_avail_state(qm, QM_START)) {
+ up_write(&qm->qps_lock);
+ return -EPERM;
+ }

dev_dbg(dev, "qm start with %d queue pairs\n", qm->qp_num);

if (!qm->qp_num) {
dev_err(dev, "qp_num should not be 0\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_unlock;
}

if (!qm->qp_bitmap) {
@@ -2086,12 +2252,15 @@ int hisi_qm_start(struct hisi_qm *qm)
qm->qp_array = devm_kcalloc(dev, qm->qp_num,
sizeof(struct hisi_qp *),
GFP_KERNEL);
- if (!qm->qp_bitmap || !qm->qp_array)
- return -ENOMEM;
+ if (!qm->qp_bitmap || !qm->qp_array) {
+ ret = -ENOMEM;
+ goto err_unlock;
+ }
}

if (!qm->use_dma_api) {
dev_dbg(&qm->pdev->dev, "qm delay start\n");
+ up_write(&qm->qps_lock);
return 0;
} else if (!qm->qdma.va) {
qm->qdma.size = QMC_ALIGN(sizeof(struct qm_eqe) * QM_Q_DEPTH) +
@@ -2102,11 +2271,19 @@ int hisi_qm_start(struct hisi_qm *qm)
&qm->qdma.dma, GFP_KERNEL);
dev_dbg(dev, "allocate qm dma buf(va=%pK, dma=%pad, size=%zx)\n",
qm->qdma.va, &qm->qdma.dma, qm->qdma.size);
- if (!qm->qdma.va)
- return -ENOMEM;
+ if (!qm->qdma.va) {
+ ret = -ENOMEM;
+ goto err_unlock;
+ }
}

- return __hisi_qm_start(qm);
+ ret = __hisi_qm_start(qm);
+ if (!ret)
+ atomic_set(&qm->status.flags, QM_START);
+
+err_unlock:
+ up_write(&qm->qps_lock);
+ return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_start);

@@ -2120,20 +2297,44 @@ static int qm_restart(struct hisi_qm *qm)
if (ret < 0)
return ret;

- write_lock(&qm->qps_lock);
+ down_write(&qm->qps_lock);
for (i = 0; i < qm->qp_num; i++) {
qp = qm->qp_array[i];
- if (qp) {
- ret = hisi_qm_start_qp(qp, 0);
+ if (qp && atomic_read(&qp->qp_status.flags) == QP_STOP &&
+ qp->is_resetting == true) {
+ ret = qm_start_qp_nolock(qp, 0);
if (ret < 0) {
dev_err(dev, "Failed to start qp%d!\n", i);

- write_unlock(&qm->qps_lock);
+ up_write(&qm->qps_lock);
+ return ret;
+ }
+ qp->is_resetting = false;
+ }
+ }
+ up_write(&qm->qps_lock);
+
+ return 0;
+}
+
+/* Stop started qps in reset flow */
+static int qm_stop_started_qp(struct hisi_qm *qm)
+{
+ struct device *dev = &qm->pdev->dev;
+ struct hisi_qp *qp;
+ int i, ret;
+
+ for (i = 0; i < qm->qp_num; i++) {
+ qp = qm->qp_array[i];
+ if (qp && atomic_read(&qp->qp_status.flags) == QP_START) {
+ qp->is_resetting = true;
+ ret = qm_stop_qp_nolock(qp);
+ if (ret < 0) {
+ dev_err(dev, "Failed to stop qp%d!\n", i);
return ret;
}
}
}
- write_unlock(&qm->qps_lock);

return 0;
}
@@ -2149,7 +2350,7 @@ static void qm_clear_queues(struct hisi_qm *qm)

for (i = 0; i < qm->qp_num; i++) {
qp = qm->qp_array[i];
- if (qp)
+ if (qp && qp->is_resetting)
memset(qp->qdma.va, 0, qp->qdma.size);
}

@@ -2166,41 +2367,43 @@ static void qm_clear_queues(struct hisi_qm *qm)
*/
int hisi_qm_stop(struct hisi_qm *qm)
{
- struct device *dev;
- struct hisi_qp *qp;
- int ret = 0, i;
+ struct device *dev = &qm->pdev->dev;
+ int ret = 0;

- if (!qm || !qm->pdev) {
- WARN_ON(1);
- return -EINVAL;
+ down_write(&qm->qps_lock);
+
+ if (!qm_avail_state(qm, QM_STOP)) {
+ ret = -EPERM;
+ goto err_unlock;
}

- dev = &qm->pdev->dev;
+ if (qm->status.stop_reason == QM_SOFT_RESET ||
+ qm->status.stop_reason == QM_FLR) {
+ ret = qm_stop_started_qp(qm);
+ if (ret < 0) {
+ dev_err(dev, "Failed to stop started qp!\n");
+ goto err_unlock;
+ }
+ }

/* Mask eq and aeq irq */
writel(0x1, qm->io_base + QM_VF_EQ_INT_MASK);
writel(0x1, qm->io_base + QM_VF_AEQ_INT_MASK);

- /* Stop all qps belong to this qm */
- for (i = 0; i < qm->qp_num; i++) {
- qp = qm->qp_array[i];
- if (qp) {
- ret = hisi_qm_stop_qp(qp);
- if (ret < 0) {
- dev_err(dev, "Failed to stop qp%d!\n", i);
- return -EBUSY;
- }
- }
- }
-
if (qm->fun_type == QM_HW_PF) {
ret = hisi_qm_set_vft(qm, 0, 0, 0);
- if (ret < 0)
+ if (ret < 0) {
dev_err(dev, "Failed to set vft!\n");
+ ret = -EBUSY;
+ goto err_unlock;
+ }
}

qm_clear_queues(qm);
+ atomic_set(&qm->status.flags, QM_STOP);

+err_unlock:
+ up_write(&qm->qps_lock);
return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_stop);
@@ -2772,6 +2975,7 @@ static int qm_set_msi(struct hisi_qm *qm, bool set)
static int qm_vf_reset_prepare(struct hisi_qm *qm)
{
struct hisi_qm_list *qm_list = qm->qm_list;
+ int stop_reason = qm->status.stop_reason;
struct pci_dev *pdev = qm->pdev;
struct pci_dev *virtfn;
struct hisi_qm *vf_qm;
@@ -2784,6 +2988,7 @@ static int qm_vf_reset_prepare(struct hisi_qm *qm)
continue;

if (pci_physfn(virtfn) == pdev) {
+ vf_qm->status.stop_reason = stop_reason;
ret = hisi_qm_stop(vf_qm);
if (ret)
goto stop_fail;
@@ -2830,6 +3035,7 @@ static int qm_controller_reset_prepare(struct hisi_qm *qm)
}
}

+ qm->status.stop_reason = QM_SOFT_RESET;
ret = hisi_qm_stop(qm);
if (ret) {
pci_err(pdev, "Fails to stop QM!\n");
diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index d1be8cd..eff156a 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -84,8 +84,24 @@
/* page number for queue file region */
#define QM_DOORBELL_PAGE_NR 1

+enum qm_stop_reason {
+ QM_NORMAL,
+ QM_SOFT_RESET,
+ QM_FLR,
+};
+
+enum qm_state {
+ QM_INIT = 0,
+ QM_START,
+ QM_CLOSE,
+ QM_STOP,
+};
+
enum qp_state {
+ QP_INIT = 1,
+ QP_START,
QP_STOP,
+ QP_CLOSE,
};

enum qm_hw_ver {
@@ -129,7 +145,8 @@ struct hisi_qm_status {
bool eqc_phase;
u32 aeq_head;
bool aeqc_phase;
- unsigned long flags;
+ atomic_t flags;
+ int stop_reason;
};

struct hisi_qm;
@@ -196,7 +213,7 @@ struct hisi_qm {
struct hisi_qm_err_status err_status;
unsigned long reset_flag;

- rwlock_t qps_lock;
+ struct rw_semaphore qps_lock;
unsigned long *qp_bitmap;
struct hisi_qp **qp_array;

@@ -225,7 +242,7 @@ struct hisi_qp_status {
u16 sq_tail;
u16 cq_head;
bool cqc_phase;
- unsigned long flags;
+ atomic_t flags;
};

struct hisi_qp_ops {
@@ -250,6 +267,7 @@ struct hisi_qp {
void (*event_cb)(struct hisi_qp *qp);

struct hisi_qm *qm;
+ bool is_resetting;
u16 pasid;
struct uacce_queue *uacce_q;
};
--
2.7.4

2020-05-08 07:01:22

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 12/13] crypto: hisilicon/zip - Use temporary sqe when doing work

From: Zhou Wang <[email protected]>

Currently zip sqe is stored in hisi_zip_qp_ctx, which will bring corruption
with multiple parallel users of the crypto tfm.

This patch removes the zip_sqe in hisi_zip_qp_ctx and uses a temporary sqe
instead.

Signed-off-by: Zhou Wang <[email protected]>
Signed-off-by: Jonathan Cameron <[email protected]>
Signed-off-by: Shukun Tan <[email protected]>
---
drivers/crypto/hisilicon/zip/zip_crypto.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
index 369ec32..5fb9d4b 100644
--- a/drivers/crypto/hisilicon/zip/zip_crypto.c
+++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
@@ -64,7 +64,6 @@ struct hisi_zip_req_q {

struct hisi_zip_qp_ctx {
struct hisi_qp *qp;
- struct hisi_zip_sqe zip_sqe;
struct hisi_zip_req_q req_q;
struct hisi_acc_sgl_pool *sgl_pool;
struct hisi_zip *zip_dev;
@@ -484,11 +483,11 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req,
static int hisi_zip_do_work(struct hisi_zip_req *req,
struct hisi_zip_qp_ctx *qp_ctx)
{
- struct hisi_zip_sqe *zip_sqe = &qp_ctx->zip_sqe;
struct acomp_req *a_req = req->req;
struct hisi_qp *qp = qp_ctx->qp;
struct device *dev = &qp->qm->pdev->dev;
struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;
+ struct hisi_zip_sqe zip_sqe;
dma_addr_t input;
dma_addr_t output;
int ret;
@@ -511,13 +510,13 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
}
req->dma_dst = output;

- hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, a_req->slen,
+ hisi_zip_fill_sqe(&zip_sqe, qp->req_type, input, output, a_req->slen,
a_req->dlen, req->sskip, req->dskip);
- hisi_zip_config_buf_type(zip_sqe, HZIP_SGL);
- hisi_zip_config_tag(zip_sqe, req->req_id);
+ hisi_zip_config_buf_type(&zip_sqe, HZIP_SGL);
+ hisi_zip_config_tag(&zip_sqe, req->req_id);

/* send command to start a task */
- ret = hisi_qp_send(qp, zip_sqe);
+ ret = hisi_qp_send(qp, &zip_sqe);
if (ret < 0)
goto err_unmap_output;

--
2.7.4

2020-05-08 07:01:22

by Shukun Tan

[permalink] [raw]
Subject: [PATCH 08/13] crypto: hisilicon - unify initial value assignment into QM

From: Weili Qian <[email protected]>

Some initial value assignment of struct hisi_qm could put into QM.

Signed-off-by: Weili Qian <[email protected]>
Signed-off-by: Shukun Tan <[email protected]>
Reviewed-by: Zhou Wang <[email protected]>
---
drivers/crypto/hisilicon/hpre/hpre_main.c | 22 +++++++-------
drivers/crypto/hisilicon/qm.c | 44 +++++++++++++++++++--------
drivers/crypto/hisilicon/sec2/sec_main.c | 50 +++++++++++++++----------------
drivers/crypto/hisilicon/zip/zip_main.c | 37 ++++++++++-------------
4 files changed, 81 insertions(+), 72 deletions(-)

diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index 7662a8f..93df31a 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -672,12 +672,13 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->ver = rev_id;
qm->sqe_size = HPRE_SQE_SIZE;
qm->dev_name = hpre_name;
- qm->fun_type = (pdev->device == HPRE_PCI_DEVICE_ID) ?
- QM_HW_PF : QM_HW_VF;

- if (pdev->is_physfn) {
+ qm->fun_type = (pdev->device == HPRE_PCI_DEVICE_ID) ?
+ QM_HW_PF : QM_HW_VF;
+ if (qm->fun_type == QM_HW_PF) {
qm->qp_base = HPRE_PF_DEF_Q_BASE;
qm->qp_num = pf_q_num;
+ qm->qm_list = &hpre_devices;
}

return hisi_qm_init(qm);
@@ -748,7 +749,6 @@ static int hpre_pf_probe_init(struct hpre *hpre)
if (ret)
return ret;

- qm->qm_list = &hpre_devices;
qm->err_ini = &hpre_err_ini;
hisi_qm_dev_err_init(qm);

@@ -758,15 +758,15 @@ static int hpre_pf_probe_init(struct hpre *hpre)
static int hpre_probe_init(struct hpre *hpre)
{
struct hisi_qm *qm = &hpre->qm;
- int ret = -ENODEV;
+ int ret;

- if (qm->fun_type == QM_HW_PF)
+ if (qm->fun_type == QM_HW_PF) {
ret = hpre_pf_probe_init(hpre);
- else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2)
- /* v2 starts to support get vft by mailbox */
- ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
+ if (ret)
+ return ret;
+ }

- return ret;
+ return 0;
}

static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -779,8 +779,6 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (!hpre)
return -ENOMEM;

- pci_set_drvdata(pdev, hpre);
-
qm = &hpre->qm;
ret = hpre_qm_init(qm, pdev);
if (ret) {
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 800beef..e401638 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -1916,6 +1916,27 @@ int hisi_qm_get_free_qp_num(struct hisi_qm *qm)
}
EXPORT_SYMBOL_GPL(hisi_qm_get_free_qp_num);

+static void hisi_qm_pre_init(struct hisi_qm *qm)
+{
+ struct pci_dev *pdev = qm->pdev;
+
+ switch (qm->ver) {
+ case QM_HW_V1:
+ qm->ops = &qm_hw_ops_v1;
+ break;
+ case QM_HW_V2:
+ qm->ops = &qm_hw_ops_v2;
+ break;
+ default:
+ return;
+ }
+
+ pci_set_drvdata(pdev, qm);
+ mutex_init(&qm->mailbox_lock);
+ init_rwsem(&qm->qps_lock);
+ qm->qp_in_used = 0;
+}
+
/**
* hisi_qm_init() - Initialize configures about qm.
* @qm: The qm needing init.
@@ -1929,16 +1950,7 @@ int hisi_qm_init(struct hisi_qm *qm)
unsigned int num_vec;
int ret;

- switch (qm->ver) {
- case QM_HW_V1:
- qm->ops = &qm_hw_ops_v1;
- break;
- case QM_HW_V2:
- qm->ops = &qm_hw_ops_v2;
- break;
- default:
- return -EINVAL;
- }
+ hisi_qm_pre_init(qm);

ret = qm_alloc_uacce(qm);
if (ret < 0)
@@ -1984,15 +1996,21 @@ int hisi_qm_init(struct hisi_qm *qm)
if (ret)
goto err_free_irq_vectors;

- qm->qp_in_used = 0;
- mutex_init(&qm->mailbox_lock);
- init_rwsem(&qm->qps_lock);
+ if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2) {
+ /* v2 starts to support get vft by mailbox */
+ ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
+ if (ret)
+ goto err_irq_unregister;
+ }
+
INIT_WORK(&qm->work, qm_work_process);

atomic_set(&qm->status.flags, QM_INIT);

return 0;

+err_irq_unregister:
+ qm_irq_unregister(qm);
err_free_irq_vectors:
pci_free_irq_vectors(pdev);
err_iounmap:
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 499c554..703b8b1 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -722,6 +722,7 @@ static int sec_pf_probe_init(struct sec_dev *sec)
static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
enum qm_hw_ver rev_id;
+ int ret;

rev_id = hisi_qm_get_hw_version(pdev);
if (rev_id == QM_HW_UNKNOWN)
@@ -729,9 +730,9 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)

qm->pdev = pdev;
qm->ver = rev_id;
-
qm->sqe_size = SEC_SQE_SIZE;
qm->dev_name = sec_name;
+
qm->fun_type = (pdev->device == SEC_PF_PCI_DEVICE_ID) ?
QM_HW_PF : QM_HW_VF;
if (qm->fun_type == QM_HW_PF) {
@@ -750,7 +751,25 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->qp_num = SEC_QUEUE_NUM_V1 - SEC_PF_DEF_Q_NUM;
}

- return hisi_qm_init(qm);
+ /*
+ * WQ_HIGHPRI: SEC request must be low delayed,
+ * so need a high priority workqueue.
+ * WQ_UNBOUND: SEC task is likely with long
+ * running CPU intensive workloads.
+ */
+ qm->wq = alloc_workqueue("%s", WQ_HIGHPRI | WQ_MEM_RECLAIM |
+ WQ_UNBOUND, num_online_cpus(),
+ pci_name(qm->pdev));
+ if (!qm->wq) {
+ pci_err(qm->pdev, "fail to alloc workqueue\n");
+ return -ENOMEM;
+ }
+
+ ret = hisi_qm_init(qm);
+ if (ret)
+ destroy_workqueue(qm->wq);
+
+ return ret;
}

static void sec_qm_uninit(struct hisi_qm *qm)
@@ -763,29 +782,10 @@ static int sec_probe_init(struct sec_dev *sec)
struct hisi_qm *qm = &sec->qm;
int ret;

- /*
- * WQ_HIGHPRI: SEC request must be low delayed,
- * so need a high priority workqueue.
- * WQ_UNBOUND: SEC task is likely with long
- * running CPU intensive workloads.
- */
- qm->wq = alloc_workqueue("%s", WQ_HIGHPRI |
- WQ_MEM_RECLAIM | WQ_UNBOUND, num_online_cpus(),
- pci_name(qm->pdev));
- if (!qm->wq) {
- pci_err(qm->pdev, "fail to alloc workqueue\n");
- return -ENOMEM;
- }
-
- if (qm->fun_type == QM_HW_PF)
+ if (qm->fun_type == QM_HW_PF) {
ret = sec_pf_probe_init(sec);
- else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2)
- /* v2 starts to support get vft by mailbox */
- ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
-
- if (ret) {
- destroy_workqueue(qm->wq);
- return ret;
+ if (ret)
+ return ret;
}

return 0;
@@ -825,8 +825,6 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (!sec)
return -ENOMEM;

- pci_set_drvdata(pdev, sec);
-
qm = &sec->qm;
ret = sec_qm_init(qm, pdev);
if (ret) {
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 6a1a824..1a5a6e3 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -694,12 +694,27 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)

qm->pdev = pdev;
qm->ver = rev_id;
-
qm->algs = "zlib\ngzip";
qm->sqe_size = HZIP_SQE_SIZE;
qm->dev_name = hisi_zip_name;
+
qm->fun_type = (pdev->device == PCI_DEVICE_ID_ZIP_PF) ?
QM_HW_PF : QM_HW_VF;
+ if (qm->fun_type == QM_HW_PF) {
+ qm->qp_base = HZIP_PF_DEF_Q_BASE;
+ qm->qp_num = pf_q_num;
+ qm->qm_list = &zip_devices;
+ } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
+ /*
+ * have no way to get qm configure in VM in v1 hardware,
+ * so currently force PF to uses HZIP_PF_DEF_Q_NUM, and force
+ * to trigger only one VF in v1 hardware.
+ *
+ * v2 hardware has no such problem.
+ */
+ qm->qp_base = HZIP_PF_DEF_Q_NUM;
+ qm->qp_num = HZIP_QUEUE_NUM_V1 - HZIP_PF_DEF_Q_NUM;
+ }

return hisi_qm_init(qm);
}
@@ -713,24 +728,6 @@ static int hisi_zip_probe_init(struct hisi_zip *hisi_zip)
ret = hisi_zip_pf_probe_init(hisi_zip);
if (ret)
return ret;
-
- qm->qp_base = HZIP_PF_DEF_Q_BASE;
- qm->qp_num = pf_q_num;
- qm->qm_list = &zip_devices;
- } else if (qm->fun_type == QM_HW_VF) {
- /*
- * have no way to get qm configure in VM in v1 hardware,
- * so currently force PF to uses HZIP_PF_DEF_Q_NUM, and force
- * to trigger only one VF in v1 hardware.
- *
- * v2 hardware has no such problem.
- */
- if (qm->ver == QM_HW_V1) {
- qm->qp_base = HZIP_PF_DEF_Q_NUM;
- qm->qp_num = HZIP_QUEUE_NUM_V1 - HZIP_PF_DEF_Q_NUM;
- } else if (qm->ver == QM_HW_V2)
- /* v2 starts to support get vft by mailbox */
- return hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
}

return 0;
@@ -746,8 +743,6 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (!hisi_zip)
return -ENOMEM;

- pci_set_drvdata(pdev, hisi_zip);
-
qm = &hisi_zip->qm;

ret = hisi_zip_qm_init(qm, pdev);
--
2.7.4

Subject: RE: [PATCH 13/13] crypto: hisilicon/zip - Make negative compression not an error

> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On Behalf Of Shukun Tan
> Sent: Friday, May 8, 2020 6:58 PM
> To: [email protected]; [email protected]
> Cc: [email protected]; Xu Zaibo <[email protected]>; Wangzhou (B) <[email protected]>
> Subject: [PATCH 13/13] crypto: hisilicon/zip - Make negative compression not an error

> From: Zhou Wang <[email protected]>

> Users can decide whether to use negative compression result, so it should not be reported as an error by driver.

> Signed-off-by: Zhou Wang <[email protected]>
> Signed-off-by: Shukun Tan <[email protected]>
> ---
> drivers/crypto/hisilicon/zip/zip_crypto.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)

> diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
> index 5fb9d4b..0f158d4 100644
> --- a/drivers/crypto/hisilicon/zip/zip_crypto.c
> +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
@@ -341,7 +341,7 @@ static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data)

> status = sqe->dw3 & HZIP_BD_STATUS_M;

> - if (status != 0 && status != HZIP_NC_ERR) {
> + if (status != 0) {

Hi Zhou, it seems your comment is saying we won't report errors for some cases. But the code seems to report more errors by removing the "&&" as the condition becomes weaker.
Anything have I lost?

> dev_err(dev, "%scompress fail in qp%u: %u, output: %u\n",
> (qp->alg_type == 0) ? "" : "de", qp->qp_id, status,
> sqe->produced);

Best Regards
Barry

Subject: RE: [PATCH 12/13] crypto: hisilicon/zip - Use temporary sqe when doing work

> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On Behalf Of Shukun Tan
> Sent: Friday, May 8, 2020 6:58 PM
> To: [email protected]; [email protected]
> Cc: [email protected]; Xu Zaibo <[email protected]>; Wangzhou (B) <[email protected]>
> Subject: [PATCH 12/13] crypto: hisilicon/zip - Use temporary sqe when doing work

> From: Zhou Wang <[email protected]>

> Currently zip sqe is stored in hisi_zip_qp_ctx, which will bring corruption with multiple parallel users of the crypto tfm.

> This patch removes the zip_sqe in hisi_zip_qp_ctx and uses a temporary sqe instead.

This looks like a quite correct fix as in the old code, the 2nd request will overwrite the zip_sqe of the 1st request if we send the 2nd request before the 1st one is completed.
So this will lead to the mistakes of both request1 and request2.

unfortunately, it seems the hang issue can still be reproduced with this patch applied if we ask multi-threads running on multi-cores to send requests in parallel. Maybe something more needs fix?

> Signed-off-by: Zhou Wang <[email protected]>
> Signed-off-by: Jonathan Cameron <[email protected]>
> Signed-off-by: Shukun Tan <[email protected]>
> ---
> drivers/crypto/hisilicon/zip/zip_crypto.c | 11 +++++------
> 1 file changed, 5 insertions(+), 6 deletions(-)

> diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
> index 369ec32..5fb9d4b 100644
> --- a/drivers/crypto/hisilicon/zip/zip_crypto.c
> +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
> @@ -64,7 +64,6 @@ struct hisi_zip_req_q {
>
> struct hisi_zip_qp_ctx {
> struct hisi_qp *qp;
> - struct hisi_zip_sqe zip_sqe;
> struct hisi_zip_req_q req_q;
> struct hisi_acc_sgl_pool *sgl_pool;
> struct hisi_zip *zip_dev;
> @@ -484,11 +483,11 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, static int hisi_zip_do_work(struct hisi_zip_req *req,
> struct hisi_zip_qp_ctx *qp_ctx)
> {
> - struct hisi_zip_sqe *zip_sqe = &qp_ctx->zip_sqe;
> struct acomp_req *a_req = req->req;
> struct hisi_qp *qp = qp_ctx->qp;
> struct device *dev = &qp->qm->pdev->dev;
> struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;
> + struct hisi_zip_sqe zip_sqe;
> dma_addr_t input;
> dma_addr_t output;
> int ret;
> @@ -511,13 +510,13 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
> }
> req->dma_dst = output;
>
> - hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, a_req->slen,
> + hisi_zip_fill_sqe(&zip_sqe, qp->req_type, input, output, a_req->slen,
> a_req->dlen, req->sskip, req->dskip);
> - hisi_zip_config_buf_type(zip_sqe, HZIP_SGL);
> - hisi_zip_config_tag(zip_sqe, req->req_id);
> + hisi_zip_config_buf_type(&zip_sqe, HZIP_SGL);
> + hisi_zip_config_tag(&zip_sqe, req->req_id);
>
> /* send command to start a task */
> - ret = hisi_qp_send(qp, zip_sqe);
> + ret = hisi_qp_send(qp, &zip_sqe);
> if (ret < 0)
> goto err_unmap_output;
>

Best Regards
Barry

2020-05-09 04:07:26

by Zhou Wang

[permalink] [raw]
Subject: Re: [PATCH 13/13] crypto: hisilicon/zip - Make negative compression not an error

On 2020/5/9 11:25, Song Bao Hua wrote:
>> -----Original Message-----
>> From: [email protected] [mailto:[email protected]] On Behalf Of Shukun Tan
>> Sent: Friday, May 8, 2020 6:58 PM
>> To: [email protected]; [email protected]
>> Cc: [email protected]; Xu Zaibo <[email protected]>; Wangzhou (B) <[email protected]>
>> Subject: [PATCH 13/13] crypto: hisilicon/zip - Make negative compression not an error
>
>> From: Zhou Wang <[email protected]>
>
>> Users can decide whether to use negative compression result, so it should not be reported as an error by driver.
>
>> Signed-off-by: Zhou Wang <[email protected]>
>> Signed-off-by: Shukun Tan <[email protected]>
>> ---
>> drivers/crypto/hisilicon/zip/zip_crypto.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>> diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
>> index 5fb9d4b..0f158d4 100644
>> --- a/drivers/crypto/hisilicon/zip/zip_crypto.c
>> +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
> @@ -341,7 +341,7 @@ static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data)
>
>> status = sqe->dw3 & HZIP_BD_STATUS_M;
>
>> - if (status != 0 && status != HZIP_NC_ERR) {
>> + if (status != 0) {
>
> Hi Zhou, it seems your comment is saying we won't report errors for some cases. But the code seems to report more errors by removing the "&&" as the condition becomes weaker.
> Anything have I lost?

My bad here. We already did this in driver. Please drop this patch.

Best,
Zhou

>
>> dev_err(dev, "%scompress fail in qp%u: %u, output: %u\n",
>> (qp->alg_type == 0) ? "" : "de", qp->qp_id, status,
>> sqe->produced);
>
> Best Regards
> Barry
>
> .
>

2020-05-09 06:50:29

by Zhou Wang

[permalink] [raw]
Subject: Re: [PATCH 12/13] crypto: hisilicon/zip - Use temporary sqe when doing work

On 2020/5/9 11:42, Song Bao Hua wrote:
>> -----Original Message-----
>> From: [email protected] [mailto:[email protected]] On Behalf Of Shukun Tan
>> Sent: Friday, May 8, 2020 6:58 PM
>> To: [email protected]; [email protected]
>> Cc: [email protected]; Xu Zaibo <[email protected]>; Wangzhou (B) <[email protected]>
>> Subject: [PATCH 12/13] crypto: hisilicon/zip - Use temporary sqe when doing work
>
>> From: Zhou Wang <[email protected]>
>
>> Currently zip sqe is stored in hisi_zip_qp_ctx, which will bring corruption with multiple parallel users of the crypto tfm.
>
>> This patch removes the zip_sqe in hisi_zip_qp_ctx and uses a temporary sqe instead.
>
> This looks like a quite correct fix as in the old code, the 2nd request will overwrite the zip_sqe of the 1st request if we send the 2nd request before the 1st one is completed.
> So this will lead to the mistakes of both request1 and request2.

Yes.

>
> unfortunately, it seems the hang issue can still be reproduced with this patch applied if we ask multi-threads running on multi-cores to send requests in parallel. Maybe something more needs fix?

Currently we do not support multi-threads using one crypto_acomp in this driver.
If you tested like this, it may go wrong, as we do not protect queue which is in zip ctx.

Best,
Zhou

>
>> Signed-off-by: Zhou Wang <[email protected]>
>> Signed-off-by: Jonathan Cameron <[email protected]>
>> Signed-off-by: Shukun Tan <[email protected]>
>> ---
>> drivers/crypto/hisilicon/zip/zip_crypto.c | 11 +++++------
>> 1 file changed, 5 insertions(+), 6 deletions(-)
>
>> diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
>> index 369ec32..5fb9d4b 100644
>> --- a/drivers/crypto/hisilicon/zip/zip_crypto.c
>> +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
>> @@ -64,7 +64,6 @@ struct hisi_zip_req_q {
>>
>> struct hisi_zip_qp_ctx {
>> struct hisi_qp *qp;
>> - struct hisi_zip_sqe zip_sqe;
>> struct hisi_zip_req_q req_q;
>> struct hisi_acc_sgl_pool *sgl_pool;
>> struct hisi_zip *zip_dev;
>> @@ -484,11 +483,11 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, static int hisi_zip_do_work(struct hisi_zip_req *req,
>> struct hisi_zip_qp_ctx *qp_ctx)
>> {
>> - struct hisi_zip_sqe *zip_sqe = &qp_ctx->zip_sqe;
>> struct acomp_req *a_req = req->req;
>> struct hisi_qp *qp = qp_ctx->qp;
>> struct device *dev = &qp->qm->pdev->dev;
>> struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;
>> + struct hisi_zip_sqe zip_sqe;
>> dma_addr_t input;
>> dma_addr_t output;
>> int ret;
>> @@ -511,13 +510,13 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
>> }
>> req->dma_dst = output;
>>
>> - hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, a_req->slen,
>> + hisi_zip_fill_sqe(&zip_sqe, qp->req_type, input, output, a_req->slen,
>> a_req->dlen, req->sskip, req->dskip);
>> - hisi_zip_config_buf_type(zip_sqe, HZIP_SGL);
>> - hisi_zip_config_tag(zip_sqe, req->req_id);
>> + hisi_zip_config_buf_type(&zip_sqe, HZIP_SGL);
>> + hisi_zip_config_tag(&zip_sqe, req->req_id);
>>
>> /* send command to start a task */
>> - ret = hisi_qp_send(qp, zip_sqe);
>> + ret = hisi_qp_send(qp, &zip_sqe);
>> if (ret < 0)
>> goto err_unmap_output;
>>
>
> Best Regards
> Barry
>
> .
>

Subject: RE: [PATCH 12/13] crypto: hisilicon/zip - Use temporary sqe when doing work

> >
> >> From: Zhou Wang <[email protected]>
> >
> >> Currently zip sqe is stored in hisi_zip_qp_ctx, which will bring corruption with multiple parallel users of the crypto tfm.
> >
> >> This patch removes the zip_sqe in hisi_zip_qp_ctx and uses a temporary sqe instead.
> >
> > This looks like a quite correct fix as in the old code, the 2nd request will overwrite the zip_sqe of the 1st request if we send the 2nd request before the 1st one is completed.
> > So this will lead to the mistakes of both request1 and request2.

> Yes.

> >
> > unfortunately, it seems the hang issue can still be reproduced with this patch applied if we ask multi-threads running on multi-cores to send requests in parallel. Maybe something more needs fix?

> Currently we do not support multi-threads using one crypto_acomp in this driver.
> If you tested like this, it may go wrong, as we do not protect queue which is in zip ctx.

Zhou, Thanks for clarification. I'm ok with this patch as it is definitely going to the right direction and removing some race conditions.
Maybe we need a follow-up patch to address the parallel problem later.

> Best,
> Zhou

Barry

> >
> >> Signed-off-by: Zhou Wang <[email protected]>
> >> Signed-off-by: Jonathan Cameron <[email protected]>
> >> Signed-off-by: Shukun Tan <[email protected]>
> >> ---
> >> drivers/crypto/hisilicon/zip/zip_crypto.c | 11 +++++------
> >> 1 file changed, 5 insertions(+), 6 deletions(-)
> >
> >> diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c
> >> b/drivers/crypto/hisilicon/zip/zip_crypto.c
> >> index 369ec32..5fb9d4b 100644
> >> --- a/drivers/crypto/hisilicon/zip/zip_crypto.c
> >> +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
> >> @@ -64,7 +64,6 @@ struct hisi_zip_req_q {
> >>
> >> struct hisi_zip_qp_ctx {
> >> struct hisi_qp *qp;
> >> - struct hisi_zip_sqe zip_sqe;
> >> struct hisi_zip_req_q req_q;
> >> struct hisi_acc_sgl_pool *sgl_pool;
> >> struct hisi_zip *zip_dev;
> >> @@ -484,11 +483,11 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, static int hisi_zip_do_work(struct hisi_zip_req *req,
> >> struct hisi_zip_qp_ctx *qp_ctx) {
> >> - struct hisi_zip_sqe *zip_sqe = &qp_ctx->zip_sqe;
> >> struct acomp_req *a_req = req->req;
> >> struct hisi_qp *qp = qp_ctx->qp;
> >> struct device *dev = &qp->qm->pdev->dev;
> >> struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;
> >> + struct hisi_zip_sqe zip_sqe;
> >> dma_addr_t input;
> >> dma_addr_t output;
> >> int ret;
> >> @@ -511,13 +510,13 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
> >> }
> >> req->dma_dst = output;
> >>
> >> - hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, a_req->slen,
> >> + hisi_zip_fill_sqe(&zip_sqe, qp->req_type, input, output,
> >> +a_req->slen,
> >> a_req->dlen, req->sskip, req->dskip);
> >> - hisi_zip_config_buf_type(zip_sqe, HZIP_SGL);
> >> - hisi_zip_config_tag(zip_sqe, req->req_id);
> >> + hisi_zip_config_buf_type(&zip_sqe, HZIP_SGL);
> >> + hisi_zip_config_tag(&zip_sqe, req->req_id);
> >>
> >> /* send command to start a task */
> >> - ret = hisi_qp_send(qp, zip_sqe);
> >> + ret = hisi_qp_send(qp, &zip_sqe);
> >> if (ret < 0)
> >> goto err_unmap_output;
> >>