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 {

Reply via email to