From: Keith Busch <[email protected]> There are a few paths that can fail with -ENOMEM, like skcipher_copy_iv, which had been treated as a generic failure. This is a transient host resource issue that can be retried later.
Signed-off-by: Keith Busch <[email protected]> --- drivers/md/dm-crypt.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 608b617fb817f..fc9c875cccfd2 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1338,6 +1338,8 @@ static int crypt_convert_block_aead(struct crypt_config *cc, dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", ctx->bio_in, s, 0); } + } else if (unlikely(r == -ENOMEM)) { + return r; } if (!r && cc->iv_gen_ops && cc->iv_gen_ops->post) @@ -1417,6 +1419,9 @@ static int crypt_convert_block_skcipher(struct crypt_config *cc, else r = crypto_skcipher_decrypt(req); + if (unlikely(r == -ENOMEM)) + return r; + if (!r && cc->iv_gen_ops && cc->iv_gen_ops->post) cc->iv_gen_ops->post(cc, org_iv, dmreq); @@ -1593,6 +1598,13 @@ static blk_status_t crypt_convert(struct crypt_config *cc, case -EBADMSG: atomic_dec(&ctx->cc_pending); return BLK_STS_PROTECTION; + /* + * There was a host resource issue. + */ + case -ENOMEM: + atomic_dec(&ctx->cc_pending); + complete(&ctx->restart); + return BLK_STS_RESOURCE; /* * There was an error while processing the request. */ @@ -2072,10 +2084,11 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags), true); /* * Crypto API backlogged the request, because its queue was full - * and we're in softirq context, so continue from a workqueue - * (TODO: is it actually possible to be in softirq in the write path?) + * and we're in softirq context, or a host memory allocation + * temporarily failed, so continue from a workqueue (TODO: is it + * actually possible to be in softirq in the write path?) */ - if (r == BLK_STS_DEV_RESOURCE) { + if (r == BLK_STS_DEV_RESOURCE || r == BLK_STS_RESOURCE) { INIT_WORK(&io->work, kcryptd_crypt_write_continue); queue_work(cc->crypt_queue, &io->work); return; @@ -2148,9 +2161,10 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) } /* * Crypto API backlogged the request, because its queue was full - * and we're in softirq context, so continue from a workqueue + * and we're in softirq context, or a host memory allocation + * temporarily failed, so continue from a workqueue */ - if (r == BLK_STS_DEV_RESOURCE) { + if (r == BLK_STS_DEV_RESOURCE || r == BLK_STS_RESOURCE) { INIT_WORK(&io->work, kcryptd_crypt_read_continue); queue_work(cc->crypt_queue, &io->work); return; -- 2.52.0
