diff --git a/kernel/fileobj.c b/kernel/fileobj.c index 87578399..18a27046 100644 --- a/kernel/fileobj.c +++ b/kernel/fileobj.c @@ -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; } diff --git a/kernel/include/page.h b/kernel/include/page.h index 5c850bf8..7a35d867 100644 --- a/kernel/include/page.h +++ b/kernel/include/page.h @@ -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 diff --git a/kernel/mem.c b/kernel/mem.c index 95bbd963..90d492c7 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -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); diff --git a/kernel/process.c b/kernel/process.c index 03a54ab7..2b815bf0 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -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; }