diff --git a/kernel/process.c b/kernel/process.c index e7b7005a..ad9aade5 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -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) { diff --git a/kernel/shmobj.c b/kernel/shmobj.c index 01cdf134..626505f4 100644 --- a/kernel/shmobj.c +++ b/kernel/shmobj.c @@ -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) {