* The kernel's address space is now also a resource that is known to the low
resource manager. * Could be drastically improved, though, by taking the fragmentation into account. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34309 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Ingo Weinhold, [email protected].
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2005-2007, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _KERNEL_LOW_RESOURCE_MANAGER_H
|
#ifndef _KERNEL_LOW_RESOURCE_MANAGER_H
|
||||||
@@ -22,10 +22,12 @@ enum {
|
|||||||
B_KERNEL_RESOURCE_PAGES = 0x01, /* physical pages */
|
B_KERNEL_RESOURCE_PAGES = 0x01, /* physical pages */
|
||||||
B_KERNEL_RESOURCE_MEMORY = 0x02, /* reservable memory */
|
B_KERNEL_RESOURCE_MEMORY = 0x02, /* reservable memory */
|
||||||
B_KERNEL_RESOURCE_SEMAPHORES = 0x04, /* semaphores */
|
B_KERNEL_RESOURCE_SEMAPHORES = 0x04, /* semaphores */
|
||||||
|
B_KERNEL_RESOURCE_ADDRESS_SPACE = 0x08, /* address space */
|
||||||
|
|
||||||
B_ALL_KERNEL_RESOURCES = B_KERNEL_RESOURCE_PAGES
|
B_ALL_KERNEL_RESOURCES = B_KERNEL_RESOURCE_PAGES
|
||||||
| B_KERNEL_RESOURCE_MEMORY
|
| B_KERNEL_RESOURCE_MEMORY
|
||||||
| B_KERNEL_RESOURCE_SEMAPHORES
|
| B_KERNEL_RESOURCE_SEMAPHORES
|
||||||
|
| B_KERNEL_RESOURCE_ADDRESS_SPACE
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*low_resource_func)(void *data, uint32 resources, int32 level);
|
typedef void (*low_resource_func)(void *data, uint32 resources, int32 level);
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ void vm_get_info(struct system_memory_info *info);
|
|||||||
uint32 vm_num_page_faults(void);
|
uint32 vm_num_page_faults(void);
|
||||||
off_t vm_available_memory(void);
|
off_t vm_available_memory(void);
|
||||||
off_t vm_available_not_needed_memory(void);
|
off_t vm_available_not_needed_memory(void);
|
||||||
|
size_t vm_kernel_address_space_left(void);
|
||||||
|
|
||||||
status_t vm_memset_physical(addr_t address, int value, size_t length);
|
status_t vm_memset_physical(addr_t address, int value, size_t length);
|
||||||
status_t vm_memcpy_from_physical(void* to, addr_t from, size_t length,
|
status_t vm_memcpy_from_physical(void* to, addr_t from, size_t length,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Ingo Weinhold, [email protected].
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2005-2008, Axel Dörfler, [email protected].
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
struct low_resource_handler
|
struct low_resource_handler
|
||||||
: public DoublyLinkedListLinkImpl<low_resource_handler> {
|
: public DoublyLinkedListLinkImpl<low_resource_handler> {
|
||||||
low_resource_func function;
|
low_resource_func function;
|
||||||
void *data;
|
void* data;
|
||||||
uint32 resources;
|
uint32 resources;
|
||||||
int32 priority;
|
int32 priority;
|
||||||
};
|
};
|
||||||
@@ -63,6 +63,7 @@ static off_t sCriticalMemoryLimit;
|
|||||||
static int32 sLowPagesState = B_NO_LOW_RESOURCE;
|
static int32 sLowPagesState = B_NO_LOW_RESOURCE;
|
||||||
static int32 sLowMemoryState = B_NO_LOW_RESOURCE;
|
static int32 sLowMemoryState = B_NO_LOW_RESOURCE;
|
||||||
static int32 sLowSemaphoresState = B_NO_LOW_RESOURCE;
|
static int32 sLowSemaphoresState = B_NO_LOW_RESOURCE;
|
||||||
|
static int32 sLowSpaceState = B_NO_LOW_RESOURCE;
|
||||||
static uint32 sLowResources = 0; // resources that are not B_NO_LOW_RESOURCE
|
static uint32 sLowResources = 0; // resources that are not B_NO_LOW_RESOURCE
|
||||||
static bigtime_t sLastMeasurement;
|
static bigtime_t sLastMeasurement;
|
||||||
|
|
||||||
@@ -85,6 +86,8 @@ low_resource_state_no_update(uint32 resources)
|
|||||||
state = max_c(state, sLowMemoryState);
|
state = max_c(state, sLowMemoryState);
|
||||||
if ((resources & B_KERNEL_RESOURCE_SEMAPHORES) != 0)
|
if ((resources & B_KERNEL_RESOURCE_SEMAPHORES) != 0)
|
||||||
state = max_c(state, sLowSemaphoresState);
|
state = max_c(state, sLowSemaphoresState);
|
||||||
|
if ((resources & B_KERNEL_RESOURCE_ADDRESS_SPACE) != 0)
|
||||||
|
state = max_c(state, sLowSpaceState);
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@@ -104,7 +107,7 @@ call_handlers(uint32 lowResources)
|
|||||||
low_resource_handler marker;
|
low_resource_handler marker;
|
||||||
sLowResourceHandlers.Insert(&marker, false);
|
sLowResourceHandlers.Insert(&marker, false);
|
||||||
|
|
||||||
while (low_resource_handler *handler
|
while (low_resource_handler* handler
|
||||||
= sLowResourceHandlers.GetNext(&marker)) {
|
= sLowResourceHandlers.GetNext(&marker)) {
|
||||||
// swap with handler
|
// swap with handler
|
||||||
sLowResourceHandlers.Swap(&marker, handler);
|
sLowResourceHandlers.Swap(&marker, handler);
|
||||||
@@ -173,11 +176,27 @@ compute_state(void)
|
|||||||
sLowSemaphoresState = B_NO_LOW_RESOURCE;
|
sLowSemaphoresState = B_NO_LOW_RESOURCE;
|
||||||
sLowResources &= ~B_KERNEL_RESOURCE_SEMAPHORES;
|
sLowResources &= ~B_KERNEL_RESOURCE_SEMAPHORES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// free kernel address space state
|
||||||
|
// TODO: this should take fragmentation into account
|
||||||
|
size_t maxSpace = KERNEL_SIZE;
|
||||||
|
size_t freeSpace = vm_kernel_address_space_left();
|
||||||
|
|
||||||
|
if (freeSpace < maxSpace >> 16)
|
||||||
|
sLowSpaceState = B_LOW_RESOURCE_CRITICAL;
|
||||||
|
if (freeSpace < maxSpace >> 8)
|
||||||
|
sLowSpaceState = B_LOW_RESOURCE_WARNING;
|
||||||
|
if (freeSpace < maxSpace >> 4)
|
||||||
|
sLowSpaceState = B_LOW_RESOURCE_NOTE;
|
||||||
|
else {
|
||||||
|
sLowSpaceState = B_NO_LOW_RESOURCE;
|
||||||
|
sLowResources &= ~B_KERNEL_RESOURCE_ADDRESS_SPACE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32
|
static status_t
|
||||||
low_resource_manager(void *)
|
low_resource_manager(void*)
|
||||||
{
|
{
|
||||||
bigtime_t timeout = kLowResourceInterval;
|
bigtime_t timeout = kLowResourceInterval;
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -231,15 +250,17 @@ state_to_string(uint32 state)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dump_handlers(int argc, char **argv)
|
dump_handlers(int argc, char** argv)
|
||||||
{
|
{
|
||||||
kprintf("current state: %c%c%c\n",
|
kprintf("current state: %c%c%c%c\n",
|
||||||
(sLowResources & B_KERNEL_RESOURCE_PAGES) != 0 ? 'p' : '-',
|
(sLowResources & B_KERNEL_RESOURCE_PAGES) != 0 ? 'p' : '-',
|
||||||
(sLowResources & B_KERNEL_RESOURCE_MEMORY) != 0 ? 'm' : '-',
|
(sLowResources & B_KERNEL_RESOURCE_MEMORY) != 0 ? 'm' : '-',
|
||||||
(sLowResources & B_KERNEL_RESOURCE_SEMAPHORES) != 0 ? 's' : '-');
|
(sLowResources & B_KERNEL_RESOURCE_SEMAPHORES) != 0 ? 's' : '-',
|
||||||
|
(sLowResources & B_KERNEL_RESOURCE_ADDRESS_SPACE) != 0 ? 'a' : '-');
|
||||||
kprintf(" pages: %s\n", state_to_string(sLowPagesState));
|
kprintf(" pages: %s\n", state_to_string(sLowPagesState));
|
||||||
kprintf(" memory: %s\n", state_to_string(sLowMemoryState));
|
kprintf(" memory: %s\n", state_to_string(sLowMemoryState));
|
||||||
kprintf(" sems: %s\n\n", state_to_string(sLowSemaphoresState));
|
kprintf(" sems: %s\n", state_to_string(sLowSemaphoresState));
|
||||||
|
kprintf(" aspace: %s\n\n", state_to_string(sLowSpaceState));
|
||||||
|
|
||||||
HandlerList::Iterator iterator = sLowResourceHandlers.GetIterator();
|
HandlerList::Iterator iterator = sLowResourceHandlers.GetIterator();
|
||||||
kprintf("function data resources prio function-name\n");
|
kprintf("function data resources prio function-name\n");
|
||||||
@@ -282,9 +303,10 @@ low_resource(uint32 resource, uint64 requirements, uint32 flags, uint32 timeout)
|
|||||||
case B_KERNEL_RESOURCE_PAGES:
|
case B_KERNEL_RESOURCE_PAGES:
|
||||||
vm_schedule_page_scanner(requirements);
|
vm_schedule_page_scanner(requirements);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_KERNEL_RESOURCE_MEMORY:
|
case B_KERNEL_RESOURCE_MEMORY:
|
||||||
break;
|
|
||||||
case B_KERNEL_RESOURCE_SEMAPHORES:
|
case B_KERNEL_RESOURCE_SEMAPHORES:
|
||||||
|
case B_KERNEL_RESOURCE_ADDRESS_SPACE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +376,7 @@ low_resource_manager_init_post_thread(void)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
unregister_low_resource_handler(low_resource_func function, void *data)
|
unregister_low_resource_handler(low_resource_func function, void* data)
|
||||||
{
|
{
|
||||||
TRACE(("unregister_low_resource_handler(function = %p, data = %p)\n",
|
TRACE(("unregister_low_resource_handler(function = %p, data = %p)\n",
|
||||||
function, data));
|
function, data));
|
||||||
@@ -363,7 +385,7 @@ unregister_low_resource_handler(low_resource_func function, void *data)
|
|||||||
HandlerList::Iterator iterator = sLowResourceHandlers.GetIterator();
|
HandlerList::Iterator iterator = sLowResourceHandlers.GetIterator();
|
||||||
|
|
||||||
while (iterator.HasNext()) {
|
while (iterator.HasNext()) {
|
||||||
low_resource_handler *handler = iterator.Next();
|
low_resource_handler* handler = iterator.Next();
|
||||||
|
|
||||||
if (handler->function == function && handler->data == data) {
|
if (handler->function == function && handler->data == data) {
|
||||||
sLowResourceHandlers.Remove(handler);
|
sLowResourceHandlers.Remove(handler);
|
||||||
@@ -380,13 +402,13 @@ unregister_low_resource_handler(low_resource_func function, void *data)
|
|||||||
the handler will be called in low resource situations.
|
the handler will be called in low resource situations.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
register_low_resource_handler(low_resource_func function, void *data,
|
register_low_resource_handler(low_resource_func function, void* data,
|
||||||
uint32 resources, int32 priority)
|
uint32 resources, int32 priority)
|
||||||
{
|
{
|
||||||
TRACE(("register_low_resource_handler(function = %p, data = %p)\n",
|
TRACE(("register_low_resource_handler(function = %p, data = %p)\n",
|
||||||
function, data));
|
function, data));
|
||||||
|
|
||||||
low_resource_handler *newHandler = (low_resource_handler *)malloc(
|
low_resource_handler *newHandler = (low_resource_handler*)malloc(
|
||||||
sizeof(low_resource_handler));
|
sizeof(low_resource_handler));
|
||||||
if (newHandler == NULL)
|
if (newHandler == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -402,7 +424,7 @@ register_low_resource_handler(low_resource_func function, void *data,
|
|||||||
|
|
||||||
HandlerList::ReverseIterator iterator
|
HandlerList::ReverseIterator iterator
|
||||||
= sLowResourceHandlers.GetReverseIterator();
|
= sLowResourceHandlers.GetReverseIterator();
|
||||||
low_resource_handler *last = NULL;
|
low_resource_handler* last = NULL;
|
||||||
while (iterator.HasNext()) {
|
while (iterator.HasNext()) {
|
||||||
low_resource_handler *handler = iterator.Next();
|
low_resource_handler *handler = iterator.Next();
|
||||||
|
|
||||||
|
|||||||
@@ -227,6 +227,9 @@ static status_t map_backing_store(vm_address_space* addressSpace,
|
|||||||
vm_area** _area, const char* areaName, bool unmapAddressRange, bool kernel);
|
vm_area** _area, const char* areaName, bool unmapAddressRange, bool kernel);
|
||||||
|
|
||||||
|
|
||||||
|
static size_t sKernelAddressSpaceLeft = KERNEL_SIZE;
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -1383,8 +1386,12 @@ insert_area(vm_address_space* addressSpace, void** _address,
|
|||||||
|
|
||||||
status = find_and_insert_area_slot(addressSpace, searchBase, size,
|
status = find_and_insert_area_slot(addressSpace, searchBase, size,
|
||||||
searchEnd, addressSpec, area);
|
searchEnd, addressSpec, area);
|
||||||
if (status == B_OK)
|
if (status == B_OK) {
|
||||||
*_address = (void*)area->base;
|
*_address = (void*)area->base;
|
||||||
|
|
||||||
|
if (addressSpace == vm_kernel_address_space())
|
||||||
|
sKernelAddressSpaceLeft -= area->size;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -1668,8 +1675,16 @@ map_backing_store(vm_address_space* addressSpace, vm_cache* cache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = insert_area(addressSpace, _virtualAddress, addressSpec, size, area);
|
status = insert_area(addressSpace, _virtualAddress, addressSpec, size, area);
|
||||||
if (status != B_OK)
|
if (status != B_OK) {
|
||||||
|
// TODO: wait and try again once this is working in the backend
|
||||||
|
#if 0
|
||||||
|
if (status == B_NO_MEMORY && addressSpec == B_ANY_KERNEL_ADDRESS) {
|
||||||
|
low_resource(B_KERNEL_RESOURCE_ADDRESS_SPACE, size,
|
||||||
|
0, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
goto err2;
|
goto err2;
|
||||||
|
}
|
||||||
|
|
||||||
// attach the cache to the area
|
// attach the cache to the area
|
||||||
area->cache = cache;
|
area->cache = cache;
|
||||||
@@ -2006,7 +2021,7 @@ vm_create_anonymous_area(team_id team, const char* name, void** address,
|
|||||||
addressSpec, wiring, protection, REGION_NO_PRIVATE_MAP, &area, name,
|
addressSpec, wiring, protection, REGION_NO_PRIVATE_MAP, &area, name,
|
||||||
(flags & CREATE_AREA_UNMAP_ADDRESS_RANGE) != 0, kernel);
|
(flags & CREATE_AREA_UNMAP_ADDRESS_RANGE) != 0, kernel);
|
||||||
|
|
||||||
if (status < B_OK) {
|
if (status != B_OK) {
|
||||||
cache->ReleaseRefAndUnlock();
|
cache->ReleaseRefAndUnlock();
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
@@ -2751,6 +2766,9 @@ remove_area_from_address_space(vm_address_space* addressSpace, vm_area* area)
|
|||||||
if (area == addressSpace->area_hint)
|
if (area == addressSpace->area_hint)
|
||||||
addressSpace->area_hint = NULL;
|
addressSpace->area_hint = NULL;
|
||||||
|
|
||||||
|
if (addressSpace == vm_kernel_address_space())
|
||||||
|
sKernelAddressSpaceLeft -= area->size;
|
||||||
|
|
||||||
if (temp == NULL)
|
if (temp == NULL)
|
||||||
panic("vm_area_release_ref: area not found in aspace's area list\n");
|
panic("vm_area_release_ref: area not found in aspace's area list\n");
|
||||||
}
|
}
|
||||||
@@ -5264,6 +5282,13 @@ vm_available_not_needed_memory(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
vm_kernel_address_space_left(void)
|
||||||
|
{
|
||||||
|
return sKernelAddressSpaceLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
vm_unreserve_memory(size_t amount)
|
vm_unreserve_memory(size_t amount)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user