Subject: uvm_pglist alloc and WAITOK
To: None <>
From: Frank van der Linden <>
List: tech-kern
Date: 09/18/2001 13:37:09
Matthias Drochner pointed out a problem that became apparent while
using the AGP code. The AGP code uses bus_dmamem_alloc to allocate
physical pages that are addressable through the AGP (PCI) bus.

bus_dmamem_alloc uses (for the i386 port, but I'm sure on other ports
as well), uvm_pglistalloc to allocate pages in the suited ranges
of memory. Normally, bus_dmamem_alloc is only used by drivers at
config time, when there's still plenty of memory available, so it
will never fail. However, the AGP code will call bus_dmamem_alloc
when triggered by a request via an ioctl call (it's hard to
change this, unless you want to allocate the entire AGP aperture
upfront, which can be 256M in size..). At this time, not much
memory may be available, because UBC or process images may be using
a lot of it.

Naturally, the AGP code passes BUS_DMA_WAITOK to bus_dmamem_alloc,
but it still fails. This is because uvm_pglistalloc ignores the
waitok flag altogether, and bailing out if:

        /* Are there even any free pages? */
        if ( <= (uvmexp.reserve_pagedaemon + uvmexp.reserve_kernel))
                goto out;

The first thing that comes to mind is that it should simply call uvm_wait(),
grab all the pages that match its constraints, and repeat this step until
it has them all. Naturally, a port must make sure that memory ranges that
may not be wanted for bus_dma are preferred above those that are, otherwise
it may never get the pages it wants.

Does that sound like a reasonable idea?

- Frank

Frank van der Linden                 
Quality NetBSD CDs, Support & Service.