From 355604212d43a7a476436ee0df209043d52c0872 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 4 Aug 2008 03:28:46 +0000 Subject: [PATCH] Patch by Zhao Shuai with changes by myself: * Keep track of the stack space actually allocated for the cache and let Write() fail when we've already allocated as much as reserved. * Added second phase of swap initialization (swap_init_post_modules()) which reads the virtual memory driver settings and creates/resizes a swap file. ATM truncate() is used to resize the swap file, but that is a bit slow. We should probably introduce a VFS function to use BFS's fast method. This should make swap support work somewhat, but since swap space is never freed ATM this would be a relatively short pleasure. Still disabled by default. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26783 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/main.cpp | 5 +++ src/system/kernel/vm/VMAnonymousCache.cpp | 50 ++++++++++++++++++++++- src/system/kernel/vm/VMAnonymousCache.h | 6 ++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/main.cpp b/src/system/kernel/main.cpp index 9cc1d9bdae..194cafae2b 100644 --- a/src/system/kernel/main.cpp +++ b/src/system/kernel/main.cpp @@ -273,6 +273,11 @@ main2(void *unused) boot_splash_set_stage(BOOT_SPLASH_STAGE_4_MOUNT_BOOT_FS); vfs_mount_boot_file_system(&sKernelArgs); +#if ENABLE_SWAP_SUPPORT + TRACE("swap_init_post_modules\n"); + swap_init_post_modules(); +#endif + // CPU specific modules may now be available boot_splash_set_stage(BOOT_SPLASH_STAGE_5_INIT_CPU_MODULES); cpu_init_post_modules(&sKernelArgs); diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp index d90901c27b..8a92a6f95b 100644 --- a/src/system/kernel/vm/VMAnonymousCache.cpp +++ b/src/system/kernel/vm/VMAnonymousCache.cpp @@ -10,7 +10,11 @@ #include "VMAnonymousCache.h" +#include +#include #include +#include +#include #include #include @@ -18,9 +22,11 @@ #include #include #include +#include #include #include #include +#include #if ENABLE_SWAP_SUPPORT @@ -152,6 +158,7 @@ VMAnonymousCache::Init(bool canOvercommit, int32 numPrecommittedPages, fPrecommittedPages = min_c(numPrecommittedPages, 255); fGuardedSize = numGuardPages * B_PAGE_SIZE; fCommittedSwapSize = 0; + fAllocatedSwapSize = 0; return B_OK; } @@ -223,6 +230,9 @@ status_t VMAnonymousCache::Write(off_t offset, const iovec *vecs, size_t count, size_t *_numBytes) { + if (fAllocatedSwapSize + count * PAGE_SIZE > fCommittedSwapSize) + return B_ERROR; + offset >>= PAGE_SHIFT; uint32 n = count; for (uint32 i = 0; i < count; i += n) { @@ -234,6 +244,8 @@ VMAnonymousCache::Write(off_t offset, const iovec *vecs, size_t count, if (pageIndex == SWAP_PAGE_NONE) panic("can't allocate swap space\n"); + fAllocatedSwapSize += n * PAGE_SIZE; + for (uint32 j = 0; j < n; j++) _SwapBlockBuild(offset + i + j, pageIndex + j); @@ -244,7 +256,6 @@ VMAnonymousCache::Write(off_t offset, const iovec *vecs, size_t count, } off_t pos = (pageIndex - swapFile->first_page) * PAGE_SIZE; - status_t status = vfs_write_pages(swapFile->vnode, NULL, pos, vecs + i, n, 0, _numBytes); if (status != B_OK) @@ -728,5 +739,40 @@ swap_init(void) sAvailSwapSpace = 0; } -#endif // ENABLE_SWAP_SUPPORT +void +swap_init_post_modules() +{ + off_t size = 0; + void *settings = load_driver_settings("virtual_memory"); + if (settings != NULL) { + if (!get_driver_boolean_parameter(settings, "vm", false, false)) + return; + + const char *string = get_driver_parameter(settings, "swap_size", NULL, + NULL); + size = string ? atoll(string) : 0; + + unload_driver_settings(settings); + } else + size = vm_page_num_pages() * B_PAGE_SIZE * 2; + + if (size < B_PAGE_SIZE) + return; + + int fd = open("/var/swap", O_RDWR | O_CREAT | O_NOCACHE, S_IRUSR | S_IWUSR); + if (fd < 0) { + dprintf("Can't open/create /var/swap: %s\n", strerror(errno)); + return; + } + close(fd); + + if (truncate("/var/swap", size) < 0) { + dprintf("Failed to resize /var/swap to %lld bytes: %s\n", size, + strerror(errno)); + } + + swap_file_add("/var/swap"); +} + +#endif // ENABLE_SWAP_SUPPORT diff --git a/src/system/kernel/vm/VMAnonymousCache.h b/src/system/kernel/vm/VMAnonymousCache.h index fdbfae59be..10fd48dddc 100644 --- a/src/system/kernel/vm/VMAnonymousCache.h +++ b/src/system/kernel/vm/VMAnonymousCache.h @@ -48,10 +48,14 @@ private: uint8 fPrecommittedPages; int32 fGuardedSize; off_t fCommittedSwapSize; + off_t fAllocatedSwapSize; }; -extern "C" void swap_init(void); +extern "C" { + void swap_init(void); + void swap_init_post_modules(); +} #endif // ENABLE_SWAP_SUPPORT