Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-9]: src/sys/dev/audio Pull up following revision(s) (requested by...
details: https://anonhg.NetBSD.org/src/rev/a6c53351f73d
branches: netbsd-9
changeset: 953219:a6c53351f73d
user: martin <martin%NetBSD.org@localhost>
date: Mon Mar 01 16:00:08 2021 +0000
description:
Pull up following revision(s) (requested by isaki in ticket #1219):
sys/dev/audio/audio.c: revision 1.89
sys/dev/audio/audio.c: revision 1.90
sys/dev/audio/audio.c: revision 1.91
Change the lock conditions to call audio_unlink().
This can remove a different copy of audio_exlock_enter() in audio_unlink()
and can use normal one. Also, in audiodetach(), this can set the exlock
at more natual order (before calling audio_unlink()).
No noticeable functional changes are intended.
Thanks for comments, riastradh@.
Protect also audioopen() and audiobellopen() from audiodetach() with
psref(9), as well as others(audioread, audiowrite, etc..).
- Rename audio_file_enter to audio_sc_acquire_fromfile, audio_file_exit
to audio_sc_release, for clarify. These are the reference counter for
this sc.
- Introduce audio_sc_acquire_foropen for audio{,bell}open.
- audio_open needs to examine sc_dying again before inserting it into
sc_files, in order to keep sc_files consistency.
The race between audiodetach and audioopen is pointed out by riastradh@.
Thank you for many advices.
Add missing curlwp_bindx() corresponding to curlwp_bind().
Pointed out by riastradh@.
diffstat:
sys/dev/audio/audio.c | 339 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 235 insertions(+), 104 deletions(-)
diffs (truncated from 717 to 300 lines):
diff -r ee6a11ec6c22 -r a6c53351f73d sys/dev/audio/audio.c
--- a/sys/dev/audio/audio.c Sun Feb 28 07:09:00 2021 +0000
+++ b/sys/dev/audio/audio.c Mon Mar 01 16:00:08 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: audio.c,v 1.28.2.20 2021/02/28 07:07:38 martin Exp $ */
+/* $NetBSD: audio.c,v 1.28.2.21 2021/03/01 16:00:08 martin Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -138,7 +138,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.20 2021/02/28 07:07:38 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.21 2021/03/01 16:00:08 martin Exp $");
#ifdef _KERNEL_OPT
#include "audio.h"
@@ -524,8 +524,10 @@
static void audio_exlock_mutex_exit(struct audio_softc *);
static int audio_exlock_enter(struct audio_softc *);
static void audio_exlock_exit(struct audio_softc *);
-static struct audio_softc *audio_file_enter(audio_file_t *, struct psref *);
-static void audio_file_exit(struct audio_softc *, struct psref *);
+static void audio_sc_acquire_foropen(struct audio_softc *, struct psref *);
+static struct audio_softc *audio_sc_acquire_fromfile(audio_file_t *,
+ struct psref *);
+static void audio_sc_release(struct audio_softc *, struct psref *);
static int audio_track_waitio(struct audio_softc *, audio_track_t *);
static int audioclose(struct file *);
@@ -1295,7 +1297,10 @@
if (error)
return error;
- /* delete sysctl nodes */
+ /*
+ * This waits currently running sysctls to finish if exists.
+ * After this, no more new sysctls will come.
+ */
sysctl_teardown(&sc->sc_log);
mutex_enter(sc->sc_lock);
@@ -1327,9 +1332,10 @@
* that hold sc, and any new calls with files that were for sc will
* fail. Thus, we now have exclusive access to the softc.
*/
+ sc->sc_exlock = 1;
/*
- * Nuke all open instances.
+ * Clean up all open instances.
* Here, we no longer need any locks to traverse sc_files.
*/
while ((file = SLIST_FIRST(&sc->sc_files)) != NULL) {
@@ -1352,7 +1358,6 @@
pmf_device_deregister(self);
/* Free resources */
- sc->sc_exlock = 1;
if (sc->sc_pmixer) {
audio_mixer_destroy(sc, sc->sc_pmixer);
kmem_free(sc->sc_pmixer, sizeof(*sc->sc_pmixer));
@@ -1524,18 +1529,41 @@
}
/*
- * Acquire sc from file, and increment the psref count.
+ * Increment reference counter for this sc.
+ * This is intended to be used for open.
+ */
+void
+audio_sc_acquire_foropen(struct audio_softc *sc, struct psref *refp)
+{
+ int s;
+
+ /* Block audiodetach while we acquire a reference */
+ s = pserialize_read_enter();
+
+ /*
+ * We don't examine sc_dying here. However, all open methods
+ * call audio_exlock_enter() right after this, so we can examine
+ * sc_dying in it.
+ */
+
+ /* Acquire a reference */
+ psref_acquire(refp, &sc->sc_psref, audio_psref_class);
+
+ /* Now sc won't go away until we drop the reference count */
+ pserialize_read_exit(s);
+}
+
+/*
+ * Get sc from file, and increment reference counter for this sc.
+ * This is intended to be used for methods other than open.
* If successful, returns sc. Otherwise returns NULL.
*/
struct audio_softc *
-audio_file_enter(audio_file_t *file, struct psref *refp)
+audio_sc_acquire_fromfile(audio_file_t *file, struct psref *refp)
{
int s;
bool dying;
- /* psref(9) forbids to migrate CPUs */
- curlwp_bind();
-
/* Block audiodetach while we acquire a reference */
s = pserialize_read_enter();
@@ -1556,10 +1584,10 @@
}
/*
- * Decrement the psref count.
+ * Decrement reference counter for this sc.
*/
void
-audio_file_exit(struct audio_softc *sc, struct psref *refp)
+audio_sc_release(struct audio_softc *sc, struct psref *refp)
{
psref_release(refp, &sc->sc_psref, audio_psref_class);
@@ -1637,6 +1665,8 @@
audioopen(dev_t dev, int flags, int ifmt, struct lwp *l)
{
struct audio_softc *sc;
+ struct psref sc_ref;
+ int bound;
int error;
/* Find the device */
@@ -1644,9 +1674,12 @@
if (sc == NULL || sc->hw_if == NULL)
return ENXIO;
+ bound = curlwp_bind();
+ audio_sc_acquire_foropen(sc, &sc_ref);
+
error = audio_exlock_enter(sc);
if (error)
- return error;
+ goto done;
device_active(sc->sc_dev, DVA_SYSTEM);
switch (AUDIODEV(dev)) {
@@ -1666,6 +1699,9 @@
}
audio_exlock_exit(sc);
+done:
+ audio_sc_release(sc, &sc_ref);
+ curlwp_bindx(bound);
return error;
}
@@ -1675,6 +1711,7 @@
struct audio_softc *sc;
struct psref sc_ref;
audio_file_t *file;
+ int bound;
int error;
dev_t dev;
@@ -1690,7 +1727,8 @@
* - free all memory objects, regardless of sc.
*/
- sc = audio_file_enter(file, &sc_ref);
+ bound = curlwp_bind();
+ sc = audio_sc_acquire_fromfile(file, &sc_ref);
if (sc) {
switch (AUDIODEV(dev)) {
case SOUND_DEVICE:
@@ -1708,8 +1746,9 @@
break;
}
- audio_file_exit(sc, &sc_ref);
- }
+ audio_sc_release(sc, &sc_ref);
+ }
+ curlwp_bindx(bound);
/* Free memory objects anyway */
TRACEF(2, file, "free memory");
@@ -1730,6 +1769,7 @@
struct audio_softc *sc;
struct psref sc_ref;
audio_file_t *file;
+ int bound;
int error;
dev_t dev;
@@ -1737,9 +1777,12 @@
file = fp->f_audioctx;
dev = file->dev;
- sc = audio_file_enter(file, &sc_ref);
- if (sc == NULL)
- return EIO;
+ bound = curlwp_bind();
+ sc = audio_sc_acquire_fromfile(file, &sc_ref);
+ if (sc == NULL) {
+ error = EIO;
+ goto done;
+ }
if (fp->f_flag & O_NONBLOCK)
ioflag |= IO_NDELAY;
@@ -1758,7 +1801,9 @@
break;
}
- audio_file_exit(sc, &sc_ref);
+ audio_sc_release(sc, &sc_ref);
+done:
+ curlwp_bindx(bound);
return error;
}
@@ -1769,6 +1814,7 @@
struct audio_softc *sc;
struct psref sc_ref;
audio_file_t *file;
+ int bound;
int error;
dev_t dev;
@@ -1776,9 +1822,12 @@
file = fp->f_audioctx;
dev = file->dev;
- sc = audio_file_enter(file, &sc_ref);
- if (sc == NULL)
- return EIO;
+ bound = curlwp_bind();
+ sc = audio_sc_acquire_fromfile(file, &sc_ref);
+ if (sc == NULL) {
+ error = EIO;
+ goto done;
+ }
if (fp->f_flag & O_NONBLOCK)
ioflag |= IO_NDELAY;
@@ -1797,7 +1846,9 @@
break;
}
- audio_file_exit(sc, &sc_ref);
+ audio_sc_release(sc, &sc_ref);
+done:
+ curlwp_bindx(bound);
return error;
}
@@ -1808,6 +1859,7 @@
struct psref sc_ref;
audio_file_t *file;
struct lwp *l = curlwp;
+ int bound;
int error;
dev_t dev;
@@ -1815,9 +1867,12 @@
file = fp->f_audioctx;
dev = file->dev;
- sc = audio_file_enter(file, &sc_ref);
- if (sc == NULL)
- return EIO;
+ bound = curlwp_bind();
+ sc = audio_sc_acquire_fromfile(file, &sc_ref);
+ if (sc == NULL) {
+ error = EIO;
+ goto done;
+ }
switch (AUDIODEV(dev)) {
case SOUND_DEVICE:
@@ -1840,7 +1895,9 @@
break;
}
- audio_file_exit(sc, &sc_ref);
+ audio_sc_release(sc, &sc_ref);
+done:
+ curlwp_bindx(bound);
return error;
}
@@ -1850,14 +1907,20 @@
struct audio_softc *sc;
struct psref sc_ref;
audio_file_t *file;
+ int bound;
+ int error;
KASSERT(fp->f_audioctx);
file = fp->f_audioctx;
Home |
Main Index |
Thread Index |
Old Index