invalidate_one_page: Support shmobj and contiguous PTE
Change-Id: I15b74ee4afd8e2dc52c933925aae4a1e0d8bcc72
This commit is contained in:
committed by
Dominique Martinet
parent
b174fb8099
commit
bdf5175d4c
@ -1698,6 +1698,7 @@ static int invalidate_one_page(void *arg0, page_table_t pt, pte_t *ptep,
|
|||||||
struct page *page;
|
struct page *page;
|
||||||
off_t linear_off;
|
off_t linear_off;
|
||||||
pte_t apte;
|
pte_t apte;
|
||||||
|
size_t memobj_pgsize;
|
||||||
|
|
||||||
dkprintf("invalidate_one_page(%p,%p,%p %#lx,%p,%d)\n",
|
dkprintf("invalidate_one_page(%p,%p,%p %#lx,%p,%d)\n",
|
||||||
arg0, pt, ptep, *ptep, pgaddr, pgshift);
|
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);
|
pte_make_null(&apte, pgsize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pte_make_fileoff(page->offset, 0, pgsize, &apte);
|
pte_make_fileoff(page->offset, 0, pgsize,
|
||||||
|
&apte);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pte_make_null(&apte, pgsize);
|
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);
|
pte_xchg(ptep, &apte);
|
||||||
flush_tlb_single((uintptr_t)pgaddr); /* XXX: TLB flush */
|
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)) {
|
if (page && page_unmap(page)) {
|
||||||
panic("invalidate_one_page");
|
panic("invalidate_one_page");
|
||||||
}
|
}
|
||||||
|
|
||||||
error = memobj_invalidate_page(range->memobj, phys, pgsize);
|
error = memobj_invalidate_page(range->memobj, phys, memobj_pgsize);
|
||||||
if (error) {
|
if (error) {
|
||||||
ekprintf("invalidate_one_page(%p,%p,%p %#lx,%p,%d):"
|
ekprintf("invalidate_one_page(%p,%p,%p %#lx,%p,%d):"
|
||||||
"invalidate failed. %d\n",
|
"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,
|
if (range->memobj->flags & MF_SHM) {
|
||||||
(void *)end, range->pgshift, VPTEF_SKIP_NULL,
|
error = ihk_mc_pt_free_range(vm->address_space->page_table,
|
||||||
&invalidate_one_page, &args);
|
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);
|
memobj_unref(range->memobj);
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|||||||
@ -37,7 +37,6 @@ static memobj_lookup_page_func_t shmobj_lookup_page;
|
|||||||
static struct memobj_ops shmobj_ops = {
|
static struct memobj_ops shmobj_ops = {
|
||||||
.free = &shmobj_free,
|
.free = &shmobj_free,
|
||||||
.get_page = &shmobj_get_page,
|
.get_page = &shmobj_get_page,
|
||||||
.invalidate_page = &shmobj_invalidate_page,
|
|
||||||
.lookup_page = &shmobj_lookup_page,
|
.lookup_page = &shmobj_lookup_page,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -440,44 +439,6 @@ out:
|
|||||||
return error;
|
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,
|
static int shmobj_lookup_page(struct memobj *memobj, off_t off, int p2align,
|
||||||
uintptr_t *physp, unsigned long *pflag)
|
uintptr_t *physp, unsigned long *pflag)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user