Added an additional flag B_OVERCOMMITTING_AREA (currently to be specified
along the protection flags). Changed the handling of B_STACK_AREA types and anonymous vm_areas: now every area can overcommit if B_OVERCOMMITTING_AREA was specified. B_STACK_AREA areas are still automatically overcommitting, but B_KERNEL_STACK_AREA areas no longer. vm_store_anonymous_noswap.c now only tests for guard pages if there were any specified which is only done for B_STACK_AREA areas. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12673 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004, Axel Dörfler, [email protected].
|
||||
/*
|
||||
* Copyright 2004-2005, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@@ -8,8 +8,13 @@
|
||||
#ifndef _KERNEL_VM_STORE_ANONYMOUS_H
|
||||
#define _KERNEL_VM_STORE_ANONYMOUS_H
|
||||
|
||||
|
||||
#include <vm_types.h>
|
||||
|
||||
vm_store *vm_store_create_anonymous_noswap(bool stack, int32 numGuardPages);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
vm_store *vm_store_create_anonymous_noswap(bool canOvercommit, int32 numGuardPages);
|
||||
|
||||
#endif /* _KERNEL_VM_STORE_ANONYMOUS_H */
|
||||
|
||||
@@ -187,7 +187,13 @@ enum {
|
||||
(B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_EXECUTE_AREA \
|
||||
| B_KERNEL_STACK_AREA)
|
||||
|
||||
#define B_OVERCOMMITTING_AREA 0x1000
|
||||
// ToDo: this is not really a protection flag, but since the "protection"
|
||||
// field is the only flag field, we currently use it for this.
|
||||
// A cleaner approach would be appreciated - maybe just an official generic
|
||||
// flags region in the protection field.
|
||||
|
||||
#define B_USER_AREA_FLAGS (B_USER_PROTECTION)
|
||||
#define B_KERNEL_AREA_FLAGS (B_KERNEL_PROTECTION | B_USER_CLONEABLE_AREA)
|
||||
#define B_KERNEL_AREA_FLAGS (B_KERNEL_PROTECTION | B_USER_CLONEABLE_AREA | B_OVERCOMMITTING_AREA)
|
||||
|
||||
#endif /* _KERNEL_VM_TYPES_H */
|
||||
|
||||
@@ -674,6 +674,7 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
|
||||
vm_cache_ref *cache_ref;
|
||||
vm_page *page = NULL;
|
||||
bool isStack = (protection & B_STACK_AREA) != 0;
|
||||
bool canOvercommit = false;
|
||||
status_t err;
|
||||
|
||||
TRACE(("create_anonymous_area %s: size 0x%lx\n", name, size));
|
||||
@@ -681,6 +682,9 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
|
||||
if (!arch_vm_supports_protection(protection))
|
||||
return B_NOT_SUPPORTED;
|
||||
|
||||
if (isStack || (protection & B_OVERCOMMITTING_AREA) != 0)
|
||||
canOvercommit = true;
|
||||
|
||||
#ifdef DEBUG_KERNEL_STACKS
|
||||
if ((protection & B_KERNEL_STACK_AREA) != 0)
|
||||
isStack = true;
|
||||
@@ -730,8 +734,9 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
|
||||
}
|
||||
|
||||
// create an anonymous store object
|
||||
store = vm_store_create_anonymous_noswap(isStack, (protection & B_USER_PROTECTION) != 0 ?
|
||||
USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES);
|
||||
store = vm_store_create_anonymous_noswap(canOvercommit, isStack ?
|
||||
((protection & B_USER_PROTECTION) != 0 ?
|
||||
USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0);
|
||||
if (store == NULL)
|
||||
panic("vm_create_anonymous_area: vm_create_store_anonymous_noswap returned NULL");
|
||||
cache = vm_cache_create(store);
|
||||
@@ -755,8 +760,6 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
|
||||
break;
|
||||
}
|
||||
|
||||
// dprintf("create_anonymous_area: calling map_backing store\n");
|
||||
|
||||
vm_cache_acquire_ref(cache_ref, true);
|
||||
err = map_backing_store(aspace, store, address, 0, size, addressSpec, wiring, protection, REGION_NO_PRIVATE_MAP, &area, name);
|
||||
vm_cache_release_ref(cache_ref);
|
||||
@@ -778,8 +781,6 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
|
||||
return err;
|
||||
}
|
||||
|
||||
// dprintf("create_anonymous_area: done calling map_backing store\n");
|
||||
|
||||
cache_ref = store->cache->ref;
|
||||
switch (wiring) {
|
||||
case B_NO_LOCK:
|
||||
@@ -788,10 +789,11 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
|
||||
|
||||
case B_FULL_LOCK:
|
||||
{
|
||||
// pages aren't mapped at this point, but we just simulate a fault on
|
||||
// Pages aren't mapped at this point, but we just simulate a fault on
|
||||
// every page, which should allocate them
|
||||
// ToDo: at this point, it would probably be cheaper to allocate
|
||||
// and map the pages directly
|
||||
addr_t va;
|
||||
// XXX remove
|
||||
for (va = area->base; va < area->base + area->size; va += B_PAGE_SIZE) {
|
||||
#ifdef DEBUG_KERNEL_STACKS
|
||||
# ifdef STACK_GROWS_DOWNWARDS
|
||||
@@ -877,7 +879,7 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
|
||||
}
|
||||
vm_put_aspace(aspace);
|
||||
|
||||
// dprintf("create_anonymous_area: done\n");
|
||||
TRACE(("vm_create_anonymous_area: done\n"));
|
||||
|
||||
if (area == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@@ -24,11 +24,12 @@
|
||||
|
||||
// The stack functionality looks like a good candidate to put into its own
|
||||
// store. I have not done this because once we have a swap file backing up
|
||||
// the memory, it would probably not a good idea to separate this anymore.
|
||||
// the memory, it would probably not be a good idea to separate this
|
||||
// anymore.
|
||||
|
||||
typedef struct anonymous_store {
|
||||
vm_store vm;
|
||||
bool is_stack;
|
||||
bool can_overcommit;
|
||||
int32 guarded_size;
|
||||
} anonymous_store;
|
||||
|
||||
@@ -46,8 +47,8 @@ anonymous_commit(struct vm_store *_store, off_t size)
|
||||
{
|
||||
anonymous_store *store = (anonymous_store *)_store;
|
||||
|
||||
// if we're a stack, we don't commit here, but in anonymous_fault()
|
||||
if (store->is_stack)
|
||||
// if we can overcommit, we don't commit here, but in anonymous_fault()
|
||||
if (store->can_overcommit)
|
||||
return B_OK;
|
||||
|
||||
// Check to see how much we could commit - we need real memory
|
||||
@@ -95,21 +96,23 @@ anonymous_fault(struct vm_store *_store, struct vm_address_space *aspace, off_t
|
||||
{
|
||||
anonymous_store *store = (anonymous_store *)_store;
|
||||
|
||||
if (store->is_stack) {
|
||||
uint32 guardOffset;
|
||||
if (store->can_overcommit) {
|
||||
if (store->guarded_size > 0) {
|
||||
uint32 guardOffset;
|
||||
|
||||
#ifdef STACK_GROWS_DOWNWARDS
|
||||
guardOffset = 0;
|
||||
guardOffset = 0;
|
||||
#elif defined(STACK_GROWS_UPWARDS)
|
||||
guardOffset = store->vm.cache->virtual_size - store->guarded_size;
|
||||
guardOffset = store->vm.cache->virtual_size - store->guarded_size;
|
||||
#else
|
||||
# error Stack direction has not been defined in arch_config.h
|
||||
#endif
|
||||
|
||||
// report stack fault, guard page hit!
|
||||
if (offset >= guardOffset && offset < guardOffset + store->guarded_size) {
|
||||
TRACE(("stack overflow!\n"));
|
||||
return B_BAD_ADDRESS;
|
||||
// report stack fault, guard page hit!
|
||||
if (offset >= guardOffset && offset < guardOffset + store->guarded_size) {
|
||||
TRACE(("stack overflow!\n"));
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
// try to commit additional memory
|
||||
@@ -141,19 +144,19 @@ static vm_store_ops anonymous_ops = {
|
||||
*/
|
||||
|
||||
vm_store *
|
||||
vm_store_create_anonymous_noswap(bool stack, int32 numGuardPages)
|
||||
vm_store_create_anonymous_noswap(bool canOvercommit, int32 numGuardPages)
|
||||
{
|
||||
anonymous_store *store = malloc(sizeof(anonymous_store));
|
||||
if (store == NULL)
|
||||
return NULL;
|
||||
|
||||
TRACE(("vm_store_create_anonymous(stack = %s, numGuardPages = %ld) at %p\n",
|
||||
stack ? "true" : "false", numGuardPages, store));
|
||||
TRACE(("vm_store_create_anonymous(canOvercommit = %s, numGuardPages = %ld) at %p\n",
|
||||
canOvercommit ? "yes" : "no", numGuardPages, store));
|
||||
|
||||
store->vm.ops = &anonymous_ops;
|
||||
store->vm.cache = NULL;
|
||||
store->vm.committed_size = 0;
|
||||
store->is_stack = stack;
|
||||
store->can_overcommit = canOvercommit;
|
||||
store->guarded_size = numGuardPages * B_PAGE_SIZE;
|
||||
|
||||
return &store->vm;
|
||||
|
||||
Reference in New Issue
Block a user