Made the VM a lot calmer if you wish; moved many dprintf()s into the new
TRACE() macro. Renamed the old TRACE macro to TRACEPFAULT. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4343 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+60
-47
@@ -36,13 +36,20 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define TRACE_VM 1
|
#define TRACE_VM 0
|
||||||
#if TRACE_VM
|
#if TRACE_VM
|
||||||
# define TRACE(x) dprintf x
|
# define TRACE(x) dprintf x
|
||||||
#else
|
#else
|
||||||
# define TRACE(x) ;
|
# define TRACE(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TRACE_PFAULT 0
|
||||||
|
#if TRACE_PFAULT
|
||||||
|
# define TRACEPFAULT dprintf("in pfault at line %d\n", __LINE__)
|
||||||
|
#else
|
||||||
|
# define TRACEPFAULT
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
|
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
|
||||||
#define ROUNDOWN(a, b) (((a) / (b)) * (b))
|
#define ROUNDOWN(a, b) (((a) / (b)) * (b))
|
||||||
|
|
||||||
@@ -205,15 +212,17 @@ static vm_region *_vm_create_region_struct(vm_address_space *aspace, const char
|
|||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// must be called with this address space's virtual_map.sem held
|
// must be called with this address space's virtual_map.sem held
|
||||||
static int find_and_insert_region_slot(vm_virtual_map *map, addr start, addr size, addr end, int addr_type, vm_region *region)
|
static int
|
||||||
|
find_and_insert_region_slot(vm_virtual_map *map, addr start, addr size, addr end, int addr_type, vm_region *region)
|
||||||
{
|
{
|
||||||
vm_region *last_r = NULL;
|
vm_region *last_r = NULL;
|
||||||
vm_region *next_r;
|
vm_region *next_r;
|
||||||
bool foundspot = false;
|
bool foundspot = false;
|
||||||
|
|
||||||
dprintf("find_and_insert_region_slot: map %p, start 0x%lx, size %ld, end 0x%lx, addr_type %d, region %p\n",
|
TRACE(("find_and_insert_region_slot: map %p, start 0x%lx, size %ld, end 0x%lx, addr_type %d, region %p\n",
|
||||||
map, start, size, end, addr_type, region);
|
map, start, size, end, addr_type, region));
|
||||||
// dprintf("map->base 0x%x, map->size 0x%x\n", map->base, map->size);
|
// dprintf("map->base 0x%x, map->size 0x%x\n", map->base, map->size);
|
||||||
|
|
||||||
// do some sanity checking
|
// do some sanity checking
|
||||||
@@ -326,8 +335,8 @@ static int map_backing_store(vm_address_space *aspace, vm_store *store,
|
|||||||
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
// dprintf("map_backing_store: aspace 0x%x, store 0x%x, *vaddr 0x%x, offset 0x%Lx, size %d, addr_type %d, wiring %d, lock %d, _region 0x%x, region_name '%s'\n",
|
TRACE(("map_backing_store: aspace 0x%x, store 0x%x, *vaddr 0x%x, offset 0x%Lx, size %d, addr_type %d, wiring %d, lock %d, _region 0x%x, region_name '%s'\n",
|
||||||
// aspace, store, *vaddr, offset, size, addr_type, wiring, lock, _region, region_name);
|
aspace, store, *vaddr, offset, size, addr_type, wiring, lock, _region, region_name));
|
||||||
|
|
||||||
region = _vm_create_region_struct(aspace, region_name, wiring, lock);
|
region = _vm_create_region_struct(aspace, region_name, wiring, lock);
|
||||||
if (!region)
|
if (!region)
|
||||||
@@ -479,7 +488,7 @@ vm_create_anonymous_region(aspace_id aid, const char *name, void **address,
|
|||||||
vm_address_space *aspace;
|
vm_address_space *aspace;
|
||||||
vm_cache_ref *cache_ref;
|
vm_cache_ref *cache_ref;
|
||||||
|
|
||||||
dprintf("create_anonymous_region: %s: size 0x%lx\n", name, size);
|
TRACE(("create_anonymous_region: %s: size 0x%lx\n", name, size));
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
if (addr_type != REGION_ADDR_ANY_ADDRESS && addr_type != REGION_ADDR_EXACT_ADDRESS)
|
if (addr_type != REGION_ADDR_ANY_ADDRESS && addr_type != REGION_ADDR_EXACT_ADDRESS)
|
||||||
@@ -932,7 +941,7 @@ _vm_delete_region(vm_address_space *aspace, region_id rid)
|
|||||||
{
|
{
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
|
|
||||||
dprintf("vm_delete_region: aspace id 0x%lx, region id 0x%lx\n", aspace->id, rid);
|
TRACE(("vm_delete_region: aspace id 0x%lx, region id 0x%lx\n", aspace->id, rid));
|
||||||
|
|
||||||
region = vm_get_region_by_id(rid);
|
region = vm_get_region_by_id(rid);
|
||||||
if (region == NULL)
|
if (region == NULL)
|
||||||
@@ -1087,7 +1096,9 @@ int vm_get_page_mapping(aspace_id aid, addr vaddr, addr *paddr)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int display_mem(int argc, char **argv)
|
|
||||||
|
static int
|
||||||
|
display_mem(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int item_size;
|
int item_size;
|
||||||
int display_width;
|
int display_width;
|
||||||
@@ -1482,7 +1493,7 @@ void vm_put_aspace(vm_address_space *aspace)
|
|||||||
if(!removeit)
|
if(!removeit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dprintf("vm_put_aspace: reached zero ref, deleting aspace\n");
|
TRACE(("vm_put_aspace: reached zero ref, deleting aspace\n"));
|
||||||
|
|
||||||
if(aspace == kernel_aspace)
|
if(aspace == kernel_aspace)
|
||||||
panic("vm_put_aspace: tried to delete the kernel aspace!\n");
|
panic("vm_put_aspace: tried to delete the kernel aspace!\n");
|
||||||
@@ -1509,7 +1520,7 @@ aspace_id vm_create_aspace(const char *name, addr base, addr size, bool kernel)
|
|||||||
if(aspace == NULL)
|
if(aspace == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
dprintf("vm_create_aspace: %s: %lx bytes starting at 0x%lx => %p\n", name, size, base, aspace);
|
TRACE(("vm_create_aspace: %s: %lx bytes starting at 0x%lx => %p\n", name, size, base, aspace));
|
||||||
|
|
||||||
aspace->name = (char *)malloc(strlen(name) + 1);
|
aspace->name = (char *)malloc(strlen(name) + 1);
|
||||||
if(aspace->name == NULL ) {
|
if(aspace->name == NULL ) {
|
||||||
@@ -1553,7 +1564,9 @@ aspace_id vm_create_aspace(const char *name, addr base, addr size, bool kernel)
|
|||||||
return aspace->id;
|
return aspace->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vm_delete_aspace(aspace_id aid)
|
|
||||||
|
int
|
||||||
|
vm_delete_aspace(aspace_id aid)
|
||||||
{
|
{
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
vm_region *next;
|
vm_region *next;
|
||||||
@@ -1563,7 +1576,7 @@ int vm_delete_aspace(aspace_id aid)
|
|||||||
if(aspace == NULL)
|
if(aspace == NULL)
|
||||||
return ERR_VM_INVALID_ASPACE;
|
return ERR_VM_INVALID_ASPACE;
|
||||||
|
|
||||||
dprintf("vm_delete_aspace: called on aspace 0x%lx\n", aid);
|
TRACE(("vm_delete_aspace: called on aspace 0x%lx\n", aid));
|
||||||
|
|
||||||
// put this aspace in the deletion state
|
// put this aspace in the deletion state
|
||||||
// this guarantees that no one else will add regions to the list
|
// this guarantees that no one else will add regions to the list
|
||||||
@@ -1669,12 +1682,14 @@ vm_thread_dump_max_commit(void *unused)
|
|||||||
for(;;) {
|
for(;;) {
|
||||||
snooze(1000000);
|
snooze(1000000);
|
||||||
if (oldmax != max_commit)
|
if (oldmax != max_commit)
|
||||||
dprintf("max_commit 0x%x\n", max_commit);
|
TRACE(("max_commit 0x%x\n", max_commit));
|
||||||
oldmax = max_commit;
|
oldmax = max_commit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int vm_init(kernel_args *ka)
|
|
||||||
|
int
|
||||||
|
vm_init(kernel_args *ka)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@@ -1683,7 +1698,7 @@ int vm_init(kernel_args *ka)
|
|||||||
addr heap_base;
|
addr heap_base;
|
||||||
void *null_addr;
|
void *null_addr;
|
||||||
|
|
||||||
dprintf("vm_init: entry\n");
|
TRACE(("vm_init: entry\n"));
|
||||||
err = vm_translation_map_module_init(ka);
|
err = vm_translation_map_module_init(ka);
|
||||||
err = arch_vm_init(ka);
|
err = arch_vm_init(ka);
|
||||||
|
|
||||||
@@ -1698,7 +1713,7 @@ int vm_init(kernel_args *ka)
|
|||||||
|
|
||||||
// map in the new heap and initialize it
|
// map in the new heap and initialize it
|
||||||
heap_base = vm_alloc_from_ka_struct(ka, HEAP_SIZE, LOCK_KERNEL|LOCK_RW);
|
heap_base = vm_alloc_from_ka_struct(ka, HEAP_SIZE, LOCK_KERNEL|LOCK_RW);
|
||||||
dprintf("heap at 0x%lx\n", heap_base);
|
TRACE(("heap at 0x%lx\n", heap_base));
|
||||||
heap_init(heap_base);
|
heap_init(heap_base);
|
||||||
|
|
||||||
// initialize the free page list and physical page mapper
|
// initialize the free page list and physical page mapper
|
||||||
@@ -1781,12 +1796,14 @@ int vm_init(kernel_args *ka)
|
|||||||
add_debugger_command("ds", &display_mem, "dump memory shorts (16-bit)");
|
add_debugger_command("ds", &display_mem, "dump memory shorts (16-bit)");
|
||||||
add_debugger_command("db", &display_mem, "dump memory bytes (8-bit)");
|
add_debugger_command("db", &display_mem, "dump memory bytes (8-bit)");
|
||||||
|
|
||||||
dprintf("vm_init: exit\n");
|
TRACE(("vm_init: exit\n"));
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vm_init_postsem(kernel_args *ka)
|
|
||||||
|
int
|
||||||
|
vm_init_postsem(kernel_args *ka)
|
||||||
{
|
{
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
|
|
||||||
@@ -1853,8 +1870,8 @@ int vm_page_fault(addr address, addr fault_address, bool is_write, bool is_user,
|
|||||||
|
|
||||||
err = vm_soft_fault(address, is_write, is_user);
|
err = vm_soft_fault(address, is_write, is_user);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dprintf("vm_page_fault: vm_soft_fault returned error %d on fault at 0x%lx, ip 0x%lx, write %d, user %d, thread 0x%lx\n",
|
TRACE(("vm_page_fault: vm_soft_fault returned error %d on fault at 0x%lx, ip 0x%lx, write %d, user %d, thread 0x%lx\n",
|
||||||
err, address, fault_address, is_write, is_user, thread_get_current_thread_id());
|
err, address, fault_address, is_write, is_user, thread_get_current_thread_id()));
|
||||||
if(!is_user) {
|
if(!is_user) {
|
||||||
struct thread *t = thread_get_current_thread();
|
struct thread *t = thread_get_current_thread();
|
||||||
if(t && t->fault_handler != 0) {
|
if(t && t->fault_handler != 0) {
|
||||||
@@ -1876,15 +1893,9 @@ int vm_page_fault(addr address, addr fault_address, bool is_write, bool is_user,
|
|||||||
return B_HANDLED_INTERRUPT;
|
return B_HANDLED_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TRACE_PFAULT 0
|
|
||||||
|
|
||||||
#if TRACE_PFAULT
|
static int
|
||||||
#define TRACE dprintf("in pfault at line %d\n", __LINE__)
|
vm_soft_fault(addr address, bool is_write, bool is_user)
|
||||||
#else
|
|
||||||
#define TRACE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|
||||||
{
|
{
|
||||||
vm_address_space *aspace;
|
vm_address_space *aspace;
|
||||||
vm_virtual_map *map;
|
vm_virtual_map *map;
|
||||||
@@ -1947,7 +1958,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
return ERR_VM_PF_BAD_PERM; // BAD_PERMISSION
|
return ERR_VM_PF_BAD_PERM; // BAD_PERMISSION
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
top_cache_ref = region->cache_ref;
|
top_cache_ref = region->cache_ref;
|
||||||
cache_offset = address - region->base + region->cache_offset;
|
cache_offset = address - region->base + region->cache_offset;
|
||||||
@@ -1963,7 +1974,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
dummy_page.state = PAGE_STATE_INACTIVE;
|
dummy_page.state = PAGE_STATE_INACTIVE;
|
||||||
dummy_page.type = PAGE_TYPE_DUMMY;
|
dummy_page.type = PAGE_TYPE_DUMMY;
|
||||||
@@ -1972,7 +1983,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
for(cache_ref = top_cache_ref; cache_ref; cache_ref = (cache_ref->cache->source) ? cache_ref->cache->source->ref : NULL) {
|
for(cache_ref = top_cache_ref; cache_ref; cache_ref = (cache_ref->cache->source) ? cache_ref->cache->source->ref : NULL) {
|
||||||
mutex_lock(&cache_ref->lock);
|
mutex_lock(&cache_ref->lock);
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
page = vm_cache_lookup_page(cache_ref, cache_offset);
|
page = vm_cache_lookup_page(cache_ref, cache_offset);
|
||||||
@@ -1985,7 +1996,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
if(page == NULL)
|
if(page == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
// page must be busy
|
// page must be busy
|
||||||
mutex_unlock(&cache_ref->lock);
|
mutex_unlock(&cache_ref->lock);
|
||||||
@@ -1993,12 +2004,12 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
mutex_lock(&cache_ref->lock);
|
mutex_lock(&cache_ref->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
if (page != NULL)
|
if (page != NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
// insert this dummy page here to keep other threads from faulting on the
|
// insert this dummy page here to keep other threads from faulting on the
|
||||||
// same address and chasing us up the cache chain
|
// same address and chasing us up the cache chain
|
||||||
@@ -2012,7 +2023,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
if(cache_ref->cache->store->ops->has_page(cache_ref->cache->store, cache_offset)) {
|
if(cache_ref->cache->store->ops->has_page(cache_ref->cache->store, cache_offset)) {
|
||||||
IOVECS(vecs, 1);
|
IOVECS(vecs, 1);
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
mutex_unlock(&cache_ref->lock);
|
mutex_unlock(&cache_ref->lock);
|
||||||
|
|
||||||
@@ -2039,10 +2050,10 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&cache_ref->lock);
|
mutex_unlock(&cache_ref->lock);
|
||||||
last_cache_ref = cache_ref;
|
last_cache_ref = cache_ref;
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
// we rolled off the end of the cache chain, so we need to decide which
|
// we rolled off the end of the cache chain, so we need to decide which
|
||||||
// cache will get the new page we're about to create
|
// cache will get the new page we're about to create
|
||||||
@@ -2053,7 +2064,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
cache_ref = top_cache_ref; // put it in the topmost cache
|
cache_ref = top_cache_ref; // put it in the topmost cache
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
if(page == NULL) {
|
if(page == NULL) {
|
||||||
// still haven't found a page, so zero out a new one
|
// still haven't found a page, so zero out a new one
|
||||||
@@ -2075,7 +2086,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
if(page->cache_ref != top_cache_ref && is_write) {
|
if(page->cache_ref != top_cache_ref && is_write) {
|
||||||
// now we have a page that has the data we want, but in the wrong cache object
|
// now we have a page that has the data we want, but in the wrong cache object
|
||||||
@@ -2121,7 +2132,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
acquire_sem_etc(map->sem, READ_COUNT, 0, 0);
|
acquire_sem_etc(map->sem, READ_COUNT, 0, 0);
|
||||||
@@ -2136,7 +2147,7 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
int new_lock = region->lock;
|
int new_lock = region->lock;
|
||||||
@@ -2150,11 +2161,11 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
(*aspace->translation_map.ops->unlock)(&aspace->translation_map);
|
(*aspace->translation_map.ops->unlock)(&aspace->translation_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
release_sem_etc(map->sem, READ_COUNT, 0);
|
release_sem_etc(map->sem, READ_COUNT, 0);
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
if(dummy_page.state == PAGE_STATE_BUSY) {
|
if(dummy_page.state == PAGE_STATE_BUSY) {
|
||||||
vm_cache_ref *temp_cache = dummy_page.cache_ref;
|
vm_cache_ref *temp_cache = dummy_page.cache_ref;
|
||||||
@@ -2164,19 +2175,21 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
|||||||
dummy_page.state = PAGE_STATE_INACTIVE;
|
dummy_page.state = PAGE_STATE_INACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
vm_page_set_state(page, PAGE_STATE_ACTIVE);
|
vm_page_set_state(page, PAGE_STATE_ACTIVE);
|
||||||
|
|
||||||
vm_cache_release_ref(top_cache_ref);
|
vm_cache_release_ref(top_cache_ref);
|
||||||
vm_put_aspace(aspace);
|
vm_put_aspace(aspace);
|
||||||
|
|
||||||
TRACE;
|
TRACEPFAULT;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vm_region *vm_virtual_map_lookup(vm_virtual_map *map, addr address)
|
|
||||||
|
static vm_region *
|
||||||
|
vm_virtual_map_lookup(vm_virtual_map *map, addr address)
|
||||||
{
|
{
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user