From 5d4f7e756645d1e414ea08183061befecc1b7466 Mon Sep 17 00:00:00 2001
From: Alexander Motin <mav@FreeBSD.org>
Date: Mon, 24 May 2021 16:42:45 -0400
Subject: [PATCH] FreeBSD: Retry OCF ENOMEM errors.

ZFS does not expect transient errors from crypto.  For read they are
counted as checksum errors, while for write end up in panic.  To not
panic on random low memory conditions retry ENOMEM errors in the OCF
wrapper function.

While there remove unneeded timeout and priority from msleep().

External-issue: https://reviews.freebsd.org/D30339
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Mark Maybee <mark.maybee@delphix.com>
Signed-off-by: Alexander Motin <mav@FreeBSD.org>
Sponsored-By: iXsystems, Inc.
Closes #12077
---
 module/os/freebsd/zfs/crypto_os.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/module/os/freebsd/zfs/crypto_os.c b/module/os/freebsd/zfs/crypto_os.c
index 0a7241699..a0223a64f 100644
--- a/module/os/freebsd/zfs/crypto_os.c
+++ b/module/os/freebsd/zfs/crypto_os.c
@@ -172,11 +172,13 @@ zfs_crypto_dispatch(freebsd_crypt_session_t *session, 	struct cryptop *crp)
 			break;
 		mtx_lock(&session->fs_lock);
 		while (session->fs_done == false)
-			msleep(crp, &session->fs_lock, PRIBIO,
-			    "zfs_crypto", hz/5);
+			msleep(crp, &session->fs_lock, 0,
+			    "zfs_crypto", 0);
 		mtx_unlock(&session->fs_lock);
 
-		if (crp->crp_etype != EAGAIN) {
+		if (crp->crp_etype == ENOMEM) {
+			pause("zcrnomem", 1);
+		} else if (crp->crp_etype != EAGAIN) {
 			error = crp->crp_etype;
 			break;
 		}