keep page.count valid through its life cycle

This commit is contained in:
NAKAMURA Gou
2014-05-07 18:34:15 +09:00
parent 29c7d40005
commit ce7af5839d
4 changed files with 16 additions and 6 deletions

View File

@ -522,6 +522,7 @@ static uintptr_t fileobj_copy_page(
memcpy(newkva, orgkva, pgsize);
ihk_atomic_dec(&orgpage->count);
newpa = virt_to_phys(newkva);
page_map(phys_to_page(newpa));
newkva = NULL; /* avoid ihk_mc_free_pages() */
break;
}

View File

@ -44,4 +44,9 @@ void free_pages(void *va, int npages);
void begin_free_pages_pending(void);
void finish_free_pages_pending(void);
static inline void page_map(struct page *page)
{
ihk_atomic_inc(&page->count);
}
#endif

View File

@ -97,7 +97,7 @@ void free_pages(void *va, int npages)
}
if (pendings->next != NULL) {
page->mode = PM_PENDING_FREE;
page->count = npages;
page->offset = npages;
list_add_tail(&page->list, pendings);
return;
}
@ -131,7 +131,7 @@ void finish_free_pages_pending(void)
}
page->mode = PM_NONE;
list_del(&page->list);
ihk_pagealloc_free(pa_allocator, page_to_phys(page), page->count);
ihk_pagealloc_free(pa_allocator, page_to_phys(page), page->offset);
}
pendings->next = pendings->prev = NULL;
@ -339,10 +339,6 @@ uintptr_t page_to_phys(struct page *page)
int page_unmap(struct page *page)
{
dkprintf("page_unmap(%p %x %d)\n", page, page->mode, page->count);
if (page->mode != PM_MAPPED) {
return 1;
}
if (ihk_atomic_sub_return(1, &page->count) > 0) {
/* other mapping exist */
dkprintf("page_unmap(%p %x %d): 0\n",
@ -351,6 +347,10 @@ int page_unmap(struct page *page)
}
/* no mapping exist */
if (page->mode != PM_MAPPED) {
return 1;
}
list_del(&page->list);
page->mode = PM_NONE;
dkprintf("page_unmap(%p %x %d): 1\n", page, page->mode, page->count);

View File

@ -1090,6 +1090,7 @@ static int page_fault_process_memory_range(struct process_vm *vm,
p2align, IHK_MC_AP_NOWAIT);
if (virt) {
phys = virt_to_phys(virt);
page_map(phys_to_page(phys));
memset(virt, 0, pgsize);
break;
}
@ -1160,6 +1161,7 @@ out:
}
}
if (virt != NULL) {
page_unmap(phys_to_page(phys));
ihk_mc_free_pages(virt, npages);
}
dkprintf("[%d]page_fault_process_memory_range(%p,%lx-%lx %lx,%lx): %d\n",
@ -1234,6 +1236,7 @@ static int protection_fault_process_memory_range(struct process_vm *vm, struct v
memcpy(newkva, oldkva, pgsize);
newpa = virt_to_phys(newkva);
page_map(phys_to_page(newpa));
}
attr = vrflag_to_ptattr(range->flag);
@ -1244,6 +1247,7 @@ static int protection_fault_process_memory_range(struct process_vm *vm, struct v
vm, range->start, range->end, range->flag,
fault_addr, error);
panic("protection_fault_process_memory_range:ihk_mc_pt_set_pte failed.");
page_unmap(phys_to_page(newpa));
ihk_mc_free_pages(newkva, npages);
goto out;
}