Module Name: src Committed By: bad Date: Fri Apr 18 22:25:58 UTC 2014
Modified Files: src/sys/dev/pci: ubsec.c ubsecvar.h Log Message: Rewrite the dmamap handling to allocate and cache the dmamaps beforehand. Calling bus_dmamap_create/destroy is no longer possible in interrupt context. Move the dmamaps to the end of struct ubsec_q so the rest of the struct can be cleared with one call to memset(). As a bonus we get a 25% increase in throughput encrypting 8K blocks. To generate a diff of this commit: cvs rdiff -u -r1.38 -r1.39 src/sys/dev/pci/ubsec.c cvs rdiff -u -r1.7 -r1.8 src/sys/dev/pci/ubsecvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/ubsec.c diff -u src/sys/dev/pci/ubsec.c:1.38 src/sys/dev/pci/ubsec.c:1.39 --- src/sys/dev/pci/ubsec.c:1.38 Sat Mar 29 19:28:25 2014 +++ src/sys/dev/pci/ubsec.c Fri Apr 18 22:25:58 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ubsec.c,v 1.38 2014/03/29 19:28:25 christos Exp $ */ +/* $NetBSD: ubsec.c,v 1.39 2014/04/18 22:25:58 bad Exp $ */ /* $FreeBSD: src/sys/dev/ubsec/ubsec.c,v 1.6.2.6 2003/01/23 21:06:43 sam Exp $ */ /* $OpenBSD: ubsec.c,v 1.127 2003/06/04 14:04:58 jason Exp $ */ @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.38 2014/03/29 19:28:25 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.39 2014/04/18 22:25:58 bad Exp $"); #undef UBSEC_DEBUG @@ -435,7 +435,7 @@ ubsec_attach(device_t parent, device_t s struct ubsec_q *q; q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q), - M_DEVBUF, M_NOWAIT); + M_DEVBUF, M_ZERO|M_NOWAIT); if (q == NULL) { aprint_error_dev(self, "can't allocate queue buffers\n"); break; @@ -575,6 +575,10 @@ ubsec_detach(device_t self, int flags) SIMPLEQ_FOREACH_SAFE(q, &sc->sc_freequeue, q_next, qtmp) { ubsec_dma_free(sc, &q->q_dma->d_alloc); + if (q->q_src_map != NULL) + bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); + if (q->q_cached_dst_map != NULL) + bus_dmamap_destroy(sc->sc_dmat, q->q_cached_dst_map); free(q, M_DEVBUF); } @@ -1198,7 +1202,8 @@ ubsec_process(void *arg, struct cryptop mutex_spin_exit(&sc->sc_mtx); dmap = q->q_dma; /* Save dma pointer */ - memset(q, 0, sizeof(struct ubsec_q)); + /* don't lose the cached dmamaps q_src_map and q_cached_dst_map */ + memset(q, 0, offsetof(struct ubsec_q, q_src_map)); memset(&ctx, 0, sizeof(ctx)); q->q_sesn = UBSEC_SESSION(crp->crp_sid); @@ -1378,17 +1383,17 @@ ubsec_process(void *arg, struct cryptop } ctx.pc_offset = htole16(coffset >> 2); - /* XXX FIXME: jonathan asks, what the heck's that 0xfff0? */ - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, UBS_MAX_SCATTER, - 0xfff0, 0, BUS_DMA_NOWAIT, &q->q_src_map) != 0) { - err = ENOMEM; - goto errout; + if (q->q_src_map == NULL) { + /* XXX FIXME: jonathan asks, what the heck's that 0xfff0? */ + if (bus_dmamap_create(sc->sc_dmat, 0xfff0, UBS_MAX_SCATTER, + 0xfff0, 0, BUS_DMA_NOWAIT, &q->q_src_map) != 0) { + err = ENOMEM; + goto errout; + } } if (crp->crp_flags & CRYPTO_F_IMBUF) { if (bus_dmamap_load_mbuf(sc->sc_dmat, q->q_src_map, q->q_src_m, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - q->q_src_map = NULL; ubsecstats.hst_noload++; err = ENOMEM; goto errout; @@ -1396,8 +1401,6 @@ ubsec_process(void *arg, struct cryptop } else if (crp->crp_flags & CRYPTO_F_IOV) { if (bus_dmamap_load_uio(sc->sc_dmat, q->q_src_map, q->q_src_io, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - q->q_src_map = NULL; ubsecstats.hst_noload++; err = ENOMEM; goto errout; @@ -1476,18 +1479,21 @@ ubsec_process(void *arg, struct cryptop err = EINVAL; goto errout; } - /* XXX: ``what the heck's that'' 0xfff0? */ - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, - UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, - &q->q_dst_map) != 0) { - ubsecstats.hst_nomap++; - err = ENOMEM; - goto errout; + if (q->q_dst_map == NULL) { + if (q->q_cached_dst_map == NULL) { + /* XXX: ``what the heck's that'' 0xfff0? */ + if (bus_dmamap_create(sc->sc_dmat, 0xfff0, + UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, + &q->q_cached_dst_map) != 0) { + ubsecstats.hst_nomap++; + err = ENOMEM; + goto errout; + } + } + q->q_dst_map = q->q_cached_dst_map; } if (bus_dmamap_load_uio(sc->sc_dmat, q->q_dst_map, q->q_dst_io, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); - q->q_dst_map = NULL; ubsecstats.hst_noload++; err = ENOMEM; goto errout; @@ -1566,20 +1572,22 @@ ubsec_process(void *arg, struct cryptop q->q_dst_m = top; ubsec_mcopy(q->q_src_m, q->q_dst_m, cpskip, cpoffset); - /* XXX again, what the heck is that 0xfff0? */ - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, - UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, - &q->q_dst_map) != 0) { - ubsecstats.hst_nomap++; - err = ENOMEM; - goto errout; + if (q->q_dst_map == NULL) { + if (q->q_cached_dst_map == NULL) { + /* XXX again, what the heck is that 0xfff0? */ + if (bus_dmamap_create(sc->sc_dmat, 0xfff0, + UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, + &q->q_cached_dst_map) != 0) { + ubsecstats.hst_nomap++; + err = ENOMEM; + goto errout; + } + } + q->q_dst_map = q->q_cached_dst_map; } if (bus_dmamap_load_mbuf(sc->sc_dmat, q->q_dst_map, q->q_dst_m, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - q->q_dst_map); - q->q_dst_map = NULL; ubsecstats.hst_noload++; err = ENOMEM; goto errout; @@ -1689,11 +1697,9 @@ errout: if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) { bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); } if (q->q_src_map != NULL) { bus_dmamap_unload(sc->sc_dmat, q->q_src_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); } mutex_spin_enter(&sc->sc_mtx); @@ -1732,12 +1738,10 @@ ubsec_callback(struct ubsec_softc *sc, s bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); } bus_dmamap_sync(sc->sc_dmat, q->q_src_map, 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, q->q_src_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); if ((crp->crp_flags & CRYPTO_F_IMBUF) && (q->q_src_m != q->q_dst_m)) { m_freem(q->q_src_m); Index: src/sys/dev/pci/ubsecvar.h diff -u src/sys/dev/pci/ubsecvar.h:1.7 src/sys/dev/pci/ubsecvar.h:1.8 --- src/sys/dev/pci/ubsecvar.h:1.7 Sun Nov 17 23:20:18 2013 +++ src/sys/dev/pci/ubsecvar.h Fri Apr 18 22:25:58 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ubsecvar.h,v 1.7 2013/11/17 23:20:18 bad Exp $ */ +/* $NetBSD: ubsecvar.h,v 1.8 2014/04/18 22:25:58 bad Exp $ */ /* $OpenBSD: ubsecvar.h,v 1.36 2003/06/04 16:02:41 jason Exp $ */ /* @@ -146,11 +146,12 @@ struct ubsec_q { struct mbuf *q_src_m, *q_dst_m; struct uio *q_src_io, *q_dst_io; - bus_dmamap_t q_src_map; - bus_dmamap_t q_dst_map; - int q_sesn; int q_flags; + + bus_dmamap_t q_dst_map; + bus_dmamap_t q_src_map; /* cached src_map */ + bus_dmamap_t q_cached_dst_map; /* cached dst_map */ }; struct ubsec_softc {