Module Name: src Committed By: riastradh Date: Mon Jun 14 10:14:01 UTC 2021
Modified Files: src/sys/dev/pad: pad.c padvar.h Log Message: pad(4): Fix some locking. - No need for sc_cond_lock. - Issue cv_broadcast under the correct lock. - Use callout_halt, not haphazard callout_stop. - IPL_SOFTCLOCK for a mutex taken from a callout. To generate a diff of this commit: cvs rdiff -u -r1.68 -r1.69 src/sys/dev/pad/pad.c cvs rdiff -u -r1.13 -r1.14 src/sys/dev/pad/padvar.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/pad/pad.c diff -u src/sys/dev/pad/pad.c:1.68 src/sys/dev/pad/pad.c:1.69 --- src/sys/dev/pad/pad.c:1.68 Mon Jun 14 00:21:09 2021 +++ src/sys/dev/pad/pad.c Mon Jun 14 10:14:01 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pad.c,v 1.68 2021/06/14 00:21:09 riastradh Exp $ */ +/* $NetBSD: pad.c,v 1.69 2021/06/14 10:14:01 riastradh Exp $ */ /*- * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.68 2021/06/14 00:21:09 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.69 2021/06/14 10:14:01 riastradh Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -223,13 +223,12 @@ pad_attach(device_t parent, device_t sel aprint_normal_dev(self, "outputs: 44100Hz, 16-bit, stereo\n"); sc->sc_dev = self; - sc->sc_dying = false; cv_init(&sc->sc_condvar, device_xname(sc->sc_dev)); - mutex_init(&sc->sc_cond_lock, MUTEX_DEFAULT, IPL_NONE); mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NONE); - callout_init(&sc->sc_pcallout, 0/*XXX?*/); + mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SOFTCLOCK); + callout_init(&sc->sc_pcallout, CALLOUT_MPSAFE); + callout_setfunc(&sc->sc_pcallout, pad_done_output, sc); sc->sc_swvol = 255; sc->sc_buflen = 0; @@ -258,7 +257,6 @@ pad_detach(device_t self, int flags) pmf_device_deregister(sc->sc_dev); - mutex_destroy(&sc->sc_cond_lock); mutex_destroy(&sc->sc_lock); mutex_destroy(&sc->sc_intr_lock); cv_destroy(&sc->sc_condvar); @@ -514,12 +512,12 @@ pad_read(struct pad_softc *sc, off_t *of err = 0; DPRINTF("%s: resid=%zu\n", __func__, uio->uio_resid); while (uio->uio_resid > 0 && !err) { - mutex_enter(&sc->sc_cond_lock); + mutex_enter(&sc->sc_intr_lock); if (sc->sc_buflen == 0) { DPRINTF("%s: wait\n", __func__); - err = cv_wait_sig(&sc->sc_condvar, &sc->sc_cond_lock); + err = cv_wait_sig(&sc->sc_condvar, &sc->sc_intr_lock); DPRINTF("%s: wake up %d\n", __func__, err); - mutex_exit(&sc->sc_cond_lock); + mutex_exit(&sc->sc_intr_lock); if (err) { if (err == ERESTART) err = EINTR; @@ -532,7 +530,7 @@ pad_read(struct pad_softc *sc, off_t *of len = uimin(uio->uio_resid, sc->sc_buflen); err = pad_get_block(sc, &pb, len); - mutex_exit(&sc->sc_cond_lock); + mutex_exit(&sc->sc_intr_lock); if (err) break; DPRINTF("%s: move %d\n", __func__, pb.pb_len); @@ -562,9 +560,7 @@ pad_set_format(void *opaque, int setmode const audio_params_t *play, const audio_params_t *rec, audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) { - struct pad_softc *sc; - - sc = (struct pad_softc *)opaque; + struct pad_softc *sc = opaque; KASSERT(mutex_owned(&sc->sc_lock)); @@ -579,12 +575,10 @@ static int pad_start_output(void *opaque, void *block, int blksize, void (*intr)(void *), void *intrarg) { - struct pad_softc *sc; + struct pad_softc *sc = opaque; int err; int ms; - sc = (struct pad_softc *)opaque; - KASSERT(mutex_owned(&sc->sc_intr_lock)); sc->sc_intr = intr; @@ -592,14 +586,12 @@ pad_start_output(void *opaque, void *blo sc->sc_blksize = blksize; DPRINTF("%s: blksize=%d\n", __func__, blksize); - mutex_enter(&sc->sc_cond_lock); err = pad_add_block(sc, block, blksize); - mutex_exit(&sc->sc_cond_lock); cv_broadcast(&sc->sc_condvar); ms = blksize * 1000 / PADCHAN / (PADPREC / NBBY) / PADFREQ; DPRINTF("%s: callout ms=%d\n", __func__, ms); - callout_reset(&sc->sc_pcallout, mstohz(ms), pad_done_output, sc); + callout_schedule(&sc->sc_pcallout, mstohz(ms)); return err; } @@ -607,19 +599,18 @@ pad_start_output(void *opaque, void *blo static int pad_halt_output(void *opaque) { - struct pad_softc *sc; - - sc = (struct pad_softc *)opaque; + struct pad_softc *sc = opaque; DPRINTF("%s\n", __func__); KASSERT(mutex_owned(&sc->sc_intr_lock)); - cv_broadcast(&sc->sc_condvar); - callout_stop(&sc->sc_pcallout); + callout_halt(&sc->sc_pcallout, &sc->sc_intr_lock); + sc->sc_intr = NULL; sc->sc_intrarg = NULL; sc->sc_buflen = 0; sc->sc_rpos = sc->sc_wpos = 0; + cv_broadcast(&sc->sc_condvar); return 0; } @@ -627,11 +618,9 @@ pad_halt_output(void *opaque) static void pad_done_output(void *arg) { - struct pad_softc *sc; + struct pad_softc *sc = arg; DPRINTF("%s\n", __func__); - sc = (struct pad_softc *)arg; - callout_stop(&sc->sc_pcallout); mutex_enter(&sc->sc_intr_lock); (*sc->sc_intr)(sc->sc_intrarg); @@ -652,9 +641,7 @@ pad_getdev(void *opaque, struct audio_de static int pad_set_port(void *opaque, mixer_ctrl_t *mc) { - struct pad_softc *sc; - - sc = (struct pad_softc *)opaque; + struct pad_softc *sc = opaque; KASSERT(mutex_owned(&sc->sc_lock)); @@ -673,9 +660,7 @@ pad_set_port(void *opaque, mixer_ctrl_t static int pad_get_port(void *opaque, mixer_ctrl_t *mc) { - struct pad_softc *sc; - - sc = (struct pad_softc *)opaque; + struct pad_softc *sc = opaque; KASSERT(mutex_owned(&sc->sc_lock)); @@ -694,9 +679,7 @@ pad_get_port(void *opaque, mixer_ctrl_t static int pad_query_devinfo(void *opaque, mixer_devinfo_t *di) { - struct pad_softc *sc __diagused; - - sc = (struct pad_softc *)opaque; + struct pad_softc *sc __diagused = opaque; KASSERT(mutex_owned(&sc->sc_lock)); @@ -744,9 +727,7 @@ pad_get_props(void *opaque) static void pad_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread) { - struct pad_softc *sc; - - sc = (struct pad_softc *)opaque; + struct pad_softc *sc = opaque; *intr = &sc->sc_intr_lock; *thread = &sc->sc_lock; Index: src/sys/dev/pad/padvar.h diff -u src/sys/dev/pad/padvar.h:1.13 src/sys/dev/pad/padvar.h:1.14 --- src/sys/dev/pad/padvar.h:1.13 Wed Jun 26 11:53:15 2019 +++ src/sys/dev/pad/padvar.h Mon Jun 14 10:14:01 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: padvar.h,v 1.13 2019/06/26 11:53:15 isaki Exp $ */ +/* $NetBSD: padvar.h,v 1.14 2021/06/14 10:14:01 riastradh Exp $ */ /*- * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca> @@ -39,9 +39,7 @@ struct pad_softc { kcondvar_t sc_condvar; kmutex_t sc_lock; kmutex_t sc_intr_lock; - kmutex_t sc_cond_lock; callout_t sc_pcallout; - bool sc_dying; device_t sc_audiodev; int sc_blksize;