NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/54818: 9.0_RC1 pagedaemon spins
Hi,
(just to remind folks, this is with NetBSD 8.1)
It seems that the behaviour from the audio.c driver is that each time
I start a playback in firefox, the dtrace script logs 4 instances of
uvm_km_kmem_alloc(), but only two of uvm_km_kmem_free().
On a hunch, I tried with this diff:
--- audio.c 7 Jun 2018 18:24:16 -0000 1.357.2.13
+++ audio.c 15 Mar 2020 09:18:57 -0000
@@ -1491,6 +1491,9 @@ audio_stream_ctor(audio_stream_t *stream
int frame_size;
size = min(size, AU_RING_SIZE);
+ /* Will overwrite, may need to release */
+ if (stream->start != NULL)
+ kmem_free(stream->start, stream->bufsize);
stream->bufsize = size;
stream->start = kmem_zalloc(size, KM_SLEEP);
frame_size = (param->precision + 7) / 8 * param->channels;
but that doesn't appear to have any effect. The trace changes
slightly with the above patch in place, in that the audio_stream_ctor
is now visible in the dtrace output as
0 -> uvm_km_kmem_alloc size: 65536
netbsd`kmem_intr_alloc+0x6d
netbsd`kmem_intr_zalloc+0xf
netbsd`audio_stream_ctor.constprop.39+0x34
netbsd`audiosetinfo+0x10a0
netbsd`audio_set_defaults+0xeb
There appears to be two places in audiosetinfo() which calls
audio_stream_ctor():
netbsd`audio_stream_ctor.constprop.39+0x34
netbsd`audiosetinfo+0x636
and
netbsd`audio_stream_ctor.constprop.39+0x34
netbsd`audiosetinfo+0x10a0
and each of them allocates twice. auidio_stream_dtor() is always
called from the same spot:
netbsd`audio_stream_dtor+0x1d
netbsd`audiosetinfo+0x14d5
The two places in "audiosetinfo()" which calls audio_stream_ctor()
decodes to
(gdb) x/i audiosetinfo+0x636
0xffffffff8079076d <audiosetinfo+1590>: test %eax,%eax
(gdb) i li *0xffffffff8079076d
Line 1307 of "/usr/src/sys/dev/audio.c"
starts at address 0xffffffff80790762 <audiosetinfo+1579>
and ends at 0xffffffff80790775 <audiosetinfo+1598>.
(gdb) x/i audiosetinfo+0x10a0
0xffffffff807911d7 <audiosetinfo+4256>: test %eax,%eax
(gdb) i li *0xffffffff807911d7
Line 1389 of "/usr/src/sys/dev/audio.c"
starts at address 0xffffffff807911c5 <audiosetinfo+4238>
and ends at 0xffffffff807911df <audiosetinfo+4264>.
(gdb)
The first one is the audio_stream_ctor() inside
audio_setup_pfilters(), the second is in audio_setup_rfilters().
Both appear to have been hoisted into audiosetinfo() by the
optimizer.
The visible trace of audio_stream_dtor() invocation is near the end of
audio_setup_pfilters(). However, the "destroy old filters" part in
audio_setup_rfilters() appears to never call the audio_stream_dtor(),
despite there being a loop near the end:
/* Destroy old filters. */
for (i = 0; i < onfilters; i++) {
of[i]->dtor(of[i]);
audio_stream_dtor(&os[i]);
}
return 0;
onfilters is set from vc->sc_nrfilters, and that field is subsequently
set to rfilters->req_size, and the preceding loop which contains the
call to audio_stream_ctor() is over rfilters->req_size.
So ... I can't quite figure out what is going on and why it's leaking
two allocations on each audio device activation. It would seem that
vc->sc_nrfilters is zero(?)
Anyone have any hints? (I'll have opportunity to test a new kernel
tomorrow.)
Regards,
- Havard
Home |
Main Index |
Thread Index |
Old Index