Index: share/man/man9/crypto_request.9 =================================================================== --- share/man/man9/crypto_request.9 +++ share/man/man9/crypto_request.9 @@ -30,7 +30,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 4, 2022 +.Dd July 19, 2022 .Dt CRYPTO_REQUEST 9 .Os .Sh NAME @@ -55,6 +55,8 @@ .Ft void .Fn crypto_initreq "crypto_session_t cses" "int how" .Ft void +.Fn crypto_reset "struct cryptop *crp" +.Ft void .Fn crypto_use_buf "struct cryptop *crp" "void *buf" "int len" .Ft void .Fn crypto_use_mbuf "struct cryptop *crp" "struct mbuf *m" @@ -134,13 +136,24 @@ .Fn crypto_dispatch_batch functions pass one or more crypto requests to the driver attached to the request's session. -If there are errors in the request's fields, these functions may return an -error to the caller. -If errors are encountered while servicing the request, they will instead -be reported to the request's callback function +If errors are encountered while servicing the request, they will be reported to +the request's callback function .Pq Fa crp_callback -via -.Fa crp_etype . +via the +.Fa crp_etype +field. +In particular, this field will be set to an errno value describing the error, +or zero if the request completed successfully. +Errors may arise due to invalid request parameters, or due to transient resource +shortages when a hardware offload driver is in use. +The error number +.Dv EAGAIN +indicates that the request could be retried. +In this case, +.Fn crypto_reset +should be called to reset some state in the request structure prior to calling +.Fn crypto_dispatch +again. .Pp Note that a request's callback function may be invoked before .Fn crypto_dispatch Index: sys/geom/eli/g_eli.c =================================================================== --- sys/geom/eli/g_eli.c +++ sys/geom/eli/g_eli.c @@ -257,7 +257,7 @@ bp->bio_cmd == BIO_READ ? "READ" : "WRITE", wr->w_sid, crp->crp_session); wr->w_sid = crp->crp_session; - crp->crp_etype = 0; + crypto_reset(crp); crypto_dispatch(crp); } Index: sys/kgssapi/krb5/kcrypto_aes.c =================================================================== --- sys/kgssapi/krb5/kcrypto_aes.c +++ sys/kgssapi/krb5/kcrypto_aes.c @@ -125,6 +125,7 @@ return (0); if (crp->crp_etype == EAGAIN) { + crypto_reset(crp); crypto_dispatch(crp); return (0); } Index: sys/netipsec/xform_ah.c =================================================================== --- sys/netipsec/xform_ah.c +++ sys/netipsec/xform_ah.c @@ -725,6 +725,7 @@ crypto_freesession(cryptoid); xd->cryptoid = crp->crp_session; CURVNET_RESTORE(); + crypto_reset(crp); crypto_dispatch(crp); return (0); } @@ -1116,6 +1117,7 @@ crypto_freesession(cryptoid); xd->cryptoid = crp->crp_session; CURVNET_RESTORE(); + crypto_reset(crp); crypto_dispatch(crp); return (0); } Index: sys/netipsec/xform_esp.c =================================================================== --- sys/netipsec/xform_esp.c +++ sys/netipsec/xform_esp.c @@ -517,6 +517,7 @@ crypto_freesession(cryptoid); xd->cryptoid = crp->crp_session; CURVNET_RESTORE(); + crypto_reset(crp); crypto_dispatch(crp); return (0); } @@ -1005,6 +1006,7 @@ crypto_freesession(cryptoid); xd->cryptoid = crp->crp_session; CURVNET_RESTORE(); + crypto_reset(crp); crypto_dispatch(crp); return (0); } Index: sys/netipsec/xform_ipcomp.c =================================================================== --- sys/netipsec/xform_ipcomp.c +++ sys/netipsec/xform_ipcomp.c @@ -315,6 +315,7 @@ crypto_freesession(cryptoid); xd->cryptoid = crp->crp_session; CURVNET_RESTORE(); + crypto_reset(crp); crypto_dispatch(crp); return (0); } @@ -561,6 +562,7 @@ crypto_freesession(cryptoid); xd->cryptoid = crp->crp_session; CURVNET_RESTORE(); + crypto_reset(crp); crypto_dispatch(crp); return (0); } Index: sys/opencrypto/crypto.c =================================================================== --- sys/opencrypto/crypto.c +++ sys/opencrypto/crypto.c @@ -1748,6 +1748,19 @@ } } +void +crypto_reset(struct cryptop *crp) +{ + KASSERT(crp->crp_etype == EAGAIN, + ("%s: cryptop %p unexpected error %d", + __func__, crp, crp->crp_etype)); + KASSERT((crp->crp_flags & CRYPTO_F_DONE) != 0, + ("%s: resettting an unfinished cryptop %p", __func__, crp)); + + crp->crp_etype = 0; + crp->crp_flags &= ~CRYPTO_F_DONE; +} + /* * Terminate a thread at module unload. The process that * initiated this is waiting for us to signal that we're gone; Index: sys/opencrypto/cryptodev.h =================================================================== --- sys/opencrypto/cryptodev.h +++ sys/opencrypto/cryptodev.h @@ -630,6 +630,7 @@ #define CRYPTO_SYMQ 0x1 int crypto_unblock(uint32_t, int); void crypto_done(struct cryptop *crp); +void crypto_reset(struct cryptop *crp); struct cryptop *crypto_clonereq(struct cryptop *crp, crypto_session_t cses, int how); Index: sys/opencrypto/cryptodev.c =================================================================== --- sys/opencrypto/cryptodev.c +++ sys/opencrypto/cryptodev.c @@ -821,8 +821,7 @@ mtx_unlock(&cse->lock); if (crp->crp_etype == EAGAIN) { - crp->crp_etype = 0; - crp->crp_flags &= ~CRYPTO_F_DONE; + crypto_reset(crp); cod->done = false; goto again; } @@ -1020,8 +1019,7 @@ mtx_unlock(&cse->lock); if (crp->crp_etype == EAGAIN) { - crp->crp_etype = 0; - crp->crp_flags &= ~CRYPTO_F_DONE; + crypto_reset(crp); cod->done = false; goto again; } Index: sys/opencrypto/ktls_ocf.c =================================================================== --- sys/opencrypto/ktls_ocf.c +++ sys/opencrypto/ktls_ocf.c @@ -220,8 +220,7 @@ break; } - crp->crp_etype = 0; - crp->crp_flags &= ~CRYPTO_F_DONE; + crypto_reset(crp); oo.done = false; counter_u64_add(ocf_retries, 1); } @@ -236,8 +235,7 @@ state = crp->crp_opaque; if (crp->crp_etype == EAGAIN) { - crp->crp_etype = 0; - crp->crp_flags &= ~CRYPTO_F_DONE; + crypto_reset(crp); counter_u64_add(ocf_retries, 1); crypto_dispatch(crp); return (0);