invalidate_one_page: Support shmobj and contiguous PTE

Change-Id: I15b74ee4afd8e2dc52c933925aae4a1e0d8bcc72
This commit is contained in:
Masamichi Takagi
2018-12-14 17:14:29 +09:00
committed by Dominique Martinet
parent b174fb8099
commit bdf5175d4c
2 changed files with 30 additions and 44 deletions

View File

@ -1698,6 +1698,7 @@ static int invalidate_one_page(void *arg0, page_table_t pt, pte_t *ptep,
struct page *page;
off_t linear_off;
pte_t apte;
size_t memobj_pgsize;
dkprintf("invalidate_one_page(%p,%p,%p %#lx,%p,%d)\n",
arg0, pt, ptep, *ptep, pgaddr, pgshift);
@ -1715,7 +1716,8 @@ static int invalidate_one_page(void *arg0, page_table_t pt, pte_t *ptep,
pte_make_null(&apte, pgsize);
}
else {
pte_make_fileoff(page->offset, 0, pgsize, &apte);
pte_make_fileoff(page->offset, 0, pgsize,
&apte);
}
} else {
pte_make_null(&apte, pgsize);
@ -1724,11 +1726,27 @@ static int invalidate_one_page(void *arg0, page_table_t pt, pte_t *ptep,
pte_xchg(ptep, &apte);
flush_tlb_single((uintptr_t)pgaddr); /* XXX: TLB flush */
/* Contiguous PTE head invalidates memobj->pgshift-sized
* memory for other members
*/
if (pte_is_contiguous(&apte)) {
if (page_is_contiguous_head(ptep, pgsize)) {
int level = pgsize_to_tbllv(pgsize);
memobj_pgsize = tbllv_to_contpgsize(level);
} else {
error = 0;
goto out;
}
} else {
memobj_pgsize = pgsize;
}
if (page && page_unmap(page)) {
panic("invalidate_one_page");
}
error = memobj_invalidate_page(range->memobj, phys, pgsize);
error = memobj_invalidate_page(range->memobj, phys, memobj_pgsize);
if (error) {
ekprintf("invalidate_one_page(%p,%p,%p %#lx,%p,%d):"
"invalidate failed. %d\n",
@ -1795,9 +1813,16 @@ int invalidate_process_memory_range(struct process_vm *vm,
}
}
error = visit_pte_range(vm->address_space->page_table, (void *)start,
(void *)end, range->pgshift, VPTEF_SKIP_NULL,
&invalidate_one_page, &args);
if (range->memobj->flags & MF_SHM) {
error = ihk_mc_pt_free_range(vm->address_space->page_table,
vm, (void *)start, (void *)end,
range->memobj);
} else {
error = visit_pte_range(vm->address_space->page_table,
(void *)start, (void *)end,
range->pgshift, VPTEF_SKIP_NULL,
&invalidate_one_page, &args);
}
memobj_unref(range->memobj);
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
if (error) {

View File

@ -37,7 +37,6 @@ static memobj_lookup_page_func_t shmobj_lookup_page;
static struct memobj_ops shmobj_ops = {
.free = &shmobj_free,
.get_page = &shmobj_get_page,
.invalidate_page = &shmobj_invalidate_page,
.lookup_page = &shmobj_lookup_page,
};
@ -440,44 +439,6 @@ out:
return error;
}
static int shmobj_invalidate_page(struct memobj *memobj, uintptr_t phys,
size_t pgsize)
{
struct shmobj *obj = to_shmobj(memobj);
int error;
struct page *page;
dkprintf("shmobj_invalidate_page(%p,%#lx,%#lx)\n", memobj, phys, pgsize);
page_list_lock(obj);
if (!(page = phys_to_page(phys))
|| !(page = page_list_lookup(obj, page->offset))) {
page_list_unlock(obj);
error = 0;
goto out;
}
page_list_unlock(obj);
if (ihk_atomic_read(&page->count) == 1) {
if (page_unmap(page)) {
ihk_mc_free_pages_user(phys_to_virt(phys),
pgsize/PAGE_SIZE);
/* Track change in page->count for shmobj.
* It is decremented in here or shmobj_destroy() or
* clear_range().
*/
dkprintf("%lx-,%s: calling memory_stat_rss_sub(),phys=%lx,size=%ld,pgsize=%ld\n",
phys, __func__, phys, pgsize, pgsize);
memory_stat_rss_sub(pgsize, pgsize);
}
}
error = 0;
out:
dkprintf("shmobj_invalidate_page(%p,%#lx,%#lx):%d\n", memobj, phys, pgsize, error);
return error;
}
static int shmobj_lookup_page(struct memobj *memobj, off_t off, int p2align,
uintptr_t *physp, unsigned long *pflag)
{