Fix lock assertion on async I/O mode.
psignal() must be called without any spin locks. Thanks maxv@!
This commit is contained in:
parent
5dd22a92f0
commit
5b1ad8c026
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: audio.c,v 1.29 2019/08/23 09:41:26 maxv Exp $ */
|
/* $NetBSD: audio.c,v 1.30 2019/08/29 13:01:07 isaki Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||||
@ -142,7 +142,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.29 2019/08/23 09:41:26 maxv Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.30 2019/08/29 13:01:07 isaki Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
@ -5729,6 +5729,36 @@ audio_track_drain(struct audio_softc *sc, audio_track_t *track)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send signal to process.
|
||||||
|
* This is intended to be called only from audio_softintr_{rd,wr}.
|
||||||
|
* Must be called with sc_lock && sc_intr_lock held.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
audio_psignal(struct audio_softc *sc, pid_t pid, int signum)
|
||||||
|
{
|
||||||
|
proc_t *p;
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(sc->sc_lock));
|
||||||
|
KASSERT(mutex_owned(sc->sc_intr_lock));
|
||||||
|
KASSERT(pid != 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* psignal() must be called without spin lock held.
|
||||||
|
* So leave intr_lock temporarily here.
|
||||||
|
*/
|
||||||
|
mutex_exit(sc->sc_intr_lock);
|
||||||
|
|
||||||
|
mutex_enter(proc_lock);
|
||||||
|
p = proc_find(pid);
|
||||||
|
if (p)
|
||||||
|
psignal(p, signum);
|
||||||
|
mutex_exit(proc_lock);
|
||||||
|
|
||||||
|
/* Enter intr_lock again */
|
||||||
|
mutex_enter(sc->sc_intr_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is software interrupt handler for record.
|
* This is software interrupt handler for record.
|
||||||
* It is called from recording hardware interrupt everytime.
|
* It is called from recording hardware interrupt everytime.
|
||||||
@ -5747,7 +5777,6 @@ audio_softintr_rd(void *cookie)
|
|||||||
{
|
{
|
||||||
struct audio_softc *sc = cookie;
|
struct audio_softc *sc = cookie;
|
||||||
audio_file_t *f;
|
audio_file_t *f;
|
||||||
proc_t *p;
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
mutex_enter(sc->sc_lock);
|
mutex_enter(sc->sc_lock);
|
||||||
@ -5767,10 +5796,7 @@ audio_softintr_rd(void *cookie)
|
|||||||
pid = f->async_audio;
|
pid = f->async_audio;
|
||||||
if (pid != 0) {
|
if (pid != 0) {
|
||||||
TRACEF(4, f, "sending SIGIO %d", pid);
|
TRACEF(4, f, "sending SIGIO %d", pid);
|
||||||
mutex_enter(proc_lock);
|
audio_psignal(sc, pid, SIGIO);
|
||||||
if ((p = proc_find(pid)) != NULL)
|
|
||||||
psignal(p, SIGIO);
|
|
||||||
mutex_exit(proc_lock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_exit(sc->sc_intr_lock);
|
mutex_exit(sc->sc_intr_lock);
|
||||||
@ -5799,7 +5825,6 @@ audio_softintr_wr(void *cookie)
|
|||||||
struct audio_softc *sc = cookie;
|
struct audio_softc *sc = cookie;
|
||||||
audio_file_t *f;
|
audio_file_t *f;
|
||||||
bool found;
|
bool found;
|
||||||
proc_t *p;
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
TRACE(4, "called");
|
TRACE(4, "called");
|
||||||
@ -5826,14 +5851,13 @@ audio_softintr_wr(void *cookie)
|
|||||||
*/
|
*/
|
||||||
if (track->usrbuf.used <= track->usrbuf_usedlow &&
|
if (track->usrbuf.used <= track->usrbuf_usedlow &&
|
||||||
!track->is_pause) {
|
!track->is_pause) {
|
||||||
|
/* For selnotify */
|
||||||
found = true;
|
found = true;
|
||||||
|
/* For SIGIO */
|
||||||
pid = f->async_audio;
|
pid = f->async_audio;
|
||||||
if (pid != 0) {
|
if (pid != 0) {
|
||||||
TRACEF(4, f, "sending SIGIO %d", pid);
|
TRACEF(4, f, "sending SIGIO %d", pid);
|
||||||
mutex_enter(proc_lock);
|
audio_psignal(sc, pid, SIGIO);
|
||||||
if ((p = proc_find(pid)) != NULL)
|
|
||||||
psignal(p, SIGIO);
|
|
||||||
mutex_exit(proc_lock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: audiovar.h,v 1.4 2019/06/26 06:57:45 isaki Exp $ */
|
/* $NetBSD: audiovar.h,v 1.5 2019/08/29 13:01:07 isaki Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||||
@ -149,7 +149,8 @@ struct audio_softc {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* List of opened descriptors.
|
* List of opened descriptors.
|
||||||
* Must be protected by sc_intr_lock.
|
* Must be protected by sc_lock || sc_intr_lock for traversal(FOREACH).
|
||||||
|
* Must be protected by sc_lock && sc_intr_lock for insertion/removal.
|
||||||
*/
|
*/
|
||||||
SLIST_HEAD(, audio_file) sc_files;
|
SLIST_HEAD(, audio_file) sc_files;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user