From owner-freebsd-bugs Mon Oct 22 2:50:10 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id E256F37B40C for ; Mon, 22 Oct 2001 02:50:02 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.4/8.11.4) id f9M9o2A27170; Mon, 22 Oct 2001 02:50:02 -0700 (PDT) (envelope-from gnats) Date: Mon, 22 Oct 2001 02:50:02 -0700 (PDT) Message-Id: <200110220950.f9M9o2A27170@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Daniel Pouzzner Subject: Re: kern/31429: kernel resource deadlock on /dev/dsp Reply-To: Daniel Pouzzner Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org The following reply was made to PR kern/31429; it has been noted by GNATS. From: Daniel Pouzzner To: freebsd-gnats-submit@FreeBSD.org Cc: Subject: Re: kern/31429: kernel resource deadlock on /dev/dsp Date: Mon, 22 Oct 2001 05:47:26 -0400 (EDT) My original submission of half an hour ago was rather flawed, in two respects: (1) apparently, it doesn't matter if the dsp was opened WRONLY or RDWR - a subsequent RDONLY open results in EBUSY either way. (2) my fix was profoundly bogus, in particular causing a kernel hang on reboot (probably due to some other resource deadlock introduced by the code). Here is a much cleaner fix that seems to actually work all-around. The changes are that d->arec[chan] is updated immediately after the allocation, before the pointer can get lost, and the last EBUSY return in the FWRITE section includes the same un-busying code as the one before it. I'm not sufficiently familiar with the subsystem to know if it's important to update d->arec[chan] scrupulously (as I have it doing now), but it doesn't hurt anything apparently. int dsp_open(snddev_info *d, int chan, int oflags, int devtype) { pcm_channel *rdch, *wrch; u_int32_t fmt; 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; d->arec[chan] = rdch; } 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; return EBUSY; } } else { if (rdch && (oflags & FREAD)) rdch->flags &= ~CHN_F_BUSY; return EBUSY; } } d->atype[chan] = devtype; d->aplay[chan] = wrch; d->ref[chan]++; switch (devtype) { [...] To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message