Conditionally move initial vfs bio alloc above 4G

On machines with just the wrong amount of physical memory (enough to
have a lot of bufs, but not enough to use VM_FREELIST_DMA32) it is
possible for 32-bit address limited devices to have little to no
memory left when attaching, due to potentially large vfs bio configs
consuming all memory below 4GB not protected by VM_FREELIST_ISADMA.
This causes the 32-bit devices to allocate from VM_FREELIST_ISADMA,
leaving that freelist emtpy when ISA devices need DMAable memory.

Rather than decrease VM_DMA32_NPAGES_THRESHOLD, use the time honored
technique of putting initially allocated kernel data structs
at the end (or at least not the beginning) of memory.

Since this allocation is done at boot and is wired, is not freed,
so the system is low on 32-bit (and ISA) dma'ble memory forever.
So it is a good candidate to move above 4GB.

While here, remove an unneeded round_page() from kmem_malloc's size
argument as suggested by alc.  The first thing kmem_malloc() does
is a round_page(size), so there is no need to do it before the call.

Reviewed by: alc
Sponsored by: Netflix
This commit is contained in:
Andrew Gallatin 2016-10-03 13:23:43 +00:00
parent 5c1ea1fcd0
commit edb2994a62

View File

@ -206,8 +206,18 @@ vm_ksubmap_init(struct kva_md_info *kmi)
*/
if (firstaddr == 0) {
size = (vm_size_t)v;
firstaddr = kmem_malloc(kernel_arena, round_page(size),
M_ZERO | M_WAITOK);
#ifdef VM_FREELIST_DMA32
/*
* Try to protect 32-bit DMAable memory from the largest
* early alloc of wired mem.
*/
firstaddr = kmem_alloc_attr(kernel_arena, size,
M_ZERO | M_NOWAIT, (vm_paddr_t)1 << 32,
~(vm_paddr_t)0, VM_MEMATTR_DEFAULT);
if (firstaddr == 0)
#endif
firstaddr = kmem_malloc(kernel_arena, size,
M_ZERO | M_WAITOK);
if (firstaddr == 0)
panic("startup: no room for tables");
goto again;