Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_page.c
Show First 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | |||||
static int vm_pageproc_waiters; | static int vm_pageproc_waiters; | ||||
/* | /* | ||||
* bogus page -- for I/O to/from partially complete buffers, | * bogus page -- for I/O to/from partially complete buffers, | ||||
* or for paging into sparsely invalid regions. | * or for paging into sparsely invalid regions. | ||||
*/ | */ | ||||
vm_page_t bogus_page; | vm_page_t bogus_page; | ||||
#ifdef PMAP_HAS_PAGE_ARRAY | |||||
vm_page_t vm_page_array = (vm_page_t)PA_MIN_ADDRESS; | |||||
#else | |||||
vm_page_t vm_page_array; | vm_page_t vm_page_array; | ||||
#endif | |||||
long vm_page_array_size; | long vm_page_array_size; | ||||
long first_page; | long first_page; | ||||
static int boot_pages; | static int boot_pages; | ||||
SYSCTL_INT(_vm, OID_AUTO, boot_pages, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, | SYSCTL_INT(_vm, OID_AUTO, boot_pages, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, | ||||
&boot_pages, 0, | &boot_pages, 0, | ||||
"number of pages allocated for bootstrapping the VM system"); | "number of pages allocated for bootstrapping the VM system"); | ||||
▲ Show 20 Lines • Show All 370 Lines • ▼ Show 20 Lines | vm_page_init_page(vm_page_t m, vm_paddr_t pa, int segind) | ||||
m->psind = 0; | m->psind = 0; | ||||
m->segind = segind; | m->segind = segind; | ||||
m->order = VM_NFREEORDER; | m->order = VM_NFREEORDER; | ||||
m->pool = VM_FREEPOOL_DEFAULT; | m->pool = VM_FREEPOOL_DEFAULT; | ||||
m->valid = m->dirty = 0; | m->valid = m->dirty = 0; | ||||
pmap_page_init(m); | pmap_page_init(m); | ||||
} | } | ||||
#ifndef PMAP_HAS_PAGE_ARRAY | |||||
static vm_paddr_t | |||||
vm_page_array_alloc(vm_offset_t *vaddr, vm_paddr_t end, vm_paddr_t page_range) | |||||
{ | |||||
vm_paddr_t new_end; | |||||
/* | /* | ||||
* Reserve an unmapped guard page to trap access to vm_page_array[-1]. | |||||
* However, because this page is allocated from KVM, out-of-bounds | |||||
* accesses using the direct map will not be trapped. | |||||
*/ | |||||
*vaddr += PAGE_SIZE; | |||||
/* | |||||
* Allocate physical memory for the page structures, and map it. | |||||
*/ | |||||
new_end = trunc_page(end - page_range * sizeof(struct vm_page)); | |||||
vm_page_array = (vm_page_t)pmap_map(vaddr, new_end, end, | |||||
VM_PROT_READ | VM_PROT_WRITE); | |||||
vm_page_array_size = page_range; | |||||
return (new_end); | |||||
} | |||||
#endif | |||||
/* | |||||
* vm_page_startup: | * vm_page_startup: | ||||
* | * | ||||
* Initializes the resident memory module. Allocates physical memory for | * Initializes the resident memory module. Allocates physical memory for | ||||
* bootstrapping UMA and some data structures that are used to manage | * bootstrapping UMA and some data structures that are used to manage | ||||
* physical pages. Initializes these structures, and populates the free | * physical pages. Initializes these structures, and populates the free | ||||
* page queues. | * page queues. | ||||
*/ | */ | ||||
vm_offset_t | vm_offset_t | ||||
▲ Show 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | #ifdef VM_PHYSSEG_SPARSE | ||||
for (i = 0; phys_avail[i + 1] != 0; i += 2) | for (i = 0; phys_avail[i + 1] != 0; i += 2) | ||||
size += phys_avail[i + 1] - phys_avail[i]; | size += phys_avail[i + 1] - phys_avail[i]; | ||||
#elif defined(VM_PHYSSEG_DENSE) | #elif defined(VM_PHYSSEG_DENSE) | ||||
size = high_avail - low_avail; | size = high_avail - low_avail; | ||||
#else | #else | ||||
#error "Either VM_PHYSSEG_DENSE or VM_PHYSSEG_SPARSE must be defined." | #error "Either VM_PHYSSEG_DENSE or VM_PHYSSEG_SPARSE must be defined." | ||||
#endif | #endif | ||||
#ifdef PMAP_HAS_PAGE_ARRAY | |||||
pmap_page_array_startup(size / PAGE_SIZE); | |||||
biggestone = vm_phys_avail_largest(); | |||||
end = new_end = phys_avail[biggestone + 1]; | |||||
#else | |||||
#ifdef VM_PHYSSEG_DENSE | #ifdef VM_PHYSSEG_DENSE | ||||
/* | /* | ||||
* In the VM_PHYSSEG_DENSE case, the number of pages can account for | * In the VM_PHYSSEG_DENSE case, the number of pages can account for | ||||
* the overhead of a page structure per page only if vm_page_array is | * the overhead of a page structure per page only if vm_page_array is | ||||
* allocated from the last physical memory chunk. Otherwise, we must | * allocated from the last physical memory chunk. Otherwise, we must | ||||
* allocate page structures representing the physical memory | * allocate page structures representing the physical memory | ||||
* underlying vm_page_array, even though they will not be used. | * underlying vm_page_array, even though they will not be used. | ||||
*/ | */ | ||||
Show All 14 Lines | #endif | ||||
*/ | */ | ||||
if (size % (PAGE_SIZE + sizeof(struct vm_page)) >= PAGE_SIZE) { | if (size % (PAGE_SIZE + sizeof(struct vm_page)) >= PAGE_SIZE) { | ||||
if (new_end == high_avail) | if (new_end == high_avail) | ||||
high_avail -= PAGE_SIZE; | high_avail -= PAGE_SIZE; | ||||
new_end -= PAGE_SIZE; | new_end -= PAGE_SIZE; | ||||
} | } | ||||
} | } | ||||
end = new_end; | end = new_end; | ||||
new_end = vm_page_array_alloc(&vaddr, end, page_range); | |||||
#endif | |||||
/* | |||||
* Reserve an unmapped guard page to trap access to vm_page_array[-1]. | |||||
* However, because this page is allocated from KVM, out-of-bounds | |||||
* accesses using the direct map will not be trapped. | |||||
*/ | |||||
vaddr += PAGE_SIZE; | |||||
/* | |||||
* Allocate physical memory for the page structures, and map it. | |||||
*/ | |||||
new_end = trunc_page(end - page_range * sizeof(struct vm_page)); | |||||
mapped = pmap_map(&vaddr, new_end, end, | |||||
VM_PROT_READ | VM_PROT_WRITE); | |||||
vm_page_array = (vm_page_t)mapped; | |||||
vm_page_array_size = page_range; | |||||
#if VM_NRESERVLEVEL > 0 | #if VM_NRESERVLEVEL > 0 | ||||
/* | /* | ||||
* Allocate physical memory for the reservation management system's | * Allocate physical memory for the reservation management system's | ||||
* data structures, and map it. | * data structures, and map it. | ||||
*/ | */ | ||||
if (high_avail == end) | new_end = vm_reserv_startup(&vaddr, new_end); | ||||
high_avail = new_end; | |||||
new_end = vm_reserv_startup(&vaddr, new_end, high_avail); | |||||
#endif | #endif | ||||
#if defined(__aarch64__) || defined(__amd64__) || defined(__mips__) || \ | #if defined(__aarch64__) || defined(__amd64__) || defined(__mips__) || \ | ||||
defined(__riscv) | defined(__riscv) | ||||
/* | /* | ||||
* Include vm_page_array and vm_reserv_array in a crash dump. | * Include vm_page_array and vm_reserv_array in a crash dump. | ||||
*/ | */ | ||||
for (pa = new_end; pa < end; pa += PAGE_SIZE) | for (pa = new_end; pa < end; pa += PAGE_SIZE) | ||||
dump_add_page(pa); | dump_add_page(pa); | ||||
▲ Show 20 Lines • Show All 3,804 Lines • Show Last 20 Lines |