Module Name: src Committed By: riastradh Date: Sat Aug 7 15:41:01 UTC 2021
Modified Files: src/sys/arch/arm/sunxi: sun8i_crypto.c Log Message: sun8icrypto(4): Call crypto_unblock when a task completes. Otherwise under load this would presumably just hang after returning ERESTART to opencrypto. To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/arch/arm/sunxi/sun8i_crypto.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/sunxi/sun8i_crypto.c diff -u src/sys/arch/arm/sunxi/sun8i_crypto.c:1.25 src/sys/arch/arm/sunxi/sun8i_crypto.c:1.26 --- src/sys/arch/arm/sunxi/sun8i_crypto.c:1.25 Wed Apr 28 16:57:05 2021 +++ src/sys/arch/arm/sunxi/sun8i_crypto.c Sat Aug 7 15:41:00 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sun8i_crypto.c,v 1.25 2021/04/28 16:57:05 bad Exp $ */ +/* $NetBSD: sun8i_crypto.c,v 1.26 2021/08/07 15:41:00 riastradh Exp $ */ /*- * Copyright (c) 2019 The NetBSD Foundation, Inc. @@ -43,7 +43,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: sun8i_crypto.c,v 1.25 2021/04/28 16:57:05 bad Exp $"); +__KERNEL_RCSID(1, "$NetBSD: sun8i_crypto.c,v 1.26 2021/08/07 15:41:00 riastradh Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -211,7 +211,7 @@ static void sun8i_crypto_timeout(void *) static int sun8i_crypto_intr(void *); static void sun8i_crypto_schedule_worker(struct sun8i_crypto_softc *); static void sun8i_crypto_worker(struct work *, void *); -static void sun8i_crypto_chan_done(struct sun8i_crypto_softc *, unsigned, +static bool sun8i_crypto_chan_done(struct sun8i_crypto_softc *, unsigned, int); static int sun8i_crypto_allocbuf(struct sun8i_crypto_softc *, size_t, @@ -1051,6 +1051,7 @@ sun8i_crypto_worker(struct work *wk, voi struct sun8i_crypto_softc *sc = cookie; uint32_t done, esr, esr_chan; unsigned i, now; + bool unblock = false; int error; /* @@ -1084,7 +1085,8 @@ sun8i_crypto_worker(struct work *wk, voi if ((sc->sc_chan[i].cc_task != NULL) && ((now - sc->sc_chan[i].cc_starttime) >= SUN8I_CRYPTO_TIMEOUT)) - sun8i_crypto_chan_done(sc, i, ETIMEDOUT); + unblock |= sun8i_crypto_chan_done(sc, i, + ETIMEDOUT); continue; } @@ -1112,11 +1114,23 @@ sun8i_crypto_worker(struct work *wk, voi * Notify the task of completion. May release the lock * to invoke a callback. */ - sun8i_crypto_chan_done(sc, i, error); + unblock |= sun8i_crypto_chan_done(sc, i, error); } /* All one; release the lock one last time. */ mutex_exit(&sc->sc_lock); + + /* + * If we cleared any channels, it is time to allow opencrypto + * to issue new operations. Asymmetric operations (which we + * don't support, at the moment, but we could) and symmetric + * operations (which we do) use the same task channels, so we + * unblock both kinds. + */ + if (unblock) { + crypto_unblock(sc->sc_opencrypto.co_driverid, + CRYPTO_SYMQ|CRYPTO_ASYMQ); + } } /* @@ -1125,7 +1139,7 @@ sun8i_crypto_worker(struct work *wk, voi * Notify the callback for the task on channel i, if there is one, * of the specified error, or 0 for success. */ -static void +static bool sun8i_crypto_chan_done(struct sun8i_crypto_softc *sc, unsigned i, int error) { struct sun8i_crypto_task *task; @@ -1140,7 +1154,8 @@ sun8i_crypto_chan_done(struct sun8i_cryp if ((task = sc->sc_chan[i].cc_task) == NULL) { device_printf(sc->sc_dev, "channel %u: no task but error=%d\n", i, error); - return; + /* We did not clear a channel. */ + return false; } sc->sc_chan[i].cc_task = NULL; @@ -1183,6 +1198,9 @@ sun8i_crypto_chan_done(struct sun8i_cryp SDT_PROBE2(sdt, sun8i_crypto, task, done, task, error); (*task->ct_callback)(sc, task, task->ct_cookie, error); mutex_enter(&sc->sc_lock); + + /* We cleared a channel. */ + return true; } /* @@ -1811,7 +1829,7 @@ sun8i_crypto_register1(struct sun8i_cryp * Called by opencrypto to allocate a new session. We don't keep * track of sessions, since there are no persistent keys in the * hardware that we take advantage of, so this only validates the - * crypto operations and returns a zero session id. + * crypto operations and returns a dummy session id of 1. */ static int sun8i_crypto_newsession(void *cookie, uint32_t *sidp, struct cryptoini *cri) @@ -1823,7 +1841,7 @@ sun8i_crypto_newsession(void *cookie, ui /* * No variation of rounds is supported here. (XXX Unused and - * unimplemented in opencrypto(9) altogether? + * unimplemented in opencrypto(9) altogether?) */ if (cri->cri_rnd) return EINVAL;