From 9cfc373538091bf2f987bd91201eba8a127206e4 Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Fri, 12 Oct 2018 13:37:50 +0900 Subject: [PATCH] Refactor "do write back only MAP_SHARED pages" * free_process_memory_range() always passes memobj to ihk_mc_pt_free_range() * clear_range_*() don't flush page in fileobj with MF_PRIVATE flag Fujitsu: POSTK_DEBUG_TEMP_FIX_87 Change-Id: I8d46d029b3fc51ca6f0e59d748a2fe93e324a374 --- arch/arm64/kernel/memory.c | 10 ++++++---- arch/x86_64/kernel/memory.c | 14 ++++++++++---- executer/kernel/mcctrl/syscall.c | 1 + kernel/fileobj.c | 7 +++++-- kernel/include/memobj.h | 4 +++- kernel/process.c | 4 +--- kernel/syscall.c | 3 ++- 7 files changed, 28 insertions(+), 15 deletions(-) diff --git a/arch/arm64/kernel/memory.c b/arch/arm64/kernel/memory.c index f3e2b523..55159a1f 100644 --- a/arch/arm64/kernel/memory.c +++ b/arch/arm64/kernel/memory.c @@ -2174,8 +2174,9 @@ static int clear_range_l1(void *args0, pte_t *ptep, uint64_t base, (old & PTE_DIRTY), args->memobj, args->memobj ? args->memobj->flags : -1); } - if (page && page_is_in_memobj(page) && ptl1_dirty(&old) && - (args->memobj) && !(args->memobj->flags & MF_ZEROFILL)) { + if (page && page_is_in_memobj(page) && + ptl1_dirty(&old) && args->memobj && + !(args->memobj->flags & (MF_ZEROFILL | MF_PRIVATE))) { memobj_flush_page(args->memobj, phys, PTL1_SIZE); } @@ -2284,8 +2285,9 @@ static int clear_range_middle(void *args0, pte_t *ptep, uint64_t base, page = phys_to_page(phys); } - if (page && page_is_in_memobj(page) && ptl_dirty(&old, level) && - !(args->memobj->flags & MF_ZEROFILL)) { + if (page && page_is_in_memobj(page) && + ptl_dirty(&old, level) && args->memobj && + !(args->memobj->flags & (MF_ZEROFILL | MF_PRIVATE))) { memobj_flush_page(args->memobj, phys, tbl.pgsize); } diff --git a/arch/x86_64/kernel/memory.c b/arch/x86_64/kernel/memory.c index 0b1b7c28..751b892c 100644 --- a/arch/x86_64/kernel/memory.c +++ b/arch/x86_64/kernel/memory.c @@ -1499,8 +1499,10 @@ static int clear_range_l1(void *args0, pte_t *ptep, uint64_t base, if (page) { dkprintf("%s: page=%p,is_in_memobj=%d,(old & PFL1_DIRTY)=%lx,memobj=%p,args->memobj->flags=%x\n", __FUNCTION__, page, page_is_in_memobj(page), (old & PFL1_DIRTY), args->memobj, args->memobj ? args->memobj->flags : -1); } - if (page && page_is_in_memobj(page) && pte_is_dirty(&old, PTL1_SIZE) && - args->memobj && !(args->memobj->flags & MF_ZEROFILL)) { + + if (page && page_is_in_memobj(page) && + pte_is_dirty(&old, PTL1_SIZE) && args->memobj && + !(args->memobj->flags & (MF_ZEROFILL | MF_PRIVATE))) { memobj_flush_page(args->memobj, phys, PTL1_SIZE); } @@ -1566,7 +1568,9 @@ static int clear_range_l2(void *args0, pte_t *ptep, uint64_t base, page = phys_to_page(phys); } - if (page && page_is_in_memobj(page) && pte_is_dirty(&old, PTL2_SIZE)) { + if (page && page_is_in_memobj(page) && + pte_is_dirty(&old, PTL2_SIZE) && args->memobj && + !(args->memobj->flags & (MF_ZEROFILL | MF_PRIVATE))) { memobj_flush_page(args->memobj, phys, PTL2_SIZE); } @@ -1647,7 +1651,9 @@ static int clear_range_l3(void *args0, pte_t *ptep, uint64_t base, page = phys_to_page(phys); } - if (page && page_is_in_memobj(page) && pte_is_dirty(&old, PTL3_SIZE)) { + if (page && page_is_in_memobj(page) && + pte_is_dirty(&old, PTL3_SIZE) && args->memobj && + !(args->memobj->flags & (MF_ZEROFILL | MF_PRIVATE))) { memobj_flush_page(args->memobj, phys, PTL3_SIZE); } diff --git a/executer/kernel/mcctrl/syscall.c b/executer/kernel/mcctrl/syscall.c index 3d8803d4..768bc910 100644 --- a/executer/kernel/mcctrl/syscall.c +++ b/executer/kernel/mcctrl/syscall.c @@ -1084,6 +1084,7 @@ enum { MF_ZEROOBJ = 0x20000, /* To identify pages of anonymous, on-demand paging ranges for rusage accounting */ MF_SHM = 0x40000, MF_HUGETLBFS = 0x100000, + MF_PRIVATE = 0x200000, /* To prevent flush in clear_range_* */ }; static int pager_get_path(struct file *file, char *path) { diff --git a/kernel/fileobj.c b/kernel/fileobj.c index 74cf7601..b39653c7 100644 --- a/kernel/fileobj.c +++ b/kernel/fileobj.c @@ -28,6 +28,7 @@ #include #include #include +#include //#define DEBUG_PRINT_FILEOBJ @@ -186,7 +187,8 @@ static struct fileobj *obj_list_lookup(uintptr_t handle) /*********************************************************************** * fileobj */ -int fileobj_create(int fd, struct memobj **objp, int *maxprotp, uintptr_t virt_addr) +int fileobj_create(int fd, struct memobj **objp, int *maxprotp, int flags, + uintptr_t virt_addr) { ihk_mc_user_context_t ctx; struct pager_create_result result __attribute__((aligned(64))); @@ -234,7 +236,8 @@ int fileobj_create(int fd, struct memobj **objp, int *maxprotp, uintptr_t virt_a } memset(newobj, 0, sizeof(*newobj)); newobj->memobj.ops = &fileobj_ops; - newobj->memobj.flags = MF_HAS_PAGER | MF_REG_FILE; + newobj->memobj.flags = MF_HAS_PAGER | MF_REG_FILE | + ((flags & MAP_PRIVATE) ? MF_PRIVATE : 0); newobj->handle = result.handle; fileobj_page_hash_init(newobj); diff --git a/kernel/include/memobj.h b/kernel/include/memobj.h index c9840c72..1ef1a266 100644 --- a/kernel/include/memobj.h +++ b/kernel/include/memobj.h @@ -35,6 +35,7 @@ enum { MF_ZEROOBJ = 0x20000, /* To identify pages of anonymous, on-demand paging ranges for rusage accounting */ MF_SHM = 0x40000, MF_HUGETLBFS = 0x100000, + MF_PRIVATE = 0x200000, /* To prevent flush in clear_range_* */ }; #define MEMOBJ_READY 0 @@ -139,7 +140,8 @@ static inline int memobj_is_removable(struct memobj *obj) return !!(obj->flags & MF_IS_REMOVABLE); } -int fileobj_create(int fd, struct memobj **objp, int *maxprotp, uintptr_t virt_addr); +int fileobj_create(int fd, struct memobj **objp, int *maxprotp, int flags, + uintptr_t virt_addr); struct shmid_ds; int shmobj_create(struct shmid_ds *ds, struct memobj **objp); int zeroobj_create(struct memobj **objp); diff --git a/kernel/process.c b/kernel/process.c index 015cc6d0..e4b02a1c 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1005,9 +1005,7 @@ int free_process_memory_range(struct process_vm *vm, struct vm_range *range) vm, (void *)start, (void *)end); } else { error = ihk_mc_pt_free_range(vm->address_space->page_table, - vm, (void *)start, (void *)end, - (range->flag & VR_PRIVATE) ? NULL : - range->memobj); + vm, (void *)start, (void *)end, range->memobj); } if (range->memobj) { memobj_unref(range->memobj); diff --git a/kernel/syscall.c b/kernel/syscall.c index 6a192aeb..6286d8d5 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1746,7 +1746,8 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot, maxprot = PROT_READ | PROT_WRITE | PROT_EXEC; if (!(flags & MAP_ANONYMOUS)) { off = off0; - error = fileobj_create(fd, &memobj, &maxprot, addr0); + error = fileobj_create(fd, &memobj, &maxprot, + flags, addr0); #ifdef ATTACHED_MIC /* * XXX: refuse device mapping in attached-mic now: