diff options
author | Christian Lamparter <chunkeey@gmail.com> | 2018-01-07 21:27:50 +0100 |
---|---|---|
committer | Mathias Kresin <dev@kresin.me> | 2018-01-12 08:00:04 +0100 |
commit | 780477d17c0e73e54397a0f3cebff08634e7231a (patch) | |
tree | 098826be0c3cbfb24fc1fc15219eed83d915e84a /target/linux/apm821xx/patches-4.14/020-0017-crypto-crypto4xx-add-backlog-queue-support.patch | |
parent | e4371779d2691553e6321e87d86212beaaa8b89d (diff) | |
download | upstream-780477d17c0e73e54397a0f3cebff08634e7231a.tar.gz upstream-780477d17c0e73e54397a0f3cebff08634e7231a.tar.bz2 upstream-780477d17c0e73e54397a0f3cebff08634e7231a.zip |
apm821xx: backport crypto4xx patches from 4.15
This patch backports changes to crypto4xx in order
to get the crypto4xx operational.
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Diffstat (limited to 'target/linux/apm821xx/patches-4.14/020-0017-crypto-crypto4xx-add-backlog-queue-support.patch')
-rw-r--r-- | target/linux/apm821xx/patches-4.14/020-0017-crypto-crypto4xx-add-backlog-queue-support.patch | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/target/linux/apm821xx/patches-4.14/020-0017-crypto-crypto4xx-add-backlog-queue-support.patch b/target/linux/apm821xx/patches-4.14/020-0017-crypto-crypto4xx-add-backlog-queue-support.patch new file mode 100644 index 0000000000..046dd9c257 --- /dev/null +++ b/target/linux/apm821xx/patches-4.14/020-0017-crypto-crypto4xx-add-backlog-queue-support.patch @@ -0,0 +1,161 @@ +From 8ef8d195430ca3542d0434cf25e5115484b9fa32 Mon Sep 17 00:00:00 2001 +From: Christian Lamparter <chunkeey@gmail.com> +Date: Wed, 4 Oct 2017 01:00:09 +0200 +Subject: [PATCH 17/25] crypto: crypto4xx - add backlog queue support + +Previously, If the crypto4xx driver used all available +security contexts, it would simply refuse new requests +with -EAGAIN. CRYPTO_TFM_REQ_MAY_BACKLOG was ignored. + +in case of dm-crypt.c's crypt_convert() function this was +causing the following errors to manifest, if the system was +pushed hard enough: + +| EXT4-fs warning (dm-1): ext4_end_bio:314: I/O error -5 writing to ino .. +| EXT4-fs warning (dm-1): ext4_end_bio:314: I/O error -5 writing to ino .. +| EXT4-fs warning (dm-1): ext4_end_bio:314: I/O error -5 writing to ino .. +| JBD2: Detected IO errors while flushing file data on dm-1-8 +| Aborting journal on device dm-1-8. +| EXT4-fs error : ext4_journal_check_start:56: Detected aborted journal +| EXT4-fs (dm-1): Remounting filesystem read-only +| EXT4-fs : ext4_writepages: jbd2_start: 2048 pages, inode 498...; err -30 + +(This did cause corruptions due to failed writes) + +To fix this mess, the crypto4xx driver needs to notifiy the +user to slow down. This can be achieved by returning -EBUSY +on requests, once the crypto hardware was falling behind. + +Note: -EBUSY has two different meanings. Setting the flag +CRYPTO_TFM_REQ_MAY_BACKLOG implies that the request was +successfully queued, by the crypto driver. To achieve this +requirement, the implementation introduces a threshold check and +adds logic to the completion routines in much the same way as +AMD's Cryptographic Coprocessor (CCP) driver do. + +Note2: Tests showed that dm-crypt starved ipsec traffic. +Under load, ipsec links dropped to 0 Kbits/s. This is because +dm-crypt's callback would instantly queue the next request. +In order to not starve ipsec, the driver reserves a small +portion of the available crypto contexts for this purpose. + +Signed-off-by: Christian Lamparter <chunkeey@gmail.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +--- + drivers/crypto/amcc/crypto4xx_core.c | 47 ++++++++++++++++++++++++++++++------ + drivers/crypto/amcc/crypto4xx_core.h | 3 ++- + 2 files changed, 41 insertions(+), 9 deletions(-) + +--- a/drivers/crypto/amcc/crypto4xx_core.c ++++ b/drivers/crypto/amcc/crypto4xx_core.c +@@ -39,6 +39,7 @@ + #include <crypto/ctr.h> + #include <crypto/sha.h> + #include <crypto/scatterwalk.h> ++#include <crypto/internal/skcipher.h> + #include "crypto4xx_reg_def.h" + #include "crypto4xx_core.h" + #include "crypto4xx_sa.h" +@@ -573,8 +574,10 @@ static u32 crypto4xx_ablkcipher_done(str + dst->offset, dst->length, DMA_FROM_DEVICE); + } + crypto4xx_ret_sg_desc(dev, pd_uinfo); +- if (ablk_req->base.complete != NULL) +- ablk_req->base.complete(&ablk_req->base, 0); ++ ++ if (pd_uinfo->state & PD_ENTRY_BUSY) ++ ablkcipher_request_complete(ablk_req, -EINPROGRESS); ++ ablkcipher_request_complete(ablk_req, 0); + + return 0; + } +@@ -591,9 +594,10 @@ static u32 crypto4xx_ahash_done(struct c + crypto4xx_copy_digest_to_dst(pd_uinfo, + crypto_tfm_ctx(ahash_req->base.tfm)); + crypto4xx_ret_sg_desc(dev, pd_uinfo); +- /* call user provided callback function x */ +- if (ahash_req->base.complete != NULL) +- ahash_req->base.complete(&ahash_req->base, 0); ++ ++ if (pd_uinfo->state & PD_ENTRY_BUSY) ++ ahash_request_complete(ahash_req, -EINPROGRESS); ++ ahash_request_complete(ahash_req, 0); + + return 0; + } +@@ -704,6 +708,7 @@ u32 crypto4xx_build_pd(struct crypto_asy + struct pd_uinfo *pd_uinfo = NULL; + unsigned int nbytes = datalen, idx; + u32 gd_idx = 0; ++ bool is_busy; + + /* figure how many gd is needed */ + num_gd = sg_nents_for_len(src, datalen); +@@ -734,6 +739,31 @@ u32 crypto4xx_build_pd(struct crypto_asy + * already got must be return the original place. + */ + spin_lock_irqsave(&dev->core_dev->lock, flags); ++ /* ++ * Let the caller know to slow down, once more than 13/16ths = 81% ++ * of the available data contexts are being used simultaneously. ++ * ++ * With PPC4XX_NUM_PD = 256, this will leave a "backlog queue" for ++ * 31 more contexts. Before new requests have to be rejected. ++ */ ++ if (req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG) { ++ is_busy = ((dev->pdr_head - dev->pdr_tail) % PPC4XX_NUM_PD) >= ++ ((PPC4XX_NUM_PD * 13) / 16); ++ } else { ++ /* ++ * To fix contention issues between ipsec (no blacklog) and ++ * dm-crypto (backlog) reserve 32 entries for "no backlog" ++ * data contexts. ++ */ ++ is_busy = ((dev->pdr_head - dev->pdr_tail) % PPC4XX_NUM_PD) >= ++ ((PPC4XX_NUM_PD * 15) / 16); ++ ++ if (is_busy) { ++ spin_unlock_irqrestore(&dev->core_dev->lock, flags); ++ return -EBUSY; ++ } ++ } ++ + if (num_gd) { + fst_gd = crypto4xx_get_n_gd(dev, num_gd); + if (fst_gd == ERING_WAS_FULL) { +@@ -888,11 +918,12 @@ u32 crypto4xx_build_pd(struct crypto_asy + sa->sa_command_1.bf.hash_crypto_offset = 0; + pd->pd_ctl.w = ctx->pd_ctl; + pd->pd_ctl_len.w = 0x00400000 | datalen; +- pd_uinfo->state = PD_ENTRY_INUSE; ++ pd_uinfo->state = PD_ENTRY_INUSE | (is_busy ? PD_ENTRY_BUSY : 0); ++ + wmb(); + /* write any value to push engine to read a pd */ + writel(1, dev->ce_base + CRYPTO4XX_INT_DESCR_RD); +- return -EINPROGRESS; ++ return is_busy ? -EBUSY : -EINPROGRESS; + } + + /** +@@ -997,7 +1028,7 @@ static void crypto4xx_bh_tasklet_cb(unsi + tail = core_dev->dev->pdr_tail; + pd_uinfo = &core_dev->dev->pdr_uinfo[tail]; + pd = &core_dev->dev->pdr[tail]; +- if ((pd_uinfo->state == PD_ENTRY_INUSE) && ++ 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; +--- a/drivers/crypto/amcc/crypto4xx_core.h ++++ b/drivers/crypto/amcc/crypto4xx_core.h +@@ -44,7 +44,8 @@ + #define PPC4XX_LAST_SD (PPC4XX_NUM_SD - 1) + #define PPC4XX_SD_BUFFER_SIZE 2048 + +-#define PD_ENTRY_INUSE 1 ++#define PD_ENTRY_BUSY BIT(1) ++#define PD_ENTRY_INUSE BIT(0) + #define PD_ENTRY_FREE 0 + #define ERING_WAS_FULL 0xffffffff + |