Date: Mon, 22 Oct 2001 02:06:52 -0700 (PDT) From: Daniel Pouzzner <douzzer@mega.nu> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/31429: kernel resource deadlock on /dev/dsp Message-ID: <200110220906.f9M96qF22169@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 31429 >Category: kern >Synopsis: kernel resource deadlock on /dev/dsp >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Oct 22 02:10:00 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Daniel Pouzzner >Release: 4.3-REL >Organization: www.mega.nu >Environment: -* uname -a FreeBSD mega 4.3-RELEASE FreeBSD 4.3-RELEASE #9: Mon Oct 22 04:52:54 EDT 2001 douzzer@mega:/usr/src.4.3/sys/compile/MEGA i386 >Description: dsp_open() in sys/dev/sound/pcm/dsp.c fails to release or remember the read channel (rdch) if the subsequent wrch allocation craps out. This causes all subsequent attempts to allocate the rdch to fail, because it is already allocated (but the pointer was discarded). >How-To-Repeat: start sound playing with xmms or any other program that opens the dsp read-write. try to record sound (from the same dsp of course) - EBUSY results. stop sound playing. try record again. should work, but instead, more EBUSYs result. >Fix: I'm sure you can do a cleaner job, but I just wanted to get this fixed prontissimo: int dsp_open(snddev_info *d, int chan, int oflags, int devtype) { pcm_channel *rdch, *wrch; u_int32_t fmt; int gotrdchthiscall = 0; if (chan >= d->chancount) return ENODEV; if ((d->flags & SD_F_SIMPLEX) && (d->ref[chan] > 0)) return EBUSY; if (d->atype[chan] != 0 && d->atype[chan] != devtype) return EBUSY; rdch = d->arec[chan]; wrch = d->aplay[chan]; if (oflags & FREAD) { if (rdch == NULL) { rdch = allocchn(d, PCMDIR_REC); if (!rdch) return EBUSY; gotrdchthiscall = 1; } else return EBUSY; } if (oflags & FWRITE) { if (wrch == NULL) { wrch = allocchn(d, PCMDIR_PLAY); if (!wrch) { if (rdch && (oflags & FREAD)) rdch->flags &= ~CHN_F_BUSY; goto busyret; } } else goto busyret; goto nobusyret; busyret: /* must liberate the rdch if it we opened it this call */ if (gotrdchthiscall) { chn_abort(rdch); rdch->flags &= ~(CHN_F_BUSY | CHN_F_RUNNING | CHN_F_MAPPED | CHN_F_DEAD); chn_reset(rdch, 0); } return EBUSY; nobusyret: } [...] >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110220906.f9M96qF22169>