Commit fb6932a2 authored by Kirill Smelkov's avatar Kirill Smelkov

X Split PAGE_LOADED -> PAGE_LOADED, PAGE_LOADED_FOR_WRITE

The latter state is the only valid state in wcfs mode when pagefault
handler sees already loaded page in fileh->pagemap.
parent 4d18f19b
...@@ -1282,7 +1282,7 @@ int main() ...@@ -1282,7 +1282,7 @@ int main()
{ {
tap_fail_callback = abort; // XXX to catch failure immediately tap_fail_callback = abort; // XXX to catch failure immediately
if (0) { if (1) {
test_vmamap(); test_vmamap();
test_file_access_synthetic(); test_file_access_synthetic();
test_file_access_pagefault(); test_file_access_pagefault();
......
...@@ -479,6 +479,7 @@ void fileh_invalidate_page(BigFileH *fileh, pgoff_t pgoffset) ...@@ -479,6 +479,7 @@ void fileh_invalidate_page(BigFileH *fileh, pgoff_t pgoffset)
BUG_ON(fileh->writeout_inprogress); BUG_ON(fileh->writeout_inprogress);
// XXX wcfs: invalidate_page must not be called (wcfs handles invalidations itself) // XXX wcfs: invalidate_page must not be called (wcfs handles invalidations itself)
// XXX or allow invalidate anyway (e.g. DIRTY -> base) ? // XXX or allow invalidate anyway (e.g. DIRTY -> base) ?
// XXX yes -> allow invalidate for wcfs too - means forget in-ram page and mmap to base memory
page = pagemap_get(&fileh->pagemap, pgoffset); page = pagemap_get(&fileh->pagemap, pgoffset);
if (page) { if (page) {
...@@ -630,12 +631,17 @@ VMFaultResult vma_on_pagefault(VMA *vma, uintptr_t addr, int write) ...@@ -630,12 +631,17 @@ VMFaultResult vma_on_pagefault(VMA *vma, uintptr_t addr, int write)
/* (3) fileh, pagen -> page (via pagemap) */ /* (3) fileh, pagen -> page (via pagemap) */
page = pagemap_get(&fileh->pagemap, pagen); page = pagemap_get(&fileh->pagemap, pagen);
/* wcfs: all dirty pages are mmapped when vma is created */ /* wcfs: all dirty pages are mmapped when vma is created.
// FIXME no: it could be in PAGE_LOADING state * thus here, if page is present in pagemap, it can be only either
// XXX and after VM_RETRY it could be in PAGE_LOADED state * - a page we just loaded for dirtying, or
// XXX ----//---- even for write * - a page that is in progress of being loaded.
if (vma->mmap_overlay) *
BUG_ON(page); * ( PAGE_LOADED_FOR_WRITE is used only to verify that in wcfs mode we
* always keep all dirty pages mmapped on fileh_open and so pagefault
* handler must not see a PAGE_LOADED page. )
*/
if (vma->mmap_overlay && page)
ASSERT(page->state == PAGE_LOADED_FOR_WRITE || page->state == PAGE_LOADING);
/* (4) no page found - allocate new from ram */ /* (4) no page found - allocate new from ram */
while (!page) { while (!page) {
...@@ -705,9 +711,6 @@ VMFaultResult vma_on_pagefault(VMA *vma, uintptr_t addr, int write) ...@@ -705,9 +711,6 @@ VMFaultResult vma_on_pagefault(VMA *vma, uintptr_t addr, int write)
pageram = page_mmap(page, NULL, PROT_READ | PROT_WRITE); pageram = page_mmap(page, NULL, PROT_READ | PROT_WRITE);
TODO(!pageram); // XXX err TODO(!pageram); // XXX err
// XXX overlay: copy data from base image, page.state=DIRTY
// XXX overlay: goto inject_page
/* load block -> pageram memory */ /* load block -> pageram memory */
blk = page->f_pgoffset; // NOTE because blksize = pagesize blk = page->f_pgoffset; // NOTE because blksize = pagesize
...@@ -755,7 +758,7 @@ VMFaultResult vma_on_pagefault(VMA *vma, uintptr_t addr, int write) ...@@ -755,7 +758,7 @@ VMFaultResult vma_on_pagefault(VMA *vma, uintptr_t addr, int write)
/* else just mark the page as loaded ok */ /* else just mark the page as loaded ok */
else else
page->state = PAGE_LOADED; page->state = (write ? PAGE_LOADED_FOR_WRITE : PAGE_LOADED);
/* we have to retry the whole fault, because the vma could have been /* we have to retry the whole fault, because the vma could have been
* changed while we were loading page with virtmem lock released */ * changed while we were loading page with virtmem lock released */
...@@ -785,7 +788,6 @@ VMFaultResult vma_on_pagefault(VMA *vma, uintptr_t addr, int write) ...@@ -785,7 +788,6 @@ VMFaultResult vma_on_pagefault(VMA *vma, uintptr_t addr, int write)
return VM_RETRY; return VM_RETRY;
} }
//inject_page:
/* (6) page data ready. Mmap it atomically into vma address space, or mprotect /* (6) page data ready. Mmap it atomically into vma address space, or mprotect
* appropriately if it was already mmaped. */ * appropriately if it was already mmaped. */
int prot = PROT_READ; int prot = PROT_READ;
...@@ -853,7 +855,7 @@ static int __ram_reclaim(RAM *ram) ...@@ -853,7 +855,7 @@ static int __ram_reclaim(RAM *ram)
/* can release ram only from loaded non-dirty pages /* can release ram only from loaded non-dirty pages
* NOTE PAGE_LOADING pages are not dropped - they just continue to load */ * NOTE PAGE_LOADING pages are not dropped - they just continue to load */
if (page->state == PAGE_LOADED) { if (page->state == PAGE_LOADED || page->state == PAGE_LOADED_FOR_WRITE) {
page_drop_memory(page); page_drop_memory(page);
batch--; batch--;
} }
......
...@@ -84,7 +84,9 @@ enum PageState { ...@@ -84,7 +84,9 @@ enum PageState {
= 2, /* file content loading was in progress = 2, /* file content loading was in progress
while request to invalidate the page came in */ while request to invalidate the page came in */
PAGE_LOADED = 3, /* file content has been loaded and was not modified */ PAGE_LOADED = 3, /* file content has been loaded and was not modified */
PAGE_DIRTY = 4, /* file content has been loaded and was modified */ PAGE_LOADED_FOR_WRITE
= 4, /* file content has been loaded and is going to be modified */
PAGE_DIRTY = 5, /* file content has been loaded and was modified */
}; };
typedef enum PageState PageState; typedef enum PageState PageState;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment