Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_map.c
Show First 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | |||||
* As mentioned above, virtual copy operations are performed | * As mentioned above, virtual copy operations are performed | ||||
* by copying VM object references from one map to | * by copying VM object references from one map to | ||||
* another, and then marking both regions as copy-on-write. | * another, and then marking both regions as copy-on-write. | ||||
*/ | */ | ||||
static struct mtx map_sleep_mtx; | static struct mtx map_sleep_mtx; | ||||
static uma_zone_t mapentzone; | static uma_zone_t mapentzone; | ||||
static uma_zone_t kmapentzone; | static uma_zone_t kmapentzone; | ||||
static uma_zone_t mapzone; | |||||
static uma_zone_t vmspace_zone; | static uma_zone_t vmspace_zone; | ||||
static int vmspace_zinit(void *mem, int size, int flags); | static int vmspace_zinit(void *mem, int size, int flags); | ||||
static int vm_map_zinit(void *mem, int ize, int flags); | |||||
static void _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, | static void _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, | ||||
vm_offset_t max); | vm_offset_t max); | ||||
static void vm_map_entry_deallocate(vm_map_entry_t entry, boolean_t system_map); | static void vm_map_entry_deallocate(vm_map_entry_t entry, boolean_t system_map); | ||||
static void vm_map_entry_dispose(vm_map_t map, vm_map_entry_t entry); | static void vm_map_entry_dispose(vm_map_t map, vm_map_entry_t entry); | ||||
static void vm_map_entry_unwire(vm_map_t map, vm_map_entry_t entry); | static void vm_map_entry_unwire(vm_map_t map, vm_map_entry_t entry); | ||||
static int vm_map_growstack(vm_map_t map, vm_offset_t addr, | static int vm_map_growstack(vm_map_t map, vm_offset_t addr, | ||||
vm_map_entry_t gap_entry); | vm_map_entry_t gap_entry); | ||||
static void vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot, | static void vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot, | ||||
vm_object_t object, vm_pindex_t pindex, vm_size_t size, int flags); | vm_object_t object, vm_pindex_t pindex, vm_size_t size, int flags); | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
static void vm_map_zdtor(void *mem, int size, void *arg); | |||||
static void vmspace_zdtor(void *mem, int size, void *arg); | static void vmspace_zdtor(void *mem, int size, void *arg); | ||||
#endif | #endif | ||||
static int vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, | static int vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, | ||||
vm_size_t max_ssize, vm_size_t growsize, vm_prot_t prot, vm_prot_t max, | vm_size_t max_ssize, vm_size_t growsize, vm_prot_t prot, vm_prot_t max, | ||||
int cow); | int cow); | ||||
static void vm_map_wire_entry_failure(vm_map_t map, vm_map_entry_t entry, | static void vm_map_wire_entry_failure(vm_map_t map, vm_map_entry_t entry, | ||||
vm_offset_t failed_addr); | vm_offset_t failed_addr); | ||||
Show All 39 Lines | |||||
* These restrictions are necessary since malloc() uses the | * These restrictions are necessary since malloc() uses the | ||||
* maps and requires map entries. | * maps and requires map entries. | ||||
*/ | */ | ||||
void | void | ||||
vm_map_startup(void) | vm_map_startup(void) | ||||
{ | { | ||||
mtx_init(&map_sleep_mtx, "vm map sleep mutex", NULL, MTX_DEF); | mtx_init(&map_sleep_mtx, "vm map sleep mutex", NULL, MTX_DEF); | ||||
mapzone = uma_zcreate("MAP", sizeof(struct vm_map), NULL, | |||||
#ifdef INVARIANTS | |||||
vm_map_zdtor, | |||||
#else | |||||
NULL, | |||||
#endif | |||||
vm_map_zinit, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); | |||||
uma_prealloc(mapzone, MAX_KMAP); | |||||
kmapentzone = uma_zcreate("KMAP ENTRY", sizeof(struct vm_map_entry), | kmapentzone = uma_zcreate("KMAP ENTRY", sizeof(struct vm_map_entry), | ||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, | NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, | ||||
UMA_ZONE_MTXCLASS | UMA_ZONE_VM); | UMA_ZONE_MTXCLASS | UMA_ZONE_VM); | ||||
mapentzone = uma_zcreate("MAP ENTRY", sizeof(struct vm_map_entry), | mapentzone = uma_zcreate("MAP ENTRY", sizeof(struct vm_map_entry), | ||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | ||||
vmspace_zone = uma_zcreate("VMSPACE", sizeof(struct vmspace), NULL, | vmspace_zone = uma_zcreate("VMSPACE", sizeof(struct vmspace), NULL, | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
vmspace_zdtor, | vmspace_zdtor, | ||||
#else | #else | ||||
NULL, | NULL, | ||||
#endif | #endif | ||||
vmspace_zinit, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); | vmspace_zinit, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); | ||||
} | } | ||||
static int | static int | ||||
vmspace_zinit(void *mem, int size, int flags) | vmspace_zinit(void *mem, int size, int flags) | ||||
{ | { | ||||
struct vmspace *vm; | struct vmspace *vm; | ||||
vm_map_t map; | |||||
vm = (struct vmspace *)mem; | vm = (struct vmspace *)mem; | ||||
map = &vm->vm_map; | |||||
vm->vm_map.pmap = NULL; | |||||
(void)vm_map_zinit(&vm->vm_map, sizeof(vm->vm_map), flags); | |||||
PMAP_LOCK_INIT(vmspace_pmap(vm)); | |||||
return (0); | |||||
} | |||||
static int | |||||
vm_map_zinit(void *mem, int size, int flags) | |||||
{ | |||||
vm_map_t map; | |||||
map = (vm_map_t)mem; | |||||
memset(map, 0, sizeof(*map)); | memset(map, 0, sizeof(*map)); | ||||
mtx_init(&map->system_mtx, "vm map (system)", NULL, MTX_DEF | MTX_DUPOK); | mtx_init(&map->system_mtx, "vm map (system)", NULL, | ||||
MTX_DEF | MTX_DUPOK); | |||||
sx_init(&map->lock, "vm map (user)"); | sx_init(&map->lock, "vm map (user)"); | ||||
PMAP_LOCK_INIT(vmspace_pmap(vm)); | |||||
return (0); | return (0); | ||||
} | } | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
static void | static void | ||||
vmspace_zdtor(void *mem, int size, void *arg) | vmspace_zdtor(void *mem, int size, void *arg) | ||||
{ | { | ||||
struct vmspace *vm; | struct vmspace *vm; | ||||
vm = (struct vmspace *)mem; | vm = (struct vmspace *)mem; | ||||
KASSERT(vm->vm_map.nentries == 0, | |||||
vm_map_zdtor(&vm->vm_map, sizeof(vm->vm_map), arg); | ("vmspace %p nentries == %d on free", vm, vm->vm_map.nentries)); | ||||
KASSERT(vm->vm_map.size == 0, | |||||
("vmspace %p size == %ju on free", vm, (uintmax_t)vm->vm_map.size)); | |||||
} | } | ||||
static void | |||||
vm_map_zdtor(void *mem, int size, void *arg) | |||||
{ | |||||
vm_map_t map; | |||||
map = (vm_map_t)mem; | |||||
KASSERT(map->nentries == 0, | |||||
("map %p nentries == %d on free.", | |||||
map, map->nentries)); | |||||
KASSERT(map->size == 0, | |||||
("map %p size == %lu on free.", | |||||
map, (unsigned long)map->size)); | |||||
} | |||||
#endif /* INVARIANTS */ | #endif /* INVARIANTS */ | ||||
/* | /* | ||||
* Allocate a vmspace structure, including a vm_map and pmap, | * Allocate a vmspace structure, including a vm_map and pmap, | ||||
* and initialize those structures. The refcnt is set to 1. | * and initialize those structures. The refcnt is set to 1. | ||||
* | |||||
* If 'pinit' is NULL then the embedded pmap is initialized via pmap_pinit(). | |||||
*/ | */ | ||||
struct vmspace * | struct vmspace * | ||||
vmspace_alloc(vm_offset_t min, vm_offset_t max, pmap_pinit_t pinit) | vmspace_alloc(vm_offset_t min, vm_offset_t max, pmap_pinit_t pinit) | ||||
{ | { | ||||
struct vmspace *vm; | struct vmspace *vm; | ||||
vm = uma_zalloc(vmspace_zone, M_WAITOK); | vm = uma_zalloc(vmspace_zone, M_WAITOK); | ||||
KASSERT(vm->vm_map.pmap == NULL, ("vm_map.pmap must be NULL")); | KASSERT(vm->vm_map.pmap == NULL, ("vm_map.pmap must be NULL")); | ||||
▲ Show 20 Lines • Show All 580 Lines • ▼ Show 20 Lines | |||||
long | long | ||||
vmspace_resident_count(struct vmspace *vmspace) | vmspace_resident_count(struct vmspace *vmspace) | ||||
{ | { | ||||
return pmap_resident_count(vmspace_pmap(vmspace)); | return pmap_resident_count(vmspace_pmap(vmspace)); | ||||
} | } | ||||
/* | /* | ||||
* vm_map_create: | |||||
* | |||||
* Creates and returns a new empty VM map with | |||||
* the given physical map structure, and having | |||||
* the given lower and upper address bounds. | |||||
*/ | |||||
vm_map_t | |||||
vm_map_create(pmap_t pmap, vm_offset_t min, vm_offset_t max) | |||||
{ | |||||
vm_map_t result; | |||||
result = uma_zalloc(mapzone, M_WAITOK); | |||||
CTR1(KTR_VM, "vm_map_create: %p", result); | |||||
_vm_map_init(result, pmap, min, max); | |||||
return (result); | |||||
} | |||||
/* | |||||
* Initialize an existing vm_map structure | * Initialize an existing vm_map structure | ||||
* such as that in the vmspace structure. | * such as that in the vmspace structure. | ||||
*/ | */ | ||||
static void | static void | ||||
_vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max) | _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max) | ||||
{ | { | ||||
map->header.eflags = MAP_ENTRY_HEADER; | map->header.eflags = MAP_ENTRY_HEADER; | ||||
Show All 13 Lines | |||||
#endif | #endif | ||||
} | } | ||||
void | void | ||||
vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max) | vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max) | ||||
{ | { | ||||
_vm_map_init(map, pmap, min, max); | _vm_map_init(map, pmap, min, max); | ||||
mtx_init(&map->system_mtx, "system map", NULL, MTX_DEF | MTX_DUPOK); | mtx_init(&map->system_mtx, "vm map (system)", NULL, | ||||
sx_init(&map->lock, "user map"); | MTX_DEF | MTX_DUPOK); | ||||
sx_init(&map->lock, "vm map (user)"); | |||||
} | } | ||||
/* | /* | ||||
* vm_map_entry_dispose: [ internal use only ] | * vm_map_entry_dispose: [ internal use only ] | ||||
* | * | ||||
* Inverse of vm_map_entry_create. | * Inverse of vm_map_entry_create. | ||||
*/ | */ | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 4,262 Lines • Show Last 20 Lines |