aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/apm821xx/patches-4.14/020-0021-crypto-crypto4xx-fix-stalls-under-heavy-load.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/apm821xx/patches-4.14/020-0021-crypto-crypto4xx-fix-stalls-under-heavy-load.patch')
-rw-r--r--target/linux/apm821xx/patches-4.14/020-0021-crypto-crypto4xx-fix-stalls-under-heavy-load.patch112
1 files changed, 112 insertions, 0 deletions
diff --git a/target/linux/apm821xx/patches-4.14/020-0021-crypto-crypto4xx-fix-stalls-under-heavy-load.patch b/target/linux/apm821xx/patches-4.14/020-0021-crypto-crypto4xx-fix-stalls-under-heavy-load.patch
new file mode 100644
index 0000000000..aa621c52ce
--- /dev/null
+++ b/target/linux/apm821xx/patches-4.14/020-0021-crypto-crypto4xx-fix-stalls-under-heavy-load.patch
@@ -0,0 +1,112 @@
+From 4b5b79998af61db8b0506fba6c0f33b57ea457bd Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Wed, 4 Oct 2017 01:00:13 +0200
+Subject: [PATCH 21/25] crypto: crypto4xx - fix stalls under heavy load
+
+If the crypto4xx device is continuously loaded by dm-crypt
+and ipsec work, it will start to work intermittent after a
+few (between 20-30) seconds, hurting throughput and latency.
+
+This patch contains various stability improvements in order
+to fix this issue. So far, the hardware has survived more
+than a day without suffering any stalls under the continuous
+load.
+
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_core.c | 33 ++++++++++++++++++---------------
+ drivers/crypto/amcc/crypto4xx_reg_def.h | 3 +++
+ 2 files changed, 21 insertions(+), 15 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -280,17 +280,20 @@ static u32 crypto4xx_get_pd_from_pdr_nol
+ static u32 crypto4xx_put_pd_to_pdr(struct crypto4xx_device *dev, u32 idx)
+ {
+ struct pd_uinfo *pd_uinfo = &dev->pdr_uinfo[idx];
++ u32 tail;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
++ pd_uinfo->state = PD_ENTRY_FREE;
++
+ if (dev->pdr_tail != PPC4XX_LAST_PD)
+ dev->pdr_tail++;
+ else
+ dev->pdr_tail = 0;
+- pd_uinfo->state = PD_ENTRY_FREE;
++ tail = dev->pdr_tail;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+- return 0;
++ return tail;
+ }
+
+ /**
+@@ -854,16 +857,16 @@ int crypto4xx_build_pd(struct crypto_asy
+ }
+ }
+
+- sa->sa_command_1.bf.hash_crypto_offset = 0;
+- pd->pd_ctl.w = 0;
+- pd->pd_ctl.bf.hash_final =
+- (crypto_tfm_alg_type(req->tfm) == CRYPTO_ALG_TYPE_AHASH);
+- pd->pd_ctl.bf.host_ready = 1;
++ pd->pd_ctl.w = PD_CTL_HOST_READY |
++ ((crypto_tfm_alg_type(req->tfm) == CRYPTO_ALG_TYPE_AHASH) |
++ (crypto_tfm_alg_type(req->tfm) == CRYPTO_ALG_TYPE_AEAD) ?
++ PD_CTL_HASH_FINAL : 0);
+ pd->pd_ctl_len.w = 0x00400000 | datalen;
+ pd_uinfo->state = PD_ENTRY_INUSE | (is_busy ? PD_ENTRY_BUSY : 0);
+
+ wmb();
+ /* write any value to push engine to read a pd */
++ writel(0, dev->ce_base + CRYPTO4XX_INT_DESCR_RD);
+ writel(1, dev->ce_base + CRYPTO4XX_INT_DESCR_RD);
+ return is_busy ? -EBUSY : -EINPROGRESS;
+ }
+@@ -964,23 +967,23 @@ static void crypto4xx_bh_tasklet_cb(unsi
+ struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+ struct pd_uinfo *pd_uinfo;
+ struct ce_pd *pd;
+- u32 tail;
++ u32 tail = core_dev->dev->pdr_tail;
++ u32 head = core_dev->dev->pdr_head;
+
+- while (core_dev->dev->pdr_head != core_dev->dev->pdr_tail) {
+- tail = core_dev->dev->pdr_tail;
++ do {
+ pd_uinfo = &core_dev->dev->pdr_uinfo[tail];
+ pd = &core_dev->dev->pdr[tail];
+ if ((pd_uinfo->state & PD_ENTRY_INUSE) &&
+- pd->pd_ctl.bf.pe_done &&
+- !pd->pd_ctl.bf.host_ready) {
+- pd->pd_ctl.bf.pe_done = 0;
++ ((READ_ONCE(pd->pd_ctl.w) &
++ (PD_CTL_PE_DONE | PD_CTL_HOST_READY)) ==
++ PD_CTL_PE_DONE)) {
+ crypto4xx_pd_done(core_dev->dev, tail);
+- crypto4xx_put_pd_to_pdr(core_dev->dev, tail);
++ tail = crypto4xx_put_pd_to_pdr(core_dev->dev, tail);
+ } else {
+ /* if tail not done, break */
+ break;
+ }
+- }
++ } while (head != tail);
+ }
+
+ /**
+--- a/drivers/crypto/amcc/crypto4xx_reg_def.h
++++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
+@@ -261,6 +261,9 @@ union ce_pd_ctl {
+ } bf;
+ u32 w;
+ } __attribute__((packed));
++#define PD_CTL_HASH_FINAL BIT(4)
++#define PD_CTL_PE_DONE BIT(1)
++#define PD_CTL_HOST_READY BIT(0)
+
+ union ce_pd_ctl_len {
+ struct {