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);
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
12
kernel/mem.c
12
kernel/mem.c
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user