Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Tweak locking and use a pool cache for commands ...
details: https://anonhg.NetBSD.org/src/rev/221b1a32816d
branches: trunk
changeset: 932822:221b1a32816d
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun May 17 00:53:09 2020 +0000
description:
Tweak locking and use a pool cache for commands and dmamaps.
This is enough to get the crypto decelerator working in LOCKDEBUG;
previously it would crash the moment you looked at it.
diffstat:
sys/dev/pci/hifn7751.c | 165 +++++++++++++++++++++++++--------------------
sys/dev/pci/hifn7751var.h | 4 +-
2 files changed, 95 insertions(+), 74 deletions(-)
diffs (truncated from 412 to 300 lines):
diff -r feda0d62490b -r 221b1a32816d sys/dev/pci/hifn7751.c
--- a/sys/dev/pci/hifn7751.c Sun May 17 00:52:31 2020 +0000
+++ b/sys/dev/pci/hifn7751.c Sun May 17 00:53:09 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hifn7751.c,v 1.70 2020/05/17 00:52:31 riastradh Exp $ */
+/* $NetBSD: hifn7751.c,v 1.71 2020/05/17 00:53:09 riastradh Exp $ */
/* $OpenBSD: hifn7751.c,v 1.179 2020/01/11 21:34:03 cheloha Exp $ */
/*
@@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.70 2020/05/17 00:52:31 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.71 2020/05/17 00:53:09 riastradh Exp $");
#include <sys/param.h>
#include <sys/cprng.h>
@@ -55,10 +55,10 @@
#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/kernel.h>
-#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/pool.h>
#include <sys/proc.h>
#include <sys/rndsource.h>
#include <sys/sha1.h>
@@ -138,6 +138,48 @@
struct hifn_stats hifnstats;
+static int
+hifn_cmd_ctor(void *vsc, void *vcmd, int pflags)
+{
+ struct hifn_softc *sc = vsc;
+ struct hifn_command *cmd = vcmd;
+ int bflags = pflags & PR_WAITOK ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT;
+ int error;
+
+ memset(cmd, 0, sizeof(*cmd));
+
+ error = bus_dmamap_create(sc->sc_dmat,
+ HIFN_MAX_DMALEN, MAX_SCATTER, HIFN_MAX_SEGLEN,
+ 0, bflags, &cmd->src_map);
+ if (error)
+ goto fail0;
+
+ error = bus_dmamap_create(sc->sc_dmat,
+ HIFN_MAX_SEGLEN*MAX_SCATTER, MAX_SCATTER, HIFN_MAX_SEGLEN,
+ 0, bflags, &cmd->dst_map_alloc);
+ if (error)
+ goto fail1;
+
+ /* Success! */
+ cmd->dst_map = NULL;
+ return 0;
+
+fail2: __unused
+ bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map_alloc);
+fail1: bus_dmamap_destroy(sc->sc_dmat, cmd->src_map);
+fail0: return error;
+}
+
+static void
+hifn_cmd_dtor(void *vsc, void *vcmd)
+{
+ struct hifn_softc *sc = vsc;
+ struct hifn_command *cmd = vcmd;
+
+ bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map_alloc);
+ bus_dmamap_destroy(sc->sc_dmat, cmd->src_map);
+}
+
static const struct hifn_product {
pci_vendor_id_t hifn_vendor;
pci_product_id_t hifn_product;
@@ -360,6 +402,11 @@
goto fail_intr;
}
+ sc->sc_cmd_cache = pool_cache_init(sizeof(struct hifn_command),
+ 0, 0, 0, "hifncmd", NULL, IPL_VM,
+ &hifn_cmd_ctor, &hifn_cmd_dtor, sc);
+ pool_cache_setlowat(sc->sc_cmd_cache, sc->sc_maxses);
+
WRITE_REG_0(sc, HIFN_0_PUCNFG,
READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
@@ -426,7 +473,9 @@
{
struct hifn_softc *sc = device_private(self);
+ mutex_enter(&sc->sc_mtx);
hifn_abort(sc);
+ mutex_exit(&sc->sc_mtx);
hifn_reset_board(sc, 1);
@@ -436,11 +485,11 @@
rnd_detach_source(&sc->sc_rnd_source);
- mutex_enter(&sc->sc_mtx);
callout_halt(&sc->sc_tickto, NULL);
if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
callout_halt(&sc->sc_rngto, NULL);
- mutex_exit(&sc->sc_mtx);
+
+ pool_cache_destroy(sc->sc_cmd_cache);
bus_space_unmap(sc->sc_st1, sc->sc_sh1, sc->sc_iosz1);
bus_space_unmap(sc->sc_st0, sc->sc_sh0, sc->sc_iosz0);
@@ -1601,10 +1650,6 @@
uint32_t cmdlen;
int cmdi, resi, err = 0;
- if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER,
- HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->src_map))
- return (ENOMEM);
-
if (crp->crp_flags & CRYPTO_F_IMBUF) {
if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->src_map,
cmd->srcu.src_m, BUS_DMA_NOWAIT)) {
@@ -1684,15 +1729,7 @@
}
cmd->dstu.dst_m = m0;
}
- }
-
- if (cmd->dst_map == NULL) {
- if (bus_dmamap_create(sc->sc_dmat,
- HIFN_MAX_SEGLEN * MAX_SCATTER, MAX_SCATTER,
- HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->dst_map)) {
- err = ENOMEM;
- goto err_srcmap;
- }
+ cmd->dst_map = cmd->dst_map_alloc;
if (crp->crp_flags & CRYPTO_F_IMBUF) {
if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map,
cmd->dstu.dst_m, BUS_DMA_NOWAIT)) {
@@ -1840,15 +1877,9 @@
if (cmd->src_map != cmd->dst_map)
bus_dmamap_unload(sc->sc_dmat, cmd->dst_map);
err_dstmap1:
- if (cmd->src_map != cmd->dst_map)
- bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map);
err_srcmap:
- if (crp->crp_flags & CRYPTO_F_IMBUF &&
- cmd->srcu.src_m != cmd->dstu.dst_m)
- m_freem(cmd->dstu.dst_m);
bus_dmamap_unload(sc->sc_dmat, cmd->src_map);
err_srcmap1:
- bus_dmamap_destroy(sc->sc_dmat, cmd->src_map);
return (err);
}
@@ -1897,6 +1928,8 @@
uint32_t dmacsr, restart;
int i, u;
+ mutex_spin_enter(&sc->sc_mtx);
+
dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
#ifdef HIFN_DEBUG
@@ -1907,8 +1940,6 @@
dma->cmdu, dma->srcu, dma->dstu, dma->resu);
#endif
- mutex_spin_enter(&sc->sc_mtx);
-
/* Nothing in the DMA unit interrupted */
if ((dmacsr & sc->sc_dmaier) == 0) {
mutex_spin_exit(&sc->sc_mtx);
@@ -2143,6 +2174,11 @@
return (EINVAL);
}
+ if ((cmd = pool_cache_get(sc->sc_cmd_cache, PR_NOWAIT)) == NULL) {
+ hifnstats.hst_nomem++;
+ return (ENOMEM);
+ }
+
mutex_spin_enter(&sc->sc_mtx);
session = HIFN_SESSION(crp->crp_sid);
if (session >= sc->sc_maxses) {
@@ -2150,13 +2186,6 @@
goto errout;
}
- cmd = malloc(sizeof(*cmd), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (cmd == NULL) {
- hifnstats.hst_nomem++;
- err = ENOMEM;
- goto errout;
- }
-
if (crp->crp_flags & CRYPTO_F_IMBUF) {
cmd->srcu.src_m = (struct mbuf *)crp->crp_buf;
cmd->dstu.dst_m = (struct mbuf *)crp->crp_buf;
@@ -2192,7 +2221,9 @@
enccrd = crd1;
#ifdef CRYPTO_LZS_COMP
} else if (crd1->crd_alg == CRYPTO_LZS_COMP) {
- return (hifn_compression(sc, crp, cmd));
+ err = hifn_compression(sc, crp, cmd);
+ mutex_spin_exit(&sc->sc_mtx);
+ return err;
#endif
} else {
err = EINVAL;
@@ -2358,6 +2389,7 @@
err = hifn_crypto(sc, cmd, crp, hint);
if (err == 0) {
+ mutex_exit(&sc->sc_mtx);
return 0;
} else if (err == ERESTART) {
/*
@@ -2376,16 +2408,19 @@
}
errout:
- if (cmd != NULL) {
- explicit_memset(cmd, 0, sizeof(*cmd));
- free(cmd, M_DEVBUF);
- }
if (err == EINVAL)
hifnstats.hst_invalid++;
else
hifnstats.hst_nomem++;
crp->crp_etype = err;
mutex_spin_exit(&sc->sc_mtx);
+ if (cmd != NULL) {
+ if (crp->crp_flags & CRYPTO_F_IMBUF &&
+ cmd->srcu.src_m != cmd->dstu.dst_m)
+ m_freem(cmd->dstu.dst_m);
+ cmd->dst_map = NULL;
+ pool_cache_put(sc->sc_cmd_cache, cmd);
+ }
crypto_done(crp);
return (0);
}
@@ -2398,6 +2433,8 @@
struct cryptop *crp;
int i, u;
+ KASSERT(mutex_owned(&sc->sc_mtx));
+
i = dma->resk; u = dma->resu;
while (u != 0) {
cmd = dma->hifn_commands[i];
@@ -2436,15 +2473,14 @@
*/
crp->crp_etype = ENOMEM;
bus_dmamap_unload(sc->sc_dmat, cmd->dst_map);
- bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map);
} else
crp->crp_etype = ENOMEM;
bus_dmamap_unload(sc->sc_dmat, cmd->src_map);
- bus_dmamap_destroy(sc->sc_dmat, cmd->src_map);
-
- explicit_memset(cmd, 0, sizeof(*cmd));
- free(cmd, M_DEVBUF);
+
+ cmd->dst_map = NULL;
+ pool_cache_put(sc->sc_cmd_cache, cmd);
+
if (crp->crp_etype != EAGAIN)
crypto_done(crp);
}
@@ -2469,6 +2505,8 @@
struct mbuf *m;
int totlen, i, u;
+ KASSERT(mutex_owned(&sc->sc_mtx));
+
if (cmd->src_map == cmd->dst_map)
bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
0, cmd->src_map->dm_mapsize,
@@ -2559,14 +2597,11 @@
}
}
- if (cmd->src_map != cmd->dst_map) {
+ if (cmd->src_map != cmd->dst_map)
bus_dmamap_unload(sc->sc_dmat, cmd->dst_map);
- bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map);
- }
bus_dmamap_unload(sc->sc_dmat, cmd->src_map);
- bus_dmamap_destroy(sc->sc_dmat, cmd->src_map);
- explicit_memset(cmd, 0, sizeof(*cmd));
- free(cmd, M_DEVBUF);
+ cmd->dst_map = NULL;
+ pool_cache_put(sc->sc_cmd_cache, cmd);
crypto_done(crp);
Home |
Main Index |
Thread Index |
Old Index