diff --git a/src/system/kernel/main.cpp b/src/system/kernel/main.cpp index 4dc31a1311..bea229b885 100644 --- a/src/system/kernel/main.cpp +++ b/src/system/kernel/main.cpp @@ -50,6 +50,8 @@ #include +#include "vm/VMAnonymousCache.h" + //#define TRACE_BOOT #ifdef TRACE_BOOT @@ -185,6 +187,10 @@ _start(kernel_args *bootKernelArgs, int currentCPU) notifications_init(); TRACE("init VFS\n"); vfs_init(&sKernelArgs); +#if ENABLE_SWAP_SUPPORT + TRACE("init swap support\n"); + swap_init(); +#endif // bring up the AP cpus in a lock step fashion TRACE("waking up AP cpus\n"); diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp index c3aa106ccb..4a902da2d5 100644 --- a/src/system/kernel/vm/VMAnonymousCache.cpp +++ b/src/system/kernel/vm/VMAnonymousCache.cpp @@ -22,6 +22,9 @@ #include #include + +#if ENABLE_SWAP_SUPPORT + //#define TRACE_STORE #ifdef TRACE_STORE # define TRACE(x) dprintf x @@ -725,3 +728,5 @@ swap_init(void) sAvailSwapSpace = 0; } +#endif // ENABLE_SWAP_SUPPORT + diff --git a/src/system/kernel/vm/VMAnonymousCache.h b/src/system/kernel/vm/VMAnonymousCache.h index 01913a4474..ed2d3506fe 100644 --- a/src/system/kernel/vm/VMAnonymousCache.h +++ b/src/system/kernel/vm/VMAnonymousCache.h @@ -12,6 +12,12 @@ #include +// uncomment to build in swap support +//#define ENABLE_SWAP_SUPPORT 1 + +#if ENABLE_SWAP_SUPPORT + + typedef page_num_t swap_addr_t; struct swap_block; @@ -49,4 +55,8 @@ private: }; +extern "C" void swap_init(void); + +#endif // ENABLE_SWAP_SUPPORT + #endif /* _KERNEL_VM_STORE_ANONYMOUS_H */ diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.h b/src/system/kernel/vm/VMAnonymousNoSwapCache.h index 5777b51bb1..c5a2bf77de 100644 --- a/src/system/kernel/vm/VMAnonymousNoSwapCache.h +++ b/src/system/kernel/vm/VMAnonymousNoSwapCache.h @@ -6,8 +6,8 @@ * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the NewOS License. */ -#ifndef _KERNEL_VM_STORE_ANONYMOUS_H -#define _KERNEL_VM_STORE_ANONYMOUS_H +#ifndef _KERNEL_VM_STORE_ANONYMOUS_NO_SWAP_H +#define _KERNEL_VM_STORE_ANONYMOUS_NO_SWAP_H #include @@ -39,4 +39,4 @@ private: }; -#endif /* _KERNEL_VM_STORE_ANONYMOUS_H */ +#endif /* _KERNEL_VM_STORE_ANONYMOUS_NO_SWAP_H */ diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 872ef5e5d5..c1d14dfa61 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -1401,7 +1401,7 @@ map_backing_store(vm_address_space *addressSpace, vm_cache *cache, // create an anonymous cache status = VMCacheFactory::CreateAnonymousCache(newCache, - (protection & B_STACK_AREA) != 0, 0, USER_STACK_GUARD_PAGES); + (protection & B_STACK_AREA) != 0, 0, USER_STACK_GUARD_PAGES, true); if (status != B_OK) goto err1; @@ -1639,7 +1639,8 @@ vm_create_anonymous_area(team_id team, const char *name, void **address, status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit, isStack ? 2 : 0, isStack ? ((protection & B_USER_PROTECTION) != 0 ? - USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0); + USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0, + wiring == B_NO_LOCK); if (status != B_OK) goto err1; @@ -2302,7 +2303,7 @@ vm_copy_on_write_area(vm_cache* lowerCache) // create an anonymous cache status_t status = VMCacheFactory::CreateAnonymousCache(upperCache, false, 0, - 0); + 0, true); if (status != B_OK) return status; diff --git a/src/system/kernel/vm/vm_cache.cpp b/src/system/kernel/vm/vm_cache.cpp index e68bac59bf..e401d1a2a5 100644 --- a/src/system/kernel/vm/vm_cache.cpp +++ b/src/system/kernel/vm/vm_cache.cpp @@ -961,6 +961,7 @@ VMCache::_RemoveConsumer(VMCache* consumer) #include +#include "VMAnonymousCache.h" #include "VMAnonymousNoSwapCache.h" #include "VMDeviceCache.h" #include "VMNullCache.h" @@ -969,8 +970,28 @@ VMCache::_RemoveConsumer(VMCache* consumer) /*static*/ status_t VMCacheFactory::CreateAnonymousCache(VMCache*& _cache, bool canOvercommit, - int32 numPrecommittedPages, int32 numGuardPages) + int32 numPrecommittedPages, int32 numGuardPages, bool swappable) { +#if ENABLE_SWAP_SUPPORT + if (swappable) { + VMAnonymousCache* cache = new(nogrow) VMAnonymousCache; + if (cache == NULL) + return B_NO_MEMORY; + + status_t error = cache->Init(canOvercommit, numPrecommittedPages, + numGuardPages); + if (error != B_OK) { + cache->Delete(); + return error; + } + + T(Create(cache)); + + _cache = cache; + return B_OK; + } +#endif + VMAnonymousNoSwapCache* cache = new(nogrow) VMAnonymousNoSwapCache; if (cache == NULL) return B_NO_MEMORY; diff --git a/src/system/kernel/vm/vm_page.cpp b/src/system/kernel/vm/vm_page.cpp index c662fb8e7f..f0f47f7f14 100644 --- a/src/system/kernel/vm/vm_page.cpp +++ b/src/system/kernel/vm/vm_page.cpp @@ -989,10 +989,16 @@ page_writer(void* /*unused*/) continue; vm_cache *cache = page->cache; - // TODO: write back temporary ones as soon as we have swap file support - if (cache->temporary - /*&& low_resource_state(B_KERNEL_RESOURCE_PAGES) - == B_NO_LOW_RESOURCE*/) { + + // Don't write back wired (locked) pages and don't write RAM pages + // until we're low on pages. + if (page->wired_count > 0 +#if ENABLE_SWAP_SUPPORT + || cache->temporary + && low_resource_state(B_KERNEL_RESOURCE_PAGES) + == B_NO_LOW_RESOURCE +#endif + ) { continue; }