diff options
author | netchild <netchild@FreeBSD.org> | 2005-09-12 18:33:33 +0000 |
---|---|---|
committer | netchild <netchild@FreeBSD.org> | 2005-09-12 18:33:33 +0000 |
commit | 9986ff6dc192f2b7a031943daf01139ea74f4d1d (patch) | |
tree | 31195ae88d1b4049061078a3fa7b05207f81f4ea | |
parent | 491de3e2d267a2069dd39a8fdabdd3beb3135507 (diff) | |
download | FreeBSD-src-9986ff6dc192f2b7a031943daf01139ea74f4d1d.zip FreeBSD-src-9986ff6dc192f2b7a031943daf01139ea74f4d1d.tar.gz |
- Fix the locking in dsp.c to prevent a LOR (AFAIK not on the LOR page).
- Remove an assertion in sound.c, it's not needed (and causes a panic now).
From the conversation via mail between glebius and Ariff:
---snip---
> Well, but which mutex protects now? Do we own anything else
> in pcm_chnalloc()? I see some queue(4) macros in pcm_chnalloc(),
> they should be protected, shouldn't they?
Queue insertion/removal occur during
1) driver loading (which is pretty much single thread /
sequential) or unloading (mutex protected, bail out if there is
any channel with refcount > 0 or busy).
2) vchan_create()/destroy(), (which is *sigh* quite complicated), but
somehow protected by 'master'/parent channel mutex. Other
thread cannot add/remove vchan (or even continue traversing
that queue) unless it can acquire parent channel mutex.
---snip---
Fix the locking in dsp.c to prevent a LOR (AFAIK not on the LOR page).
Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my>
Tested with: INVARIANTS[1] and DIAGNOSTICS[2]
Tested by: netchild [1,2], David Reid <david@jetnet.co.uk> [1]
-rw-r--r-- | sys/dev/sound/pcm/dsp.c | 6 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sound.c | 2 |
2 files changed, 3 insertions, 5 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index b10e5bd..46d9602 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -329,7 +329,6 @@ dsp_close(struct cdev *i_dev, int flags, int mode, struct thread *td) s = spltty(); d = dsp_get_info(i_dev); - pcm_lock(d); rdch = i_dev->si_drv1; wrch = i_dev->si_drv2; @@ -351,6 +350,8 @@ dsp_close(struct cdev *i_dev, int flags, int mode, struct thread *td) */ if ((rdch || wrch) && refs == 0) { + pcm_lock(d); + if (pcm_getfakechan(d)) pcm_getfakechan(d)->flags = 0; @@ -382,8 +383,7 @@ dsp_close(struct cdev *i_dev, int flags, int mode, struct thread *td) chn_reset(wrch, 0); pcm_chnrelease(wrch); } - } else - pcm_unlock(d); + } splx(s); return 0; } diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index dbeda1d..a5ce1d3 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -166,8 +166,6 @@ pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid, int chnum) struct snddev_channel *sce; int err; - snd_mtxassert(d->lock); - /* scan for a free channel */ SLIST_FOREACH(sce, &d->channels, link) { c = sce->channel; |