From b55e164669f6b7049b99931f45708140a3a8732a Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Wed, 12 Jun 2019 23:06:56 +0900 Subject: [PATCH] page_fault_process_memory_range: Disable COW for VM region with zeroobj This fixes ostest-mem_limits.001 which tries to anonymous-mmap 95% of total memory. It reports a failure because: (1) McKernel tries to allocate physically contiguous area and fails (2) It turns on demand-paging (3) It tries to obtain a page from zeroobj and fails (4) It allocates a new page (5) It performs COW on the page, which is unnecessary Change-Id: Iddf0548bb9216f9bf91fb03fa21f890e599bfdad --- kernel/process.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/kernel/process.c b/kernel/process.c index 08c0d5c0..1fe233f1 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1855,6 +1855,8 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang uintptr_t phys; struct page *page = NULL; unsigned long memobj_flag = 0; + int private_range, patching_to_rdonly; + int devfile_or_hugetlbfs_or_premap, regfile_or_shm; dkprintf("page_fault_process_memory_range(%p,%lx-%lx %lx,%lx,%lx)\n", vm, range->start, range->end, range->flag, fault_addr, reason); ihk_mc_spinlock_lock_noirq(&vm->page_table_lock); @@ -1970,11 +1972,23 @@ retry: attr = arch_vrflag_to_ptattr(range->flag | memobj_flag, reason, ptep); /* Copy on write */ - if (((range->flag & VR_PRIVATE) || - ((reason & PF_PATCH) && !(range->flag & VR_PROT_WRITE))) - && ((!page && ((phys == NOPHYS) || range->memobj)) - || (page && (page_is_in_memobj(page) || - page_is_multi_mapped(page))))) { + + private_range = (range->flag & VR_PRIVATE); + patching_to_rdonly = + ((reason & PF_PATCH) && !(range->flag & VR_PROT_WRITE)); + + /* device file map, hugetlbfs file map, pre-mapped file map */ + devfile_or_hugetlbfs_or_premap = + (!page && + (range->memobj && !(range->memobj->flags | MF_ZEROOBJ))); + + /* regular file map, Sys V shared memory map */ + regfile_or_shm = + (page && + (page_is_in_memobj(page) || page_is_multi_mapped(page))); + + if ((private_range || patching_to_rdonly) && + (devfile_or_hugetlbfs_or_premap || regfile_or_shm)) { if (!(attr & PTATTR_DIRTY)) { attr &= ~PTATTR_WRITABLE;