Module Name: src Committed By: jdolecek Date: Sat Oct 22 22:32:33 UTC 2016
Modified Files: src/sys/dev: dksubr.c dkvar.h Log Message: change sc_deferred to TAILQ (reusing bufq b_actq) to avoid possible buf leak for MPSAFE drivers To generate a diff of this commit: cvs rdiff -u -r1.89 -r1.90 src/sys/dev/dksubr.c cvs rdiff -u -r1.25 -r1.26 src/sys/dev/dkvar.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/dksubr.c diff -u src/sys/dev/dksubr.c:1.89 src/sys/dev/dksubr.c:1.90 --- src/sys/dev/dksubr.c:1.89 Wed Sep 14 23:05:05 2016 +++ src/sys/dev/dksubr.c Sat Oct 22 22:32:33 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: dksubr.c,v 1.89 2016/09/14 23:05:05 mlelstv Exp $ */ +/* $NetBSD: dksubr.c,v 1.90 2016/10/22 22:32:33 jdolecek Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 1999, 2002, 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.89 2016/09/14 23:05:05 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.90 2016/10/22 22:32:33 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -105,6 +105,8 @@ dk_attach(struct dk_softc *dksc) /* Attach the device into the rnd source list. */ rnd_attach_source(&dksc->sc_rnd_source, dksc->sc_xname, RND_TYPE_DISK, RND_FLAG_DEFAULT); + + TAILQ_INIT(&dksc->sc_deferred); } void @@ -378,25 +380,27 @@ dk_start(struct dk_softc *dksc, struct b * * So when a diskstart fails, the buffer is saved * and tried again before the next buffer is fetched. - * dk_drain() handles flushing of a saved buffer. + * dk_drain() handles flushing of a saved buffer(s). * * This keeps order of I/O operations, unlike bufq_put. */ - bp = dksc->sc_deferred; - dksc->sc_deferred = NULL; - - if (bp == NULL) - bp = bufq_get(dksc->sc_bufq); - - while (bp != NULL) { + for(;;) { + bp = TAILQ_FIRST(&dksc->sc_deferred); + if (__predict_false(bp != NULL)) + TAILQ_REMOVE(&dksc->sc_deferred, bp, b_actq); + else { + bp = bufq_get(dksc->sc_bufq); + if (bp == NULL) + break; + } disk_busy(&dksc->sc_dkdev); mutex_exit(&dksc->sc_iolock); error = dkd->d_diskstart(dksc->sc_dev, bp); mutex_enter(&dksc->sc_iolock); if (error == EAGAIN) { - dksc->sc_deferred = bp; + TAILQ_INSERT_TAIL(&dksc->sc_deferred, bp, b_actq); disk_unbusy(&dksc->sc_dkdev, 0, (bp->b_flags & B_READ)); break; } @@ -406,8 +410,6 @@ dk_start(struct dk_softc *dksc, struct b bp->b_resid = bp->b_bcount; dk_done1(dksc, bp, false); } - - bp = bufq_get(dksc->sc_bufq); } dksc->sc_busy = false; @@ -451,9 +453,8 @@ dk_drain(struct dk_softc *dksc) struct buf *bp; mutex_enter(&dksc->sc_iolock); - bp = dksc->sc_deferred; - dksc->sc_deferred = NULL; - if (bp != NULL) { + while ((bp = TAILQ_FIRST(&dksc->sc_deferred)) != NULL) { + TAILQ_REMOVE(&dksc->sc_deferred, bp, b_actq); bp->b_error = EIO; bp->b_resid = bp->b_bcount; biodone(bp); Index: src/sys/dev/dkvar.h diff -u src/sys/dev/dkvar.h:1.25 src/sys/dev/dkvar.h:1.26 --- src/sys/dev/dkvar.h:1.25 Mon Dec 21 12:33:12 2015 +++ src/sys/dev/dkvar.h Sat Oct 22 22:32:33 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: dkvar.h,v 1.25 2015/12/21 12:33:12 mlelstv Exp $ */ +/* $NetBSD: dkvar.h,v 1.26 2016/10/22 22:32:33 jdolecek Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -49,7 +49,7 @@ struct dk_softc { kmutex_t sc_iolock; /* protects buffer queue */ struct bufq_state *sc_bufq; /* buffer queue */ int sc_dtype; /* disk type */ - struct buf *sc_deferred; /* retry after start failed */ + TAILQ_HEAD(, buf) sc_deferred; /* retry after start failed */ bool sc_busy; /* processing buffers */ krndsource_t sc_rnd_source; /* entropy source */ };