NetBSD Problem Report #56947

From martin@aprisoft.de  Sat Jul 30 15:01:13 2022
Return-Path: <martin@aprisoft.de>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 065C21A9239
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 30 Jul 2022 15:01:13 +0000 (UTC)
Message-Id: <20220730150103.E368D5CC975@emmas.aprisoft.de>
Date: Sat, 30 Jul 2022 17:01:03 +0200 (CEST)
From: martin@NetBSD.org
Reply-To: martin@NetBSD.org
To: gnats-bugs@NetBSD.org
Subject: audio(4) may fail uobj allocation under VA fragmentation/preassure
X-Send-Pr-Version: 3.95

>Number:         56947
>Category:       kern
>Synopsis:       audio(4) may fail uobj allocation under VA fragmentation/preassure
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    isaki
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jul 30 15:05:01 +0000 2022
>Closed-Date:    Sun Apr 23 16:09:53 +0000 2023
>Last-Modified:  Sun Apr 23 16:09:53 +0000 2023
>Originator:     Martin Husemann
>Release:        NetBSD 9.99.99
>Organization:
The NetBSD Foundation, Inc.
>Environment:
System: NetBSD big-apple.aprisoft.de 9.99.99 NetBSD 9.99.99 (POWERMAC_G5.MP) #65: Thu Jul 28 16:26:57 CEST 2022 martin@seven-days-to-the-wolves.aprisoft.de:/work/src/sys/arch/macppc/compile/POWERMAC_G5.MP macppc
Architecture: powerpc
Machine: macppc
>Description:

On a 32bit kernel with limited VA and the machine under heavy load (like
building pkgs) audio(4) sometimes fails with this printf
(sys/dev/audio/audio.c line 4701:

        if (track->usrbuf_blksize != oldblksize) {
                error = audio_realloc_usrbuf(track, newbufsize);
                if (error) {
                        device_printf(sc->sc_dev, "malloc usrbuf(%d) failed\n",
                            newbufsize);
                        goto error;
                }
        }

and the userland audio app aborts. The "newbufsize" printed is always
the maximum (64k) for me.

I added some instrumentation around audio_realloc_usrbuf and for a typical
playback of a single song I get:

[ 26185.7526103] audio0: play format changing: 0/0/0/0 -> 8000/1/8/8
[ 26185.7526103] audio0: block size changes from 0 to 512
[ 26185.7526103] audio0: play format changing: 8000/1/8/8 -> 48000/7/16/16
[ 26185.7526103] audio0: block size changes from 512 to 12288
[ 26185.7626097] audio0: play format changing: 48000/7/16/16 -> 4800
[ 26185.8226099] audio0: play format changing: 0/0/0/0 -> 8000/1/8/8
[ 26185.8226099] audio0: block size changes from 0 to 512
[ 26185.8226099] audio0: play format changing: 8000/1/8/8 -> 48000/7/16/16
[ 26185.8226099] audio0: block size changes from 512 to 12288
[ 26185.8226099] audio_free_usrbuf: freeing usrbuf

That is quite a bit of unecessary (re-)allocations.

>How-To-Repeat:
s/a

>Fix:

I wonder if we:

 a) could defer allocation untill the mmap actually happens (so the interim
    variants like the default 8k ulaw that is never really used avoid it
    completely)
 b) keep the uobj (and all allocations for it) around (i.e. not free
    it on close) so we stick with a single 64k uobj for each audio
    that is ever used at least once and never need to allocate anythin
    on later open/uses

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: kern-bug-people->isaki
Responsible-Changed-By: isaki@NetBSD.org
Responsible-Changed-When: Mon, 01 Aug 2022 12:35:48 +0000
Responsible-Changed-Why:
I will try.


From: "Tetsuya Isaki" <isaki@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/56947 CVS commit: src/sys/dev/audio
Date: Sat, 13 Aug 2022 06:47:41 +0000

 Module Name:	src
 Committed By:	isaki
 Date:		Sat Aug 13 06:47:41 UTC 2022

 Modified Files:
 	src/sys/dev/audio: audio.c audiodef.h

 Log Message:
 audio: Rework about usrbuf allocation.
 - Allocate the usrbuf from kmem(9) instead of uvm(9).  The usrbuf has used
   uvm(9), in case mmap(2) might be issued later.  However, despite the most
   apps don't use mmap(2), allocating (and reallocating) uvm(9) every time
   would be expensive.  In addition, uvm(9) for recording usrbuf was totally
   pointless now.
 - For playback, the usrbuf memory will be allocated in pages.  Because the
   usrbuf for playback is mostly near 64KB for backward compatibility.
   This will reduce reallocation especially from the initial ulaw to the most
   commonly used format like slinear16/2ch/48kHz.
 - When mmap(2) is called, it will replace the playback usrbuf from kmem(9) to
   uvm(9).
 - Prohibit changing playback format once mmap(2) is called.
   It follows netbsd-7.
 - For recording, the usrbuf memory will be allocated in the requested size
   every time as before.  Because the usrbuf for recording is only one block
   and is enough small to the page in the most case.
 Inspired by PR kern/56947.


 To generate a diff of this commit:
 cvs rdiff -u -r1.134 -r1.135 src/sys/dev/audio/audio.c
 cvs rdiff -u -r1.19 -r1.20 src/sys/dev/audio/audiodef.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Tetsuya Isaki <isaki@pastel-flower.jp>
To: gnats-bugs@netbsd.org
Cc: kern-bug-people@netbsd.org,
	gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: kern/56947: audio(4) may fail uobj allocation under VA fragmentation/preassure
Date: Sat, 13 Aug 2022 16:03:07 +0900

 Please try audio.c 1.135 (or later).
 I have made two improvements on this revision.
 - Memory reallocation should be reduced.
 - Allocating uvm(9) defers until mmap is actually called.

 If it doesn't improve your problem, then please show me
 - dmesg (at least audio device, hardware device, and memory size).
 - sysctl hw.pagesize
 - sysctl hw.audio<N>.blk_ms
 - what apps do you use?

 > I added some instrumentation around audio_realloc_usrbuf and for a typical
 > playback of a single song I get:
 > 
 > [ 26185.7526103] audio0: play format changing: 0/0/0/0 -> 8000/1/8/8
 > [ 26185.7526103] audio0: block size changes from 0 to 512
 > [ 26185.7526103] audio0: play format changing: 8000/1/8/8 -> 48000/7/16/16
 > [ 26185.7526103] audio0: block size changes from 512 to 12288
 > [ 26185.7626097] audio0: play format changing: 48000/7/16/16 -> 4800
 > [ 26185.8226099] audio0: play format changing: 0/0/0/0 -> 8000/1/8/8
 > [ 26185.8226099] audio0: block size changes from 0 to 512
 > [ 26185.8226099] audio0: play format changing: 8000/1/8/8 -> 48000/7/16/16
 > [ 26185.8226099] audio0: block size changes from 512 to 12288
 > [ 26185.8226099] audio_free_usrbuf: freeing usrbuf
 > 
 > That is quite a bit of unecessary (re-)allocations.

 I don't know details because I don't know where did you put this
 message.  But it looks to me that two descriptors did the sequence
 of open(it calls the initial AUDIO_SETINFO internally) and
 AUDIO_SETINFO once respectively.

 "#define AUDIO_DEBUG 2" (at sys/dev/audio/audio.c:242) will help.

 >  a) could defer allocation untill the mmap actually happens (so the interim
 >     variants like the default 8k ulaw that is never really used avoid it
 >     completely)

 "defer allocation until actual write (to avoid reallocating never-used
 initial ulaw)" is not good idea.  Under this mechanism, even though you
 issue AUDIO_SETINFO with the size which cannot be allocated, it will
 succeed.  This will confuse users.

 But "defer allocation until mmap" is interesting because only few apps
 call mmap(2).

 >  b) keep the uobj (and all allocations for it) around (i.e. not free
 >     it on close) so we stick with a single 64k uobj for each audio
 >     that is ever used at least once and never need to allocate anythin
 >     on later open/uses

 I disagree it as is.  It is technically possible but
 - On modern machines, it's totally unnecessary mechanism despite
   the code is more complex.
 - On ancient (small memory) machines, holding 64k at all times is
   acceptable?


 Anyway, your suggestions inspired me much.  Thank you.
 ---
 Tetsuya Isaki <isaki@pastel-flower.jp / isaki@NetBSD.org>

From: Tetsuya Isaki <isaki@pastel-flower.jp>
To: gnats-bugs@netbsd.org
Cc: kern-bug-people@netbsd.org,
	gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: kern/56947: audio(4) may fail uobj allocation under VA fragmentation/preassure
Date: Sat, 22 Apr 2023 17:12:09 +0900

 Hello, martin@.

 At Sat, 13 Aug 2022 16:03:07 +0900,
 Tetsuya Isaki wrote:
 > 
 > Please try audio.c 1.135 (or later).
 > I have made two improvements on this revision.
 > - Memory reallocation should be reduced.
 > - Allocating uvm(9) defers until mmap is actually called.

 Have the issue re-occurred since then?
 (I think I have fixed it at sys/dev/audio/audio.c,v 1.135)
 ---
 Tetsuya Isaki <isaki@pastel-flower.jp / isaki@NetBSD.org>

State-Changed-From-To: open->closed
State-Changed-By: martin@NetBSD.org
State-Changed-When: Sun, 23 Apr 2023 16:09:53 +0000
State-Changed-Why:
Have not seen it again since r1.135


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2023 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.