From ce592a3df82cd1f94a02d624dfcfe4a07b5a5966 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Tue, 11 Jul 2023 23:20:24 +0000 Subject: [PATCH] dksubr(9): Avoid holding lock across rnd_add_uint32. Works around a problem where entering entropy sometimes takes the global entropy lock, which is at IPL_SOFTSERIAL. We should also address this by using the interrupt-like path instead, which might drop samples and schedule a softint, but never takes the global entropy lock, but this is a quick stop-gap to address immediate problems that multiple people have suddenly started seeing (though it's unclear to me why the problems didn't turn up a year ago). --- sys/dev/dksubr.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/sys/dev/dksubr.c b/sys/dev/dksubr.c index 2de7159a3c7f..2c544c726bef 100644 --- a/sys/dev/dksubr.c +++ b/sys/dev/dksubr.c @@ -77,7 +77,6 @@ static int dk_subr_modcmd(modcmd_t, void *); static void dk_makedisklabel(struct dk_softc *); static int dk_translate(struct dk_softc *, struct buf *); -static void dk_done1(struct dk_softc *, struct buf *, bool); void dk_init(struct dk_softc *dksc, device_t dev, int dtype) @@ -442,7 +441,9 @@ dk_start(struct dk_softc *dksc, struct buf *bp) if (error != 0) { bp->b_error = error; bp->b_resid = bp->b_bcount; - dk_done1(dksc, bp, false); + mutex_exit(&dksc->sc_iolock); + dk_done(dksc, bp); + mutex_enter(&dksc->sc_iolock); } bp = bufq_get(dksc->sc_bufq); @@ -454,8 +455,8 @@ done: mutex_exit(&dksc->sc_iolock); } -static void -dk_done1(struct dk_softc *dksc, struct buf *bp, bool lock) +void +dk_done(struct dk_softc *dksc, struct buf *bp) { struct disk *dk = &dksc->sc_dkdev; @@ -467,24 +468,16 @@ dk_done1(struct dk_softc *dksc, struct buf *bp, bool lock) printf("\n"); } - if (lock) - mutex_enter(&dksc->sc_iolock); + mutex_enter(&dksc->sc_iolock); disk_unbusy(dk, bp->b_bcount - bp->b_resid, (bp->b_flags & B_READ)); + mutex_exit(&dksc->sc_iolock); if ((dksc->sc_flags & DKF_NO_RND) == 0) rnd_add_uint32(&dksc->sc_rnd_source, bp->b_rawblkno); - if (lock) - mutex_exit(&dksc->sc_iolock); biodone(bp); } -void -dk_done(struct dk_softc *dksc, struct buf *bp) -{ - dk_done1(dksc, bp, true); -} - void dk_drain(struct dk_softc *dksc) {