diff options
author | Sergio Lopez <slp@sinrega.org> | 2011-12-29 22:30:12 +0100 |
---|---|---|
committer | Sergio Lopez <slp@sinrega.org> | 2011-12-29 22:30:12 +0100 |
commit | 666299d037be6ffa83345d6d281fa955431f55fe (patch) | |
tree | f63ff542ac6bbe6d6d99fa17348a5ca958685227 /vm/vm_resident.c | |
parent | 6af53cb9d48013971ad5fa37de173c1bbf73292a (diff) |
* include/mach/memory_object.h: Add MEMORY_OBJECT_COPY_VMPRIV to mark objects that can't be blocked even if dirty page limits has been exceeded.k0ro/advisory_pageout/master
* vm/memory_object.c (memory_object_data_supply): Mark pages provided by user as external.
* (memory_object_lock_request): Lock page queues before cleaning holding pages.
* (memory_object_set_attributes_common): Deal with MEMORY_OBJECT_COPY_VMPRIV.
* vm/vm_fault.c (vm_fault_page): If the number of potentially dirty pages has reached a certain static number, either request a pageout or block the thread.
* (vm_fault_page): Force an early request for a real page instead of a fictitious one.
* vm/vm_object.h (struct vm_object): New flag vm_privileged that relates with MEMORY_OBJECT_COPY_PRIV.
* vm/vm_object.c (vm_object_bootstrap): Initialize vm_privileged property as FALSE.
* vm/vm_page.h: Add variables vm_page_too_dirty, vm_page_dirty_count and vm_page_external_target.
* vm/vm_pageout.c: Adjust VM_PAGE_FREE_TARGET, VM_PAGE_FREE_MIN and VM_PAGE_EXTERNAL_LIMIT. Make vm_page_external_target signed.
* (vm_pageout_setup): Write lock cleaned pages. Adjust dirty page counters.
* (vm_pageout_scan): Try freeing clean external pages first. Disable broken old code.
* vm/vm_resident.c: Add variables vm_page_too_dirty and vm_page_dirty_count.
* (vm_page_convert.c): Propagate external argument to converted page.
* (vm_page_grab): Don't use old external page limits.
* (vm_page_grab_contiguous_pages): Likewise.
* (vm_page_wait): Likewise.
* (vm_page_release): Don't adjust external count.
* (vm_page_free): Adjust external and external-dirty counters here. Wake up blocked threads.
Diffstat (limited to 'vm/vm_resident.c')
-rw-r--r-- | vm/vm_resident.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/vm/vm_resident.c b/vm/vm_resident.c index 96354a45..d3db6869 100644 --- a/vm/vm_resident.c +++ b/vm/vm_resident.c @@ -162,6 +162,8 @@ int vm_page_inactive_target = 0; int vm_page_free_reserved = 0; int vm_page_laundry_count = 0; int vm_page_external_limit = 0; +int vm_page_too_dirty = 0; +int vm_page_dirty_count = 0; /* @@ -207,6 +209,7 @@ void vm_page_bootstrap( m->laundry = FALSE; m->free = FALSE; m->external = FALSE; + m->overwriting = FALSE; m->busy = TRUE; m->wanted = FALSE; @@ -838,6 +841,7 @@ boolean_t vm_page_convert( m->phys_addr = real_m->phys_addr; m->fictitious = FALSE; + m->external = external; real_m->phys_addr = vm_page_fictitious_addr; real_m->fictitious = TRUE; @@ -866,10 +870,8 @@ vm_page_t vm_page_grab( * for externally-managed pages. */ - if (((vm_page_free_count < vm_page_free_reserved) - || (external - && (vm_page_external_count > vm_page_external_limit))) - && !current_thread()->vm_privilege) { + if ((vm_page_free_count < vm_page_free_reserved) && + !current_thread()->vm_privilege) { simple_unlock(&vm_page_queue_free_lock); return VM_PAGE_NULL; } @@ -979,8 +981,7 @@ vm_page_grab_contiguous_pages( * Do not dip into the reserved pool. */ - if ((vm_page_free_count < vm_page_free_reserved) - || (vm_page_external_count >= vm_page_external_limit)) { + if (vm_page_free_count < vm_page_free_reserved) { printf_once("no more room for vm_page_grab_contiguous_pages"); simple_unlock(&vm_page_queue_free_lock); return KERN_RESOURCE_SHORTAGE; @@ -1163,8 +1164,6 @@ void vm_page_release( mem->pageq.next = (queue_entry_t) vm_page_queue_free; vm_page_queue_free = mem; vm_page_free_count++; - if (external) - vm_page_external_count--; /* * Check if we should wake up someone waiting for page. @@ -1215,8 +1214,7 @@ void vm_page_wait( */ simple_lock(&vm_page_queue_free_lock); - if ((vm_page_free_count < vm_page_free_target) - || (vm_page_external_count > vm_page_external_limit)) { + if (vm_page_free_count < vm_page_free_target) { if (vm_page_free_wanted++ == 0) thread_wakeup((event_t)&vm_page_free_wanted); assert_wait((event_t)&vm_page_free_count, FALSE); @@ -1292,6 +1290,19 @@ void vm_page_free( if (mem->absent) vm_object_absent_release(mem->object); + if (mem->external) { + vm_page_external_count--; + mem->external = FALSE; + if (mem->overwriting) { + vm_page_dirty_count--; + if (vm_page_too_dirty) { + vm_page_too_dirty--; + if (vm_page_too_dirty == 0) + thread_wakeup((event_t)&vm_page_too_dirty); + } + } + } + /* * XXX The calls to vm_page_init here are * really overkill. |