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
This commit is contained in:
@ -1855,6 +1855,8 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
|||||||
uintptr_t phys;
|
uintptr_t phys;
|
||||||
struct page *page = NULL;
|
struct page *page = NULL;
|
||||||
unsigned long memobj_flag = 0;
|
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);
|
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);
|
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);
|
attr = arch_vrflag_to_ptattr(range->flag | memobj_flag, reason, ptep);
|
||||||
|
|
||||||
/* Copy on write */
|
/* Copy on write */
|
||||||
if (((range->flag & VR_PRIVATE) ||
|
|
||||||
((reason & PF_PATCH) && !(range->flag & VR_PROT_WRITE)))
|
private_range = (range->flag & VR_PRIVATE);
|
||||||
&& ((!page && ((phys == NOPHYS) || range->memobj))
|
patching_to_rdonly =
|
||||||
|| (page && (page_is_in_memobj(page) ||
|
((reason & PF_PATCH) && !(range->flag & VR_PROT_WRITE));
|
||||||
page_is_multi_mapped(page))))) {
|
|
||||||
|
/* 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)) {
|
if (!(attr & PTATTR_DIRTY)) {
|
||||||
attr &= ~PTATTR_WRITABLE;
|
attr &= ~PTATTR_WRITABLE;
|
||||||
|
|||||||
Reference in New Issue
Block a user