NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

re: kern/46232: netbsd-6 pad(4) panic: locking against myself



The following reply was made to PR kern/46232; it has been noted by GNATS.

From: matthew green <mrg%eterna.com.au@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: gnats-admin%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost,
    Matthew Mondor <mm_lists%pulsar-zone.net@localhost>
Subject: re: kern/46232: netbsd-6 pad(4) panic: locking against myself
Date: Mon, 26 Mar 2012 17:46:33 +1100

 could you please try this patch?  thanks.
 
 
 .mrg.
 
 
 Index: audio.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/audio.c,v
 retrieving revision 1.258
 diff -p -r1.258 audio.c
 *** audio.c    21 Feb 2012 20:53:34 -0000      1.258
 --- audio.c    26 Mar 2012 06:45:55 -0000
 *************** int    audio_initbufs(struct audio_softc *)
 *** 241,246 ****
 --- 241,247 ----
   void audio_calcwater(struct audio_softc *);
   int  audio_drain(struct audio_softc *);
   void audio_clear(struct audio_softc *);
 + void audio_clear_intr_unlocked(struct audio_softc *sc);
   static inline void audio_pint_silence
        (struct audio_softc *, struct audio_ringbuffer *, uint8_t *, int);
   
 *************** audio_clear(struct audio_softc *sc)
 *** 1992,1998 ****
   
        KASSERT(mutex_owned(sc->sc_lock));
   
 -      mutex_enter(sc->sc_intr_lock);
        if (sc->sc_rbus) {
                cv_broadcast(&sc->sc_rchan);
                sc->hw_if->halt_input(sc->hw_hdl);
 --- 1993,1998 ----
 *************** audio_clear(struct audio_softc *sc)
 *** 2005,2010 ****
 --- 2005,2018 ----
                sc->sc_pbus = false;
                sc->sc_pr.pause = false;
        }
 + }
 + 
 + void
 + audio_clear_intr_unlocked(struct audio_softc *sc)
 + {
 + 
 +      mutex_enter(sc->sc_intr_lock);
 +      audio_clear(sc);
        mutex_exit(sc->sc_intr_lock);
   }
   
 *************** audiosetinfo(struct audio_softc *sc, str
 *** 3643,3649 ****
        setmode = 0;
        if (nr > 0) {
                if (!cleared) {
 !                      audio_clear(sc);
                        cleared = true;
                }
                modechange = true;
 --- 3651,3657 ----
        setmode = 0;
        if (nr > 0) {
                if (!cleared) {
 !                      audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                modechange = true;
 *************** audiosetinfo(struct audio_softc *sc, str
 *** 3651,3657 ****
        }
        if (np > 0) {
                if (!cleared) {
 !                      audio_clear(sc);
                        cleared = true;
                }
                modechange = true;
 --- 3659,3665 ----
        }
        if (np > 0) {
                if (!cleared) {
 !                      audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                modechange = true;
 *************** audiosetinfo(struct audio_softc *sc, str
 *** 3660,3666 ****
   
        if (SPECIFIED(ai->mode)) {
                if (!cleared) {
 !                      audio_clear(sc);
                        cleared = true;
                }
                modechange = true;
 --- 3668,3674 ----
   
        if (SPECIFIED(ai->mode)) {
                if (!cleared) {
 !                      audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                modechange = true;
 *************** audiosetinfo(struct audio_softc *sc, str
 *** 3754,3760 ****
   
        if (SPECIFIED(p->port)) {
                if (!cleared) {
 !                      audio_clear(sc);
                        cleared = true;
                }
                error = au_set_port(sc, &sc->sc_outports, p->port);
 --- 3762,3768 ----
   
        if (SPECIFIED(p->port)) {
                if (!cleared) {
 !                      audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                error = au_set_port(sc, &sc->sc_outports, p->port);
 *************** audiosetinfo(struct audio_softc *sc, str
 *** 3763,3769 ****
        }
        if (SPECIFIED(r->port)) {
                if (!cleared) {
 !                      audio_clear(sc);
                        cleared = true;
                }
                error = au_set_port(sc, &sc->sc_inports, r->port);
 --- 3771,3777 ----
        }
        if (SPECIFIED(r->port)) {
                if (!cleared) {
 !                      audio_clear_intr_unlocked(sc);
                        cleared = true;
                }
                error = au_set_port(sc, &sc->sc_inports, r->port);
 *************** audiosetinfo(struct audio_softc *sc, str
 *** 3825,3831 ****
                /* Block size specified explicitly. */
                if (ai->blocksize == 0) {
                        if (!cleared) {
 !                              audio_clear(sc);
                                cleared = true;
                        }
                        sc->sc_blkset = false;
 --- 3833,3839 ----
                /* Block size specified explicitly. */
                if (ai->blocksize == 0) {
                        if (!cleared) {
 !                              audio_clear_intr_unlocked(sc);
                                cleared = true;
                        }
                        sc->sc_blkset = false;
 *************** audiosetinfo(struct audio_softc *sc, str
 *** 3836,3842 ****
                        /* check whether new blocksize changes actually */
                        if (hw->round_blocksize == NULL) {
                                if (!cleared) {
 !                                      audio_clear(sc);
                                        cleared = true;
                                }
                                sc->sc_pr.blksize = ai->blocksize;
 --- 3844,3850 ----
                        /* check whether new blocksize changes actually */
                        if (hw->round_blocksize == NULL) {
                                if (!cleared) {
 !                                      audio_clear_intr_unlocked(sc);
                                        cleared = true;
                                }
                                sc->sc_pr.blksize = ai->blocksize;
 *************** audiosetinfo(struct audio_softc *sc, str
 *** 3849,3855 ****
                                if (pblksize != sc->sc_pr.blksize ||
                                    rblksize != sc->sc_rr.blksize) {
                                        if (!cleared) {
 !                                              audio_clear(sc);
                                                cleared = true;
                                        }
                                        sc->sc_pr.blksize = ai->blocksize;
 --- 3857,3863 ----
                                if (pblksize != sc->sc_pr.blksize ||
                                    rblksize != sc->sc_rr.blksize) {
                                        if (!cleared) {
 !                                              audio_clear_intr_unlocked(sc);
                                                cleared = true;
                                        }
                                        sc->sc_pr.blksize = ai->blocksize;
 


Home | Main Index | Thread Index | Old Index