* The system now holds back a small reserve of committable memory and pages. The
memory and page reservation functions have a new "priority" parameter that indicates how deep the function may tap into that reserve. The currently existing priority levels are "user", "system", and "VIP". The idea is that user programs should never be able to cause a state that gets the kernel into trouble due to heavy battling for memory. The "VIP" level (not really used yet) is intended for allocations that are required to free memory eventually (in the page writer). More levels are thinkable in the future, like "user real time" or "user system server". * Added "priority" parameters to several VMCache methods. * Replaced the map_backing_store() "unmapAddressRange" parameter by a "flags" parameter. * Added area creation flag CREATE_AREA_PRIORITY_VIP and slab allocator flag CACHE_PRIORITY_VIP indicating the importance of the request. * Changed most code to pass the right priorities/flags. These changes already significantly improve the behavior in low memory situations. I've tested a bit with 64 MB (virtual) RAM and, while not particularly fast and responsive, the system remains at least usable under high memory pressure. As a side effect the slab allocator can now be used as general memory allocator. Not done by default yet, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35295 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -21,6 +21,7 @@ enum {
|
||||
/* object_cache_{alloc,free}() flags */
|
||||
CACHE_DONT_WAIT_FOR_MEMORY = 1 << 8,
|
||||
CACHE_DONT_LOCK_KERNEL_SPACE = 1 << 9,
|
||||
CACHE_PRIORITY_VIP = 1 << 10,
|
||||
|
||||
/* internal */
|
||||
CACHE_ALIGN_ON_SIZE = 1 << 30,
|
||||
|
||||
@@ -105,8 +105,9 @@ public:
|
||||
uint32 CountWritableAreas(VMArea* ignoreArea) const;
|
||||
|
||||
status_t WriteModified();
|
||||
status_t SetMinimalCommitment(off_t commitment);
|
||||
status_t Resize(off_t newSize);
|
||||
status_t SetMinimalCommitment(off_t commitment,
|
||||
int priority);
|
||||
status_t Resize(off_t newSize, int priority);
|
||||
|
||||
status_t FlushAndRemoveAllPages();
|
||||
|
||||
@@ -122,7 +123,7 @@ public:
|
||||
{ return fRefCount; }
|
||||
|
||||
// backing store operations
|
||||
virtual status_t Commit(off_t size);
|
||||
virtual status_t Commit(off_t size, int priority);
|
||||
virtual bool HasPage(off_t offset);
|
||||
|
||||
virtual status_t Read(off_t offset, const iovec *vecs,
|
||||
@@ -200,12 +201,13 @@ class VMCacheFactory {
|
||||
public:
|
||||
static status_t CreateAnonymousCache(VMCache*& cache,
|
||||
bool canOvercommit, int32 numPrecommittedPages,
|
||||
int32 numGuardPages, bool swappable);
|
||||
int32 numGuardPages, bool swappable,
|
||||
int priority);
|
||||
static status_t CreateVnodeCache(VMCache*& cache,
|
||||
struct vnode* vnode);
|
||||
static status_t CreateDeviceCache(VMCache*& cache,
|
||||
addr_t baseAddress);
|
||||
static status_t CreateNullCache(VMCache*& cache);
|
||||
static status_t CreateNullCache(int priority, VMCache*& cache);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,20 @@ struct vnode;
|
||||
#define CREATE_AREA_DONT_WAIT 0x01
|
||||
#define CREATE_AREA_UNMAP_ADDRESS_RANGE 0x02
|
||||
#define CREATE_AREA_DONT_CLEAR 0x04
|
||||
#define CREATE_AREA_PRIORITY_VIP 0x08
|
||||
|
||||
// memory/page allocation priorities
|
||||
#define VM_PRIORITY_USER 0
|
||||
#define VM_PRIORITY_SYSTEM 1
|
||||
#define VM_PRIORITY_VIP 2
|
||||
|
||||
// page reserves
|
||||
#define VM_PAGE_RESERVE_USER 512
|
||||
#define VM_PAGE_RESERVE_SYSTEM 128
|
||||
|
||||
// memory reserves
|
||||
#define VM_MEMORY_RESERVE_USER (VM_PAGE_RESERVE_USER * B_PAGE_SIZE)
|
||||
#define VM_MEMORY_RESERVE_SYSTEM (VM_PAGE_RESERVE_SYSTEM * B_PAGE_SIZE)
|
||||
|
||||
|
||||
extern struct ObjectCache* gPageMappingsObjectCache;
|
||||
@@ -84,7 +98,7 @@ area_id vm_map_file(team_id aid, const char *name, void **address,
|
||||
struct VMCache *vm_area_get_locked_cache(struct VMArea *area);
|
||||
void vm_area_put_locked_cache(struct VMCache *cache);
|
||||
area_id vm_create_null_area(team_id team, const char *name, void **address,
|
||||
uint32 addressSpec, addr_t size);
|
||||
uint32 addressSpec, addr_t size, uint32 flags);
|
||||
area_id vm_copy_area(team_id team, const char *name, void **_address,
|
||||
uint32 addressSpec, uint32 protection, area_id sourceID);
|
||||
area_id vm_clone_area(team_id team, const char *name, void **address,
|
||||
|
||||
@@ -46,13 +46,14 @@ void vm_page_schedule_write_page_range(struct VMCache *cache,
|
||||
uint32 firstPage, uint32 endPage);
|
||||
|
||||
void vm_page_unreserve_pages(uint32 count);
|
||||
void vm_page_reserve_pages(uint32 count);
|
||||
bool vm_page_try_reserve_pages(uint32 count);
|
||||
void vm_page_reserve_pages(uint32 count, int priority);
|
||||
bool vm_page_try_reserve_pages(uint32 count, int priority);
|
||||
|
||||
struct vm_page *vm_page_allocate_page(int pageState);
|
||||
struct vm_page *vm_page_allocate_page_run(int state, addr_t base,
|
||||
addr_t length);
|
||||
struct vm_page *vm_page_allocate_page_run_no_base(int state, addr_t count);
|
||||
addr_t length, int priority);
|
||||
struct vm_page *vm_page_allocate_page_run_no_base(int state, addr_t count,
|
||||
int priority);
|
||||
struct vm_page *vm_page_at_index(int32 index);
|
||||
struct vm_page *vm_lookup_page(addr_t pageNumber);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ extern "C" {
|
||||
status_t vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite,
|
||||
bool isUser, addr_t *newip);
|
||||
void vm_unreserve_memory(size_t bytes);
|
||||
status_t vm_try_reserve_memory(size_t bytes, bigtime_t timeout);
|
||||
status_t vm_try_reserve_memory(size_t bytes, int priority, bigtime_t timeout);
|
||||
void vm_schedule_page_scanner(uint32 target);
|
||||
status_t vm_daemon_init(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user