Implemented new function vm_page_write_modified() that writes all dirty
pages in a cache back using the store's write method. Doesn't optimize disk access yet. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10204 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
257d99f228
commit
86b5aa8df9
@ -1,10 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2002-2004, The Haiku Team. All rights reserved.
|
* Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de.
|
||||||
** Distributed under the terms of the Haiku License.
|
* Distributed under the terms of the MIT License.
|
||||||
**
|
*
|
||||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||||
** Distributed under the terms of the NewOS License.
|
* Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
@ -127,6 +128,94 @@ move_page_to_queue(page_queue *from_q, page_queue *to_q, vm_page *page)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
write_page(vm_page *page)
|
||||||
|
{
|
||||||
|
vm_store *store = page->cache->store;
|
||||||
|
size_t length = B_PAGE_SIZE;
|
||||||
|
status_t status;
|
||||||
|
iovec vecs[1];
|
||||||
|
|
||||||
|
TRACE(("write_page(page = %p): offset = %Ld\n", page, page->offset));
|
||||||
|
|
||||||
|
vm_get_physical_page(page->ppn * B_PAGE_SIZE, (addr_t *)&vecs[0].iov_base, PHYSICAL_PAGE_CAN_WAIT);
|
||||||
|
vecs->iov_len = B_PAGE_SIZE;
|
||||||
|
|
||||||
|
status = store->ops->write(store, page->offset, vecs, 1, &length);
|
||||||
|
|
||||||
|
vm_put_physical_page((addr_t)vecs[0].iov_base);
|
||||||
|
|
||||||
|
if (status < B_OK)
|
||||||
|
dprintf("write_page(page = %p): offset = %Ld, status = %ld\n", page, page->offset, status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
vm_page_write_modified(vm_cache *cache)
|
||||||
|
{
|
||||||
|
vm_page *page = cache->page_list;
|
||||||
|
|
||||||
|
// ToDo: join adjacent pages into one vec list
|
||||||
|
|
||||||
|
for (; page; page = page->cache_next) {
|
||||||
|
status_t status;
|
||||||
|
bool gotPage = false;
|
||||||
|
|
||||||
|
cpu_status state = disable_interrupts();
|
||||||
|
acquire_spinlock(&page_lock);
|
||||||
|
|
||||||
|
if (page->state == PAGE_STATE_MODIFIED) {
|
||||||
|
remove_page_from_queue(&page_modified_queue, page);
|
||||||
|
page->state = PAGE_STATE_BUSY;
|
||||||
|
gotPage = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
release_spinlock(&page_lock);
|
||||||
|
restore_interrupts(state);
|
||||||
|
|
||||||
|
if (!gotPage)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// got modified page, let's write it back
|
||||||
|
|
||||||
|
status = write_page(page);
|
||||||
|
if (status == B_OK) {
|
||||||
|
vm_area *area;
|
||||||
|
|
||||||
|
// It's written back now, so we can clear the modified flag in all mappings
|
||||||
|
for (area = page->cache->ref->areas; area; area = area->cache_next) {
|
||||||
|
if (page->offset >= area->cache_offset
|
||||||
|
&& page->offset < area->cache_offset + area->size) {
|
||||||
|
vm_translation_map *map = &area->aspace->translation_map;
|
||||||
|
map->ops->lock(map);
|
||||||
|
map->ops->clear_flags(map, page->offset - area->cache_offset + area->base,
|
||||||
|
PAGE_MODIFIED);
|
||||||
|
map->ops->unlock(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// put it into the active queue
|
||||||
|
|
||||||
|
state = disable_interrupts();
|
||||||
|
acquire_spinlock(&page_lock);
|
||||||
|
|
||||||
|
if (page->ref_count > 0)
|
||||||
|
page->state = PAGE_STATE_ACTIVE;
|
||||||
|
else
|
||||||
|
page->state = PAGE_STATE_INACTIVE;
|
||||||
|
|
||||||
|
enqueue_page(&page_active_queue, page);
|
||||||
|
|
||||||
|
release_spinlock(&page_lock);
|
||||||
|
restore_interrupts(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static int pageout_daemon()
|
static int pageout_daemon()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user