keep page.count valid through its life cycle
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
12
kernel/mem.c
12
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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user