Re: git: 5317480967bf - main - sound: Remove CHN_F_SLEEPING
Date: Tue, 26 Nov 2024 18:32:14 UTC
On 11/26/24 06:48, Christos Margiolis wrote:
> The branch main has been updated by christos:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=5317480967bfc8bf678e4da3fce81bcb3f5b7836
>
> commit 5317480967bfc8bf678e4da3fce81bcb3f5b7836
> Author: Christos Margiolis <christos@FreeBSD.org>
> AuthorDate: 2024-11-26 14:48:36 +0000
> Commit: Christos Margiolis <christos@FreeBSD.org>
> CommitDate: 2024-11-26 14:48:36 +0000
>
> sound: Remove CHN_F_SLEEPING
>
> The KASSERT in chn_sleep() can be triggered if more than one thread
> wants to sleep on a given channel at the same time. While this is not
> really a common scenario, tools such as stress2, which use fork() and
> the child process(es) inherit the parent's FDs as a result, we can end
> up triggering such scenarios.
>
> Fix this by removing CHN_F_SLEEPING altogether, which is not very useful
> in the first place:
> - CHN_BROADCAST() checks cv_waiters already, so there is no need to
> check CHN_F_SLEEPING as well.
> - We can check whether cv_waiters is 0 in pcm_killchans(), instead of
> whether CHN_F_SLEEPING is not set.
>
> Reported by: dougm, pho (stress2)
> Sponsored by: The FreeBSD Foundation
> MFC after: 2 days
> Reviewed by: dev_submerge.ch, markj
> Differential Revision: https://reviews.freebsd.org/D47559
> ---
> sys/dev/sound/pcm/channel.c | 13 +------------
> sys/dev/sound/pcm/channel.h | 4 ++--
> sys/dev/sound/pcm/sound.c | 4 ++--
> 3 files changed, 5 insertions(+), 16 deletions(-)
>
> diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
> index 79a8d35b22f7..d226adfba06b 100644
> --- a/sys/dev/sound/pcm/channel.h
> +++ b/sys/dev/sound/pcm/channel.h
> @@ -354,7 +354,7 @@ enum {
> #define CHN_F_RUNNING 0x00000004 /* dma is running */
> #define CHN_F_TRIGGERED 0x00000008
> #define CHN_F_NOTRIGGER 0x00000010
> -#define CHN_F_SLEEPING 0x00000020
> +/* unused 0x00000020 */
>
> #define CHN_F_NBIO 0x00000040 /* do non-blocking i/o */
> #define CHN_F_MMAP 0x00000080 /* has been mmap()ed */
> @@ -381,8 +381,8 @@ enum {
> "\002ABORTING" \
> "\003RUNNING" \
> "\004TRIGGERED" \
> + /* \006 */ \
> "\005NOTRIGGER" \
> - "\006SLEEPING" \
> "\007NBIO" \
Hmm, new comment is mis-sorted?
> "\010MMAP" \
> "\011BUSY" \
> diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
> index 4b7bcc64397f..218147b73db0 100644
> --- a/sys/dev/sound/pcm/sound.c
> +++ b/sys/dev/sound/pcm/sound.c
> @@ -221,8 +221,8 @@ pcm_killchans(struct snddev_info *d)
> /* Make sure all channels are stopped. */
> CHN_FOREACH(ch, d, channels.pcm) {
> CHN_LOCK(ch);
> - if ((ch->flags & CHN_F_SLEEPING) == 0 &&
> - CHN_STOPPED(ch) && ch->inprog == 0) {
> + if (ch->intr_cv.cv_waiters == 0 && CHN_STOPPED(ch) &&
> + ch->inprog == 0) {
I'm not super excited about reading cv_waiters directly. Generally speaking
'struct cv' is opaque to the rest of the kernel. Maybe add a little inline
routine or macro cv_waiters() that returns this value instead? Then it can
be documented in condvar.9 along with the caveats about when it is safe to
use.
--
John Baldwin