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
This commit is contained in:
Ingo Weinhold 2008-08-04 03:28:46 +00:00
parent 8eabecf603
commit 355604212d
3 changed files with 58 additions and 3 deletions

View File

@ -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);

View File

@ -10,7 +10,11 @@
#include "VMAnonymousCache.h"
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arch_config.h>
#include <heap.h>
@ -18,9 +22,11 @@
#include <slab/Slab.h>
#include <vfs.h>
#include <vm.h>
#include <vm_page.h>
#include <vm_priv.h>
#include <util/DoublyLinkedList.h>
#include <util/OpenHashTable.h>
#include <driver_settings.h>
#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

View File

@ -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