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); memcpy(newkva, orgkva, pgsize);
ihk_atomic_dec(&orgpage->count); ihk_atomic_dec(&orgpage->count);
newpa = virt_to_phys(newkva); newpa = virt_to_phys(newkva);
page_map(phys_to_page(newpa));
newkva = NULL; /* avoid ihk_mc_free_pages() */ newkva = NULL; /* avoid ihk_mc_free_pages() */
break; break;
} }

View File

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

View File

@ -97,7 +97,7 @@ void free_pages(void *va, int npages)
} }
if (pendings->next != NULL) { if (pendings->next != NULL) {
page->mode = PM_PENDING_FREE; page->mode = PM_PENDING_FREE;
page->count = npages; page->offset = npages;
list_add_tail(&page->list, pendings); list_add_tail(&page->list, pendings);
return; return;
} }
@ -131,7 +131,7 @@ void finish_free_pages_pending(void)
} }
page->mode = PM_NONE; page->mode = PM_NONE;
list_del(&page->list); 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; pendings->next = pendings->prev = NULL;
@ -339,10 +339,6 @@ uintptr_t page_to_phys(struct page *page)
int page_unmap(struct page *page) int page_unmap(struct page *page)
{ {
dkprintf("page_unmap(%p %x %d)\n", page, page->mode, page->count); 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) { if (ihk_atomic_sub_return(1, &page->count) > 0) {
/* other mapping exist */ /* other mapping exist */
dkprintf("page_unmap(%p %x %d): 0\n", dkprintf("page_unmap(%p %x %d): 0\n",
@ -351,6 +347,10 @@ int page_unmap(struct page *page)
} }
/* no mapping exist */ /* no mapping exist */
if (page->mode != PM_MAPPED) {
return 1;
}
list_del(&page->list); list_del(&page->list);
page->mode = PM_NONE; page->mode = PM_NONE;
dkprintf("page_unmap(%p %x %d): 1\n", page, page->mode, page->count); 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); p2align, IHK_MC_AP_NOWAIT);
if (virt) { if (virt) {
phys = virt_to_phys(virt); phys = virt_to_phys(virt);
page_map(phys_to_page(phys));
memset(virt, 0, pgsize); memset(virt, 0, pgsize);
break; break;
} }
@ -1160,6 +1161,7 @@ out:
} }
} }
if (virt != NULL) { if (virt != NULL) {
page_unmap(phys_to_page(phys));
ihk_mc_free_pages(virt, npages); ihk_mc_free_pages(virt, npages);
} }
dkprintf("[%d]page_fault_process_memory_range(%p,%lx-%lx %lx,%lx): %d\n", 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); memcpy(newkva, oldkva, pgsize);
newpa = virt_to_phys(newkva); newpa = virt_to_phys(newkva);
page_map(phys_to_page(newpa));
} }
attr = vrflag_to_ptattr(range->flag); 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, vm, range->start, range->end, range->flag,
fault_addr, error); fault_addr, error);
panic("protection_fault_process_memory_range:ihk_mc_pt_set_pte failed."); panic("protection_fault_process_memory_range:ihk_mc_pt_set_pte failed.");
page_unmap(phys_to_page(newpa));
ihk_mc_free_pages(newkva, npages); ihk_mc_free_pages(newkva, npages);
goto out; goto out;
} }