From d2db6398530b54476a193a877b5ac6641663e96e Mon Sep 17 00:00:00 2001 From: Yoshihisa Morizumi Date: Fri, 8 Jan 2021 16:56:32 +0900 Subject: [PATCH] xpmem: support large page 1. try to use as large page as possible on attach 2. pre-map resident remote pages on attach Change-Id: I5580682a4199e94085a9bad9ce3958a0f14cdcea --- arch/arm64/kernel/syscall.c | 3 +- arch/arm64/kernel/vdso.c | 4 +- arch/x86_64/kernel/syscall.c | 8 +- kernel/host.c | 4 +- kernel/include/page.h | 1 + kernel/include/process.h | 6 +- kernel/include/syscall.h | 2 +- kernel/include/xpmem.h | 2 + kernel/include/xpmem_private.h | 13 +- kernel/mem.c | 6 + kernel/process.c | 20 +- kernel/syscall.c | 56 ++- kernel/xpmem.c | 506 +++++++++++++++----------- test/common.sh | 4 +- test/issues/1259/C1259.sh | 190 ++++++++++ test/issues/1259/Makefile | 12 + test/issues/1259/README | 104 ++++++ test/issues/1259/XTP_001.c | 60 +++ test/issues/1259/XTP_002.c | 76 ++++ test/issues/1259/XTP_003.c | 79 ++++ test/issues/1259/XTP_004.c | 112 ++++++ test/issues/1259/XTP_005.c | 76 ++++ test/issues/1259/XTP_006.c | 64 ++++ test/issues/1259/XTP_007.c | 89 +++++ test/issues/1259/XTP_008.c | 89 +++++ test/issues/1259/XTP_009.c | 92 +++++ test/issues/1259/XTP_010.c | 90 +++++ test/issues/1259/XTP_011.c | 88 +++++ test/issues/1259/aarch64_config | 2 + test/issues/1259/aarch64_result.log | 61 ++++ test/issues/1259/huge_page_xpmem.c | 182 +++++++++ test/issues/1259/large_page.patch | 117 ++++++ test/issues/1259/mc_run.sh | 15 + test/issues/1259/multi_vmr_xpmem.c | 190 ++++++++++ test/issues/1259/util.h | 28 ++ test/issues/1259/util2.h | 31 ++ test/issues/1259/x86_64_config | 2 + test/issues/1259/x86_64_result.log | 64 ++++ test/issues/1473/CMakeLists.txt | 164 +++++++++ test/issues/1473/README | 35 ++ test/issues/1473/XTP_001.c | 57 +++ test/issues/1473/XTP_002.c | 76 ++++ test/issues/1473/XTP_003.c | 80 ++++ test/issues/1473/XTP_004.c | 111 ++++++ test/issues/1473/XTP_005.c | 77 ++++ test/issues/1473/XTP_006.c | 62 ++++ test/issues/1473/XTP_007.c | 91 +++++ test/issues/1473/XTP_008.c | 91 +++++ test/issues/1473/XTP_009.c | 92 +++++ test/issues/1473/XTP_010.c | 88 +++++ test/issues/1473/XTP_011.c | 90 +++++ test/issues/1473/aarch64.conf | 3 + test/issues/1473/common.sh.in | 19 + test/issues/1473/huge_page_xpmem.c | 190 ++++++++++ test/issues/1473/ihk_kmsg_size.patch | 13 + test/issues/1473/large_page.patch | 117 ++++++ test/issues/1473/multi_vmr_xpmem.c | 199 ++++++++++ test/issues/1473/okng.h | 32 ++ test/issues/1473/util.h | 11 + test/issues/1473/util.sh.in | 122 +++++++ test/issues/1473/x86_64.conf | 3 + test/issues/1473/xpmem_attach01.c | 143 ++++++++ test/issues/1473/xpmem_attach01.sh.in | 66 ++++ test/issues/1473/xpmem_attach02.c | 162 +++++++++ test/issues/1473/xpmem_attach02.sh.in | 63 ++++ test/issues/1473/xpmem_attach03.sh.in | 230 ++++++++++++ test/issues/1473/xpmem_make01.c | 79 ++++ test/issues/1473/xpmem_make01.sh.in | 8 + 68 files changed, 4878 insertions(+), 244 deletions(-) create mode 100755 test/issues/1259/C1259.sh create mode 100644 test/issues/1259/Makefile create mode 100644 test/issues/1259/README create mode 100644 test/issues/1259/XTP_001.c create mode 100644 test/issues/1259/XTP_002.c create mode 100644 test/issues/1259/XTP_003.c create mode 100644 test/issues/1259/XTP_004.c create mode 100644 test/issues/1259/XTP_005.c create mode 100644 test/issues/1259/XTP_006.c create mode 100644 test/issues/1259/XTP_007.c create mode 100644 test/issues/1259/XTP_008.c create mode 100644 test/issues/1259/XTP_009.c create mode 100644 test/issues/1259/XTP_010.c create mode 100644 test/issues/1259/XTP_011.c create mode 100644 test/issues/1259/aarch64_config create mode 100644 test/issues/1259/huge_page_xpmem.c create mode 100644 test/issues/1259/large_page.patch create mode 100755 test/issues/1259/mc_run.sh create mode 100644 test/issues/1259/multi_vmr_xpmem.c create mode 100644 test/issues/1259/util.h create mode 100644 test/issues/1259/util2.h create mode 100644 test/issues/1259/x86_64_config create mode 100644 test/issues/1473/CMakeLists.txt create mode 100644 test/issues/1473/README create mode 100644 test/issues/1473/XTP_001.c create mode 100644 test/issues/1473/XTP_002.c create mode 100644 test/issues/1473/XTP_003.c create mode 100644 test/issues/1473/XTP_004.c create mode 100644 test/issues/1473/XTP_005.c create mode 100644 test/issues/1473/XTP_006.c create mode 100644 test/issues/1473/XTP_007.c create mode 100644 test/issues/1473/XTP_008.c create mode 100644 test/issues/1473/XTP_009.c create mode 100644 test/issues/1473/XTP_010.c create mode 100644 test/issues/1473/XTP_011.c create mode 100644 test/issues/1473/aarch64.conf create mode 100644 test/issues/1473/common.sh.in create mode 100644 test/issues/1473/huge_page_xpmem.c create mode 100644 test/issues/1473/ihk_kmsg_size.patch create mode 100644 test/issues/1473/large_page.patch create mode 100644 test/issues/1473/multi_vmr_xpmem.c create mode 100644 test/issues/1473/okng.h create mode 100644 test/issues/1473/util.h create mode 100644 test/issues/1473/util.sh.in create mode 100644 test/issues/1473/x86_64.conf create mode 100644 test/issues/1473/xpmem_attach01.c create mode 100644 test/issues/1473/xpmem_attach01.sh.in create mode 100644 test/issues/1473/xpmem_attach02.c create mode 100644 test/issues/1473/xpmem_attach02.sh.in create mode 100644 test/issues/1473/xpmem_attach03.sh.in create mode 100644 test/issues/1473/xpmem_make01.c create mode 100644 test/issues/1473/xpmem_make01.sh.in diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 2ea28136..7562f1f5 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1807,7 +1808,7 @@ SYSCALL_DECLARE(mmap) goto out; } - addr = do_mmap(addr, len, prot, flags, fd, off0); + addr = do_mmap(addr, len, prot, flags, fd, off0, 0, NULL); error = 0; out: diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index acf93447..f0b88383 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -155,7 +155,7 @@ int arch_map_vdso(struct process_vm *vm) flag = VR_REMOTE | VR_PROT_READ; flag |= VRFLAG_PROT_TO_MAXPROT(flag); ret = add_process_memory_range(vm, start, end, vdso.vvar_phys, flag, - NULL, 0, PAGE_SHIFT, &range); + NULL, 0, PAGE_SHIFT, NULL, &range); if (ret != 0){ dkprintf("ERROR: adding memory range for tod_data\n"); goto exit; @@ -167,7 +167,7 @@ int arch_map_vdso(struct process_vm *vm) flag = VR_REMOTE | VR_PROT_READ | VR_PROT_EXEC; flag |= VRFLAG_PROT_TO_MAXPROT(flag); ret = add_process_memory_range(vm, start, end, vdso.vdso_physlist[0], flag, - NULL, 0, PAGE_SHIFT, &range); + NULL, 0, PAGE_SHIFT, NULL, &range); if (ret != 0) { dkprintf("ERROR: adding memory range for vdso_text\n"); diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c index fe5a0dc5..3825fee8 100644 --- a/arch/x86_64/kernel/syscall.c +++ b/arch/x86_64/kernel/syscall.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1511,7 +1512,7 @@ recheck: goto out; } - addr = do_mmap(addr, len, prot, flags, fd, off0); + addr = do_mmap(addr, len, prot, flags, fd, off0, 0, NULL); error = 0; out: @@ -1840,7 +1841,7 @@ int arch_map_vdso(struct process_vm *vm) vrflags |= VR_PROT_READ | VR_PROT_EXEC; vrflags |= VRFLAG_PROT_TO_MAXPROT(vrflags); error = add_process_memory_range(vm, (intptr_t)s, (intptr_t)e, - NOPHYS, vrflags, NULL, 0, PAGE_SHIFT, &range); + NOPHYS, vrflags, NULL, 0, PAGE_SHIFT, NULL, &range); if (error) { ekprintf("ERROR: adding memory range for vdso. %d\n", error); goto out; @@ -1872,7 +1873,8 @@ int arch_map_vdso(struct process_vm *vm) vrflags |= VR_PROT_READ; vrflags |= VRFLAG_PROT_TO_MAXPROT(vrflags); error = add_process_memory_range(vm, (intptr_t)s, (intptr_t)e, - NOPHYS, vrflags, NULL, 0, PAGE_SHIFT, &range); + NOPHYS, vrflags, NULL, 0, + PAGE_SHIFT, NULL, &range); if (error) { ekprintf("ERROR: adding memory range for vvar. %d\n", error); goto out; diff --git a/kernel/host.c b/kernel/host.c index 1eb671c7..88f9cd73 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -142,7 +142,7 @@ int prepare_process_ranges_args_envs(struct thread *thread, if ((error = add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0, pn->sections[i].len > LARGE_PAGE_SIZE ? LARGE_PAGE_SHIFT : PAGE_SHIFT, - &range)) != 0) { + NULL, &range)) != 0) { kprintf("ERROR: adding memory range for ELF section %i\n", i); goto err; } @@ -289,7 +289,7 @@ int prepare_process_ranges_args_envs(struct thread *thread, dkprintf("%s: args_envs: %d pages\n", __func__, argenv_page_count); if ((error = add_process_memory_range(vm, addr, e, args_envs_p, - flags, NULL, 0, PAGE_SHIFT, NULL)) != 0) { + flags, NULL, 0, PAGE_SHIFT, NULL, NULL)) != 0){ ihk_mc_free_pages_user(args_envs, argenv_page_count); kprintf("ERROR: adding memory range for args/envs\n"); goto err; diff --git a/kernel/include/page.h b/kernel/include/page.h index cead7c47..23faeb41 100644 --- a/kernel/include/page.h +++ b/kernel/include/page.h @@ -72,4 +72,5 @@ extern int anon_on_demand; #ifdef ENABLE_FUGAKU_HACKS extern int hugetlbfs_on_demand; #endif +extern int xpmem_page_in_remote_on_attach; #endif diff --git a/kernel/include/process.h b/kernel/include/process.h index 4874d7de..b5547de6 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -55,6 +55,7 @@ #define VR_MEMTYPE_MASK 0x0f000000 #define VR_PAGEOUT 0x10000000 #define VR_DONTDUMP 0x20000000 +#define VR_XPMEM 0x40000000 #define VR_WIPEONFORK 0x80000000 #define PROT_TO_VR_FLAG(prot) (((unsigned long)(prot) << 16) & VR_PROT_MASK) @@ -850,7 +851,7 @@ int add_process_memory_range(struct process_vm *vm, unsigned long start, unsigned long end, unsigned long phys, unsigned long flag, struct memobj *memobj, off_t offset, - int pgshift, struct vm_range **rp); + int pgshift, void *private_data, struct vm_range **rp); int remove_process_memory_range(struct process_vm *vm, unsigned long start, unsigned long end, int *ro_freedp); int split_process_memory_range(struct process_vm *vm, @@ -875,6 +876,9 @@ struct vm_range *previous_process_memory_range( int extend_up_process_memory_range(struct process_vm *vm, struct vm_range *range, uintptr_t newend); +int page_fault_process_memory_range(struct process_vm *vm, + struct vm_range *range, + uintptr_t fault_addr, uint64_t reason); int page_fault_process_vm(struct process_vm *fault_vm, void *fault_addr, uint64_t reason); int remove_process_region(struct process_vm *vm, diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index abb57321..e54d9306 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -535,7 +535,7 @@ enum set_cputime_mode { void set_cputime(enum set_cputime_mode mode); int do_munmap(void *addr, size_t len, int holding_memory_range_lock); intptr_t do_mmap(uintptr_t addr0, size_t len0, int prot, int flags, int fd, - off_t off0); + off_t off0, const int vrf0, void *private_data); void clear_host_pte(uintptr_t addr, size_t len, int holding_memory_range_lock); typedef int32_t key_t; int do_shmget(key_t key, size_t size, int shmflg); diff --git a/kernel/include/xpmem.h b/kernel/include/xpmem.h index 52cb244b..69228752 100644 --- a/kernel/include/xpmem.h +++ b/kernel/include/xpmem.h @@ -27,6 +27,8 @@ int xpmem_remove_process_memory_range(struct process_vm *vm, struct vm_range *vmr); int xpmem_fault_process_memory_range(struct process_vm *vm, struct vm_range *vmr, unsigned long vaddr, uint64_t reason); +int xpmem_update_process_page_table(struct process_vm *vm, + struct vm_range *vmr); struct xpmem_attachment { ihk_rwspinlock_t at_lock; /* att lock */ diff --git a/kernel/include/xpmem_private.h b/kernel/include/xpmem_private.h index dc2853ff..41d3b867 100644 --- a/kernel/include/xpmem_private.h +++ b/kernel/include/xpmem_private.h @@ -248,11 +248,12 @@ static void xpmem_clear_PTEs_of_att(struct xpmem_attachment *, unsigned long, static int xpmem_remap_pte(struct process_vm *, struct vm_range *, unsigned long, uint64_t, struct xpmem_segment *, unsigned long); -static int xpmem_ensure_valid_page(struct xpmem_segment *, unsigned long); +static int xpmem_ensure_valid_page(struct xpmem_segment *, unsigned long, + int); static pte_t * xpmem_vaddr_to_pte(struct process_vm *, unsigned long, size_t *pgsize); static int xpmem_pin_page(struct xpmem_thread_group *, struct thread *, - struct process_vm *, unsigned long); + struct process_vm *, unsigned long, int); static void xpmem_unpin_pages(struct xpmem_segment *, struct process_vm *, unsigned long, size_t); @@ -406,7 +407,7 @@ static inline void xpmem_tg_ref( DBUG_ON(ihk_atomic_read(&tg->refcnt) <= 0); ihk_atomic_inc(&tg->refcnt); - XPMEM_DEBUG("return: tg->refcnt=%d", tg->refcnt); + //XPMEM_DEBUG("return: tg->refcnt=%d", tg->refcnt); } static inline void xpmem_seg_ref( @@ -415,7 +416,7 @@ static inline void xpmem_seg_ref( DBUG_ON(ihk_atomic_read(&seg->refcnt) <= 0); ihk_atomic_inc(&seg->refcnt); - XPMEM_DEBUG("return: seg->refcnt=%d", seg->refcnt); + //XPMEM_DEBUG("return: seg->refcnt=%d", seg->refcnt); } static inline void xpmem_ap_ref( @@ -424,7 +425,7 @@ static inline void xpmem_ap_ref( DBUG_ON(ihk_atomic_read(&ap->refcnt) <= 0); ihk_atomic_inc(&ap->refcnt); - XPMEM_DEBUG("return: ap->refcnt=%d", ap->refcnt); + //XPMEM_DEBUG("return: ap->refcnt=%d", ap->refcnt); } static inline void xpmem_att_ref( @@ -433,7 +434,7 @@ static inline void xpmem_att_ref( DBUG_ON(ihk_atomic_read(&att->refcnt) <= 0); ihk_atomic_inc(&att->refcnt); - XPMEM_DEBUG("return: att->refcnt=%d", att->refcnt); + //XPMEM_DEBUG("return: att->refcnt=%d", att->refcnt); } static inline int xpmem_is_private_data( diff --git a/kernel/mem.c b/kernel/mem.c index 1e44a2f7..e975aa6b 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -66,6 +66,7 @@ int anon_on_demand = 0; #ifdef ENABLE_FUGAKU_HACKS int hugetlbfs_on_demand; #endif +int xpmem_page_in_remote_on_attach; int sysctl_overcommit_memory = OVERCOMMIT_ALWAYS; static struct ihk_mc_pa_ops *pa_ops; @@ -2144,6 +2145,11 @@ void mem_init(void) kprintf("Demand paging on ANONYMOUS mappings enabled.\n"); anon_on_demand = 1; } + + if (find_command_line("xpmem_page_in_remote_on_attach")) { + kprintf("Demand paging on XPMEM remote mappings enabled.\n"); + xpmem_page_in_remote_on_attach = 1; + } #ifdef ENABLE_FUGAKU_HACKS if (find_command_line("hugetlbfs_on_demand")) { diff --git a/kernel/process.c b/kernel/process.c index 82df0e3c..d3748699 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1465,7 +1465,7 @@ int add_process_memory_range(struct process_vm *vm, unsigned long start, unsigned long end, unsigned long phys, unsigned long flag, struct memobj *memobj, off_t offset, - int pgshift, struct vm_range **rp) + int pgshift, void *private_data, struct vm_range **rp) { dkprintf("%s: start=%lx,end=%lx,phys=%lx,flag=%lx\n", __FUNCTION__, start, end, phys, flag); struct vm_range *range; @@ -1493,7 +1493,7 @@ int add_process_memory_range(struct process_vm *vm, range->memobj = memobj; range->objoff = offset; range->pgshift = pgshift; - range->private_data = NULL; + range->private_data = private_data; range->straight_start = 0; #ifdef ENABLE_TOFU INIT_LIST_HEAD(&range->tofu_stag_list); @@ -1517,6 +1517,10 @@ int add_process_memory_range(struct process_vm *vm, else if (flag & VR_IO_NOCACHE) { rc = update_process_page_table(vm, range, phys, PTATTR_UNCACHABLE); } + else if (flag & VR_XPMEM) { + range->memobj->flags |= MF_XPMEM; + // xpmem_update_process_page_table() is called in do_mmap() + } else if (flag & VR_DEMAND_PAGING) { dkprintf("%s: range: 0x%lx - 0x%lx is demand paging\n", __FUNCTION__, range->start, range->end); @@ -1539,7 +1543,8 @@ int add_process_memory_range(struct process_vm *vm, } /* Clear content! */ - if (phys != NOPHYS && !(flag & (VR_REMOTE | VR_DEMAND_PAGING)) + if (phys != NOPHYS + && !(flag & (VR_REMOTE | VR_DEMAND_PAGING | VR_XPMEM)) && ((flag & VR_PROT_MASK) != VR_PROT_NONE)) { if (!zero_at_free) { @@ -2074,7 +2079,9 @@ out: return error; } -static int page_fault_process_memory_range(struct process_vm *vm, struct vm_range *range, uintptr_t fault_addr, uint64_t reason) +int page_fault_process_memory_range(struct process_vm *vm, + struct vm_range *range, + uintptr_t fault_addr, uint64_t reason) { int error; pte_t *ptep; @@ -2621,7 +2628,8 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn, vrflag |= VR_MAXPROT_READ | VR_MAXPROT_WRITE | VR_MAXPROT_EXEC; #define NOPHYS ((uintptr_t)-1) if ((rc = add_process_memory_range(thread->vm, start, end, NOPHYS, - vrflag, NULL, 0, USER_STACK_PAGE_SHIFT, &range)) != 0) { + vrflag, NULL, 0, USER_STACK_PAGE_SHIFT, + NULL, &range)) != 0) { ihk_mc_free_pages_user(stack, minsz >> PAGE_SHIFT); kprintf("%s: error addding process memory range: %d\n", rc); return rc; @@ -2795,7 +2803,7 @@ unsigned long extend_process_region(struct process_vm *vm, if ((rc = add_process_memory_range(vm, end_allocated, new_end_allocated, (p == 0 ? 0 : virt_to_phys(p)), flag, NULL, 0, - align_shift, NULL)) != 0) { + align_shift, NULL, NULL)) != 0) { ihk_mc_free_pages_user(p, npages); return end_allocated; } diff --git a/kernel/syscall.c b/kernel/syscall.c index 469440e8..4fbd8d87 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1772,6 +1772,12 @@ static int search_free_space(size_t len, int pgshift, uintptr_t *addrp) /* try given addr first */ addr = *addrp; if (addr != 0) { + if ((region->user_end <= addr) + || ((region->user_end - len) < addr)) { + error = -ENOMEM; + goto out; + } + range = lookup_process_memory_range(thread->vm, addr, addr+len); if (range == NULL) goto out; @@ -1807,7 +1813,8 @@ out: intptr_t do_mmap(const uintptr_t addr0, const size_t len0, const int prot, - const int flags, const int fd, const off_t off0) + const int flags, const int fd, const off_t off0, + const int vrf0, void *private_data) { struct thread *thread = cpu_local_var(current); struct vm_regions *region = &thread->vm->region; @@ -1815,11 +1822,11 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot, size_t len = len0; size_t populate_len = 0; off_t off; - int error; - intptr_t npages; + int error = 0; + intptr_t npages = 0; int p2align; void *p = NULL; - int vrflags; + int vrflags = VR_NONE; uintptr_t phys; intptr_t straight_phys; struct memobj *memobj = NULL; @@ -1941,7 +1948,7 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot, if (add_process_memory_range(proc->vm, (unsigned long)proc->straight_va, (unsigned long)proc->straight_va + proc->straight_len, NOPHYS, vrflags, NULL, 0, - PAGE_SHIFT + p2align, &range) != 0) { + PAGE_SHIFT + p2align, private_data, &range) != 0) { kprintf("%s: error: adding straight memory range \n", __FUNCTION__); proc->straight_va = 0; @@ -2076,7 +2083,8 @@ straight_out: } p2align = pgshift - PAGE_SHIFT; } - else if ((flags & MAP_PRIVATE) && (flags & MAP_ANONYMOUS) + else if ((((flags & MAP_PRIVATE) && (flags & MAP_ANONYMOUS)) + || (vrf0 & VR_XPMEM)) && !proc->thp_disable) { pgshift = 0; /* transparent huge page */ p2align = PAGE_P2ALIGN; @@ -2116,22 +2124,24 @@ straight_out: } else if (flags & MAP_ANONYMOUS) { /* Obtain mapping address */ - error = search_free_space(len, PAGE_SHIFT + p2align, &addr); + error = search_free_space(len, + PAGE_SHIFT + p2align, &addr); if (error) { - ekprintf("do_mmap:search_free_space(%lx,%lx,%d) failed. %d\n", - len, region->map_end, p2align, error); + kprintf("%s: error: search_free_space(%lx,%lx,%lx) failed. %d\n", + __func__, len, PAGE_SHIFT + p2align, addr, error); goto out; } } /* do the map */ vrflags = VR_NONE; + vrflags |= vrf0; vrflags |= PROT_TO_VR_FLAG(prot); vrflags |= (flags & MAP_PRIVATE)? VR_PRIVATE: 0; vrflags |= (flags & MAP_LOCKED)? VR_LOCKED: 0; vrflags |= VR_DEMAND_PAGING; - if (flags & MAP_ANONYMOUS) { - if (!anon_on_demand && (flags & MAP_PRIVATE)) { + if (flags & MAP_ANONYMOUS && !anon_on_demand) { + if (flags & MAP_PRIVATE) { vrflags &= ~VR_DEMAND_PAGING; } } @@ -2276,6 +2286,7 @@ straight_out: } /* Prepopulated ANONYMOUS mapping */ else if (!(vrflags & VR_DEMAND_PAGING) + && !(flags & MAP_SHARED) && ((vrflags & VR_PROT_MASK) != VR_PROT_NONE)) { npages = len >> PAGE_SHIFT; /* Small allocations mostly benefit from closest RAM, @@ -2379,7 +2390,7 @@ straight_out: } error = add_process_memory_range(thread->vm, addr, addr+len, phys, - vrflags, memobj, off, pgshift, &range); + vrflags, memobj, off, pgshift, private_data, &range); if (error) { kprintf("%s: add_process_memory_range failed for 0x%lx:%lu" " flags: %lx, vrflags: %lx, pgshift: %d, error: %d\n", @@ -2467,6 +2478,19 @@ out: } ihk_rwspinlock_write_unlock_noirq(&thread->vm->memory_range_lock); + ihk_rwspinlock_read_lock_noirq(&thread->vm->memory_range_lock); + if (!error && range && range->memobj && + (range->memobj->flags & MF_XPMEM)) { + error = xpmem_update_process_page_table(thread->vm, range); + if (error) { + ekprintf("%s: xpmem_update_process_page_table(): " + "vm: %p, range: %lx-%lx failed %d\n", + __func__, thread->vm, + range->start, range->end, error); + } + } + ihk_rwspinlock_read_unlock_noirq(&thread->vm->memory_range_lock); + if (!error && populated_mapping && !((vrflags & VR_PROT_MASK) == VR_PROT_NONE) && !range->straight_start) { error = populate_process_memory(thread->vm, @@ -2496,7 +2520,7 @@ out: } } - if (p) { + if (p && npages > 0) { ihk_mc_free_pages_user(p, npages); } if (memobj) { @@ -5009,7 +5033,7 @@ perf_mmap(struct mckfd *sfd, ihk_mc_user_context_t *ctx) flags |= MAP_ANONYMOUS; prot |= PROT_WRITE; - rc = do_mmap(addr0, len0, prot, flags, fd, off0); + rc = do_mmap(addr0, len0, prot, flags, fd, off0, 0, NULL); // setup perf_event_mmap_page page = (struct perf_event_mmap_page *)rc; @@ -6542,7 +6566,7 @@ SYSCALL_DECLARE(shmat) } error = add_process_memory_range(vm, addr, addr+len, -1, - vrflags, &obj->memobj, 0, obj->pgshift, NULL); + vrflags, &obj->memobj, 0, obj->pgshift, NULL, NULL); if (error) { if (!(prot & PROT_WRITE)) { (void)set_host_vma(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC, 1/* holding memory_range_lock */); @@ -9441,7 +9465,7 @@ SYSCALL_DECLARE(mremap) error = add_process_memory_range(thread->vm, newstart, newend, -1, range->flag, range->memobj, range->objoff + (oldstart - range->start), - range->pgshift, NULL); + 0, NULL, NULL); if (error) { ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):" "add failed. %d\n", diff --git a/kernel/xpmem.c b/kernel/xpmem.c index 7503c8c0..ed89fc8c 100644 --- a/kernel/xpmem.c +++ b/kernel/xpmem.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -222,7 +223,8 @@ static int xpmem_ioctl( attach_info.fd, attach_info.flags, &at_vaddr); if (ret != 0) { - XPMEM_DEBUG("return: cmd=0x%x, ret=%d", cmd, ret); + XPMEM_DEBUG("return: at_vaddr: %lx, cmd=0x%x, ret=%d", + at_vaddr, cmd, ret); return ret; } @@ -233,7 +235,8 @@ static int xpmem_ioctl( return -EFAULT; } - XPMEM_DEBUG("return: cmd=0x%x, ret=%d", cmd, ret); + XPMEM_DEBUG("XPMEM_CMD_ATTACH: return: at_vaddr: %lx, cmd=0x%x, ret=%d", + at_vaddr, cmd, ret); return ret; } @@ -447,8 +450,8 @@ static int xpmem_make( * multiple of pages in size. */ if (offset_in_page(vaddr) != 0 || - /* Special treatment of -1UL */ - (offset_in_page(size) != 0 && size != 0xffffffffffffffff)) { + /* Special treatment of -1UL */ + (offset_in_page(size) != 0 && size != 0xffffffffffffffff)) { xpmem_tg_deref(seg_tg); XPMEM_DEBUG("return: ret=%d", -EINVAL); return -EINVAL; @@ -1011,7 +1014,6 @@ static int xpmem_attach( struct xpmem_segment *seg; struct xpmem_attachment *att; unsigned long at_lock; - struct vm_range *vmr; struct process_vm *vm = cpu_local_var(current)->vm; XPMEM_DEBUG("call: apid=0x%lx, offset=0x%lx, size=0x%lx, vaddr=0x%lx, " @@ -1137,37 +1139,18 @@ static int xpmem_attach( XPMEM_DEBUG("do_mmap(): vaddr=0x%lx, size=0x%lx, prot_flags=0x%lx, " "flags=0x%lx, fd=%d, offset=0x%lx", vaddr, size, prot_flags, flags, mckfd->fd, offset); - /* The new range uses on-demand paging and is associated with shmobj because of - MAP_ANONYMOUS && !MAP_PRIVATE && MAP_SHARED */ - at_vaddr = do_mmap(vaddr, size, prot_flags, flags, mckfd->fd, offset); + /* The new range is associated with shmobj because of + * MAP_ANONYMOUS && !MAP_PRIVATE && MAP_SHARED. Note that MAP_FIXED + * support prevents us from reusing segment vm_range when segment vm + * and attach vm is the same. + */ + at_vaddr = do_mmap(vaddr, size, prot_flags, flags, mckfd->fd, + offset, VR_XPMEM, att); if (IS_ERR((void *)(uintptr_t)at_vaddr)) { ret = at_vaddr; goto out_2; } XPMEM_DEBUG("at_vaddr=0x%lx", at_vaddr); - att->at_vaddr = at_vaddr; - - ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock); - - vmr = lookup_process_memory_range(vm, at_vaddr, at_vaddr + 1); - - /* To identify pages of XPMEM attachment for rusage accounting */ - if(vmr->memobj) { - vmr->memobj->flags |= MF_XPMEM; - } else { - ekprintf("%s: vmr->memobj equals to NULL\n", __FUNCTION__); - } - - ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock); - - if (!vmr) { - ret = -ENOENT; - goto out_2; - } - vmr->private_data = att; - - - att->at_vmr = vmr; *at_vaddr_p = at_vaddr + offset_in_page(att->vaddr); @@ -1193,7 +1176,6 @@ out_1: return ret; } - static int xpmem_detach( unsigned long at_vaddr) { @@ -1757,27 +1739,33 @@ out: } -int xpmem_fault_process_memory_range( +static int _xpmem_fault_process_memory_range( struct process_vm *vm, struct vm_range *vmr, unsigned long vaddr, - uint64_t reason) + uint64_t reason, + int page_in_remote) { int ret = 0; - unsigned long seg_vaddr = 0; - pte_t *pte = NULL; - pte_t *old_pte = NULL; + unsigned long seg_vaddr; struct xpmem_thread_group *ap_tg; struct xpmem_thread_group *seg_tg; struct xpmem_access_permit *ap; struct xpmem_attachment *att; struct xpmem_segment *seg; - size_t pgsize; - unsigned long at_lock; - int att_locked = 0; + pte_t *att_pte; + void *att_pgaddr; + size_t att_pgsize; + int att_p2align; + pte_t *seg_pte; + size_t seg_pgsize; + uintptr_t seg_phys; + uintptr_t seg_phys_plus_off; + uintptr_t seg_phys_aligned; + enum ihk_mc_pt_attribute att_attr; - XPMEM_DEBUG("call: vmr=0x%p, vaddr=0x%lx, reason=0x%lx", - vmr, vaddr, reason); + XPMEM_DEBUG("call: vmr=0x%p, vaddr=0x%lx, reason=0x%lx, page_in_remote: %d", + vmr, vaddr, reason, page_in_remote); att = (struct xpmem_attachment *)vmr->private_data; if (att == NULL) { @@ -1804,70 +1792,169 @@ int xpmem_fault_process_memory_range( seg_tg = seg->tg; xpmem_tg_ref(seg_tg); - at_lock = ihk_rwspinlock_write_lock(&att->at_lock); - att_locked = 1; - if ((seg->flags & XPMEM_FLAG_DESTROYING) || (seg_tg->flags & XPMEM_FLAG_DESTROYING)) { - ret = -ENOENT; - goto out_2; + ret = -EFAULT; + goto out; } if ((att->flags & XPMEM_FLAG_DESTROYING) || (ap_tg->flags & XPMEM_FLAG_DESTROYING) || (seg_tg->flags & XPMEM_FLAG_DESTROYING)) { - goto out_2; + kprintf("%s: XPMEM_FLAG_DESTROYING\n", + __func__); + ret = -EFAULT; + goto out; } if (vaddr < att->at_vaddr || vaddr + 1 > att->at_vaddr + att->at_size) { - goto out_2; + kprintf("%s: vaddr: %lx, att->at_vaddr: %lx, att->at_size: %lx\n", + __func__, vaddr, att->at_vaddr, att->at_size); + ret = -EFAULT; + goto out; } - seg_vaddr = (att->vaddr & PAGE_MASK) + (vaddr - att->at_vaddr); + /* page-in remote pages on page-fault or (on attach and + * xpmem_page_in_remote_on_attach isn't specified) + */ + seg_vaddr = att->vaddr + (vaddr - att->at_vaddr); XPMEM_DEBUG("vaddr=%lx, seg_vaddr=%lx", vaddr, seg_vaddr); - ret = xpmem_ensure_valid_page(seg, seg_vaddr); + ret = xpmem_ensure_valid_page(seg, seg_vaddr, page_in_remote); if (ret != 0) { - goto out_2; + goto out; } - pte = xpmem_vaddr_to_pte(seg_tg->vm, seg_vaddr, &pgsize); + if (is_remote_vm(seg_tg->vm)) { + ihk_rwspinlock_read_lock_noirq(&seg_tg->vm->memory_range_lock); + } + + if (seg_tg->vm->proc->straight_va && + seg_vaddr >= (unsigned long)seg_tg->vm->proc->straight_va && + seg_vaddr < ((unsigned long)seg_tg->vm->proc->straight_va + + seg_tg->vm->proc->straight_len)) { + seg_phys = (((unsigned long)seg_vaddr & PAGE_MASK) - + (unsigned long)seg_tg->vm->proc->straight_va) + + seg_tg->vm->proc->straight_pa; + seg_pgsize = (1UL << 29); + XPMEM_DEBUG("seg_vaddr: 0x%lx in PID %d is straight -> phys: 0x%lx", + (unsigned long)seg_vaddr & PAGE_MASK, + seg_tg->tgid, seg_phys); + } + else { + seg_pte = xpmem_vaddr_to_pte(seg_tg->vm, seg_vaddr, &seg_pgsize); + + /* map only resident remote pages on attach and + * xpmem_page_in_remote_on_attach is specified + */ + if (!seg_pte || pte_is_null(seg_pte)) { + ret = page_in_remote ? -EFAULT : 0; + if (is_remote_vm(seg_tg->vm)) { + ihk_rwspinlock_read_unlock_noirq(&seg_tg->vm->memory_range_lock); + } + goto out; + } + + seg_phys = pte_get_phys(seg_pte); + } + + /* clear lower bits of the contiguous-PTE tail entries */ + seg_phys_plus_off = (seg_phys & ~(seg_pgsize - 1)) | + (seg_vaddr & (seg_pgsize - 1)); + XPMEM_DEBUG("seg_vaddr: %lx, seg_phys: %lx, seg_phys_plus_off: %lx, seg_pgsize: %lx", + seg_vaddr, seg_phys, seg_phys_plus_off, seg_pgsize); + + if (is_remote_vm(seg_tg->vm)) { + ihk_rwspinlock_read_unlock_noirq(&seg_tg->vm->memory_range_lock); + } + + /* find largest page-size fitting vm range and segment page */ + att_pte = ihk_mc_pt_lookup_pte(vm->address_space->page_table, + (void *)vaddr, vmr->pgshift, &att_pgaddr, &att_pgsize, + &att_p2align); + + while ((unsigned long)att_pgaddr < vmr->start || + vmr->end < (uintptr_t)att_pgaddr + att_pgsize || + att_pgsize > seg_pgsize) { + att_pte = NULL; + ret = arch_get_smaller_page_size(NULL, att_pgsize, + &att_pgsize, &att_p2align); + if (ret) { + kprintf("%s: arch_get_smaller_page_size failed: " + " range: %lx-%lx, pgsize: %lx, ret: %d\n", + __func__, vmr->start, vmr->end, att_pgsize, + ret); + goto out; + } + att_pgaddr = (void *)(vaddr & ~(att_pgsize - 1)); + } + + arch_adjust_allocate_page_size(vm->address_space->page_table, + vaddr, att_pte, &att_pgaddr, + &att_pgsize); + + seg_phys_aligned = seg_phys_plus_off & ~(att_pgsize - 1); + + XPMEM_DEBUG("att_pte=%p, att_pgaddr=0x%p, att_pgsize=%lu, " + "att_p2align=%d", + att_pte, att_pgaddr, att_pgsize, att_p2align); + + /* last arg is not used */ + att_attr = arch_vrflag_to_ptattr(vmr->flag, reason, NULL); + XPMEM_DEBUG("att_attr=0x%lx", att_attr); + + if (att_pte && !pte_is_null(att_pte)) { + unsigned long att_phys = pte_get_phys(att_pte); + + if (att_phys != seg_phys_aligned) { + ret = -EFAULT; + ekprintf("%s: ERROR: pte mismatch: " + "0x%lx != 0x%lx\n", + __func__, att_phys, seg_phys_aligned); + } + + if (page_in_remote) { + ihk_atomic_dec(&seg->tg->n_pinned); + } + goto out; + } + + XPMEM_DEBUG("att_pgaddr: %lx, att_pgsize: %lx, " + "seg_vaddr: %lx, seg_pgsize: %lx, " + "seg_phys_aligned: %lx\n", + att_pgaddr, att_pgsize, seg_vaddr, + seg_pgsize, seg_phys_aligned); + if (att_pte && !pgsize_is_contiguous(att_pgsize)) { + ret = ihk_mc_pt_set_pte(vm->address_space->page_table, + att_pte, att_pgsize, + seg_phys_aligned, + att_attr); + if (ret) { + ret = -EFAULT; + ekprintf("%s: ERROR: ihk_mc_pt_set_pte() failed %d\n", + __func__, ret); + goto out; + } + } + else { + ret = ihk_mc_pt_set_range(vm->address_space->page_table, vm, + att_pgaddr, att_pgaddr + att_pgsize, + seg_phys_aligned, + att_attr, vmr->pgshift, vmr, 1); + if (ret) { + ret = -EFAULT; + ekprintf("%s: ERROR: ihk_mc_pt_set_range() failed %d\n", + __func__, ret); + goto out; + } + } att->flags |= XPMEM_FLAG_VALIDPTEs; - -out_2: - xpmem_ap_deref(ap); - xpmem_tg_deref(ap_tg); - - if (pte && !pte_is_null(pte)) { - old_pte = xpmem_vaddr_to_pte(cpu_local_var(current)->vm, vaddr, - &pgsize); - if (old_pte && !pte_is_null(old_pte)) { - if (*old_pte != *pte) { - ret = -EFAULT; - ekprintf("%s: ERROR: pte mismatch: " - "0x%lx != 0x%lx\n", - __FUNCTION__, *old_pte, *pte); - } - - ihk_atomic_dec(&seg->tg->n_pinned); - goto out_1; - } - - ret = xpmem_remap_pte(vm, vmr, vaddr, reason, seg, seg_vaddr); - if (ret) { - ekprintf("%s: ERROR: xpmem_remap_pte() failed %d\n", - __FUNCTION__, ret); - } - } - flush_tlb_single(vaddr); -out_1: - if (att_locked) { - ihk_rwspinlock_write_unlock(&att->at_lock, at_lock); - } - +out: + xpmem_ap_deref(ap); + xpmem_tg_deref(ap_tg); xpmem_tg_deref(seg_tg); xpmem_seg_deref(seg); xpmem_att_deref(att); @@ -1877,125 +1964,124 @@ out_1: return ret; } - -static int xpmem_remap_pte( +int xpmem_fault_process_memory_range( struct process_vm *vm, struct vm_range *vmr, unsigned long vaddr, - uint64_t reason, - struct xpmem_segment *seg, - unsigned long seg_vaddr) + uint64_t reason) { int ret; - struct xpmem_thread_group *seg_tg = seg->tg; - struct vm_range *seg_vmr; - pte_t *seg_pte; - void *seg_pgaddr; - size_t seg_pgsize; - int seg_p2align; - uintptr_t seg_phys; - pte_t *att_pte; - void *att_pgaddr; - size_t att_pgsize; - int att_p2align; - enum ihk_mc_pt_attribute att_attr; + unsigned long at_lock; + struct xpmem_attachment *att; - XPMEM_DEBUG("call: vmr=0x%p, vaddr=0x%lx, reason=0x%lx, segid=0x%lx, " - "seg_vaddr=0x%lx", - vmr, vaddr, reason, seg->segid, seg_vaddr); + att = (struct xpmem_attachment *)vmr->private_data; + if (att == NULL) { + return -EFAULT; + } + at_lock = ihk_rwspinlock_read_lock(&att->at_lock); + ret = _xpmem_fault_process_memory_range(vm, vmr, vaddr, reason, 1); + ihk_rwspinlock_read_unlock(&att->at_lock, at_lock); + return ret; +} - if (is_remote_vm(seg_tg->vm)) { - ihk_rwspinlock_read_lock_noirq(&seg_tg->vm->memory_range_lock); +int xpmem_update_process_page_table( + struct process_vm *vm, struct vm_range *vmr) +{ + int ret = 0; + unsigned long vaddr; + pte_t *pte; + size_t pgsize; + struct xpmem_thread_group *ap_tg; + struct xpmem_thread_group *seg_tg; + struct xpmem_access_permit *ap; + struct xpmem_attachment *att; + struct xpmem_segment *seg; + + XPMEM_DEBUG("call: vmr=0x%p", vmr); + + att = (struct xpmem_attachment *)vmr->private_data; + if (att == NULL) { + return -EFAULT; } - seg_vmr = lookup_process_memory_range(seg_tg->vm, seg_vaddr, - seg_vaddr + 1); + xpmem_att_ref(att); + ap = att->ap; + xpmem_ap_ref(ap); + ap_tg = ap->tg; + xpmem_tg_ref(ap_tg); - if (!seg_vmr) { + if ((ap->flags & XPMEM_FLAG_DESTROYING) || + (ap_tg->flags & XPMEM_FLAG_DESTROYING)) { ret = -EFAULT; - ekprintf("%s: ERROR: lookup_process_memory_range() failed\n", - __FUNCTION__); - goto out; + goto out_1; } - if (seg_tg->vm->proc->straight_va && - seg_vaddr >= (unsigned long)seg_tg->vm->proc->straight_va && - seg_vaddr < ((unsigned long)seg_tg->vm->proc->straight_va + - seg_tg->vm->proc->straight_len)) { - seg_phys = (((unsigned long)seg_vaddr & PAGE_MASK) - - (unsigned long)seg_tg->vm->proc->straight_va) + - seg_tg->vm->proc->straight_pa; - dkprintf("%s: 0x%lx in PID %d is straight -> phys: 0x%lx\n", - __func__, (unsigned long)seg_vaddr & PAGE_MASK, - seg_tg->tgid, seg_phys); - } - else { + DBUG_ON(cpu_local_var(current)->proc->pid != ap_tg->tgid); + DBUG_ON(ap->mode != XPMEM_RDWR); - seg_pte = ihk_mc_pt_lookup_pte(seg_tg->vm->address_space->page_table, - (void *)seg_vaddr, seg_vmr->pgshift, &seg_pgaddr, &seg_pgsize, - &seg_p2align); - if (!seg_pte) { - ret = -EFAULT; - ekprintf("%s: ERROR: ihk_mc_pt_lookup_pte() failed\n", - __FUNCTION__); - goto out; - } - XPMEM_DEBUG("seg_pte=0x%016lx, seg_pgaddr=0x%p, seg_pgsize=%lu, " - "seg_p2align=%d", - *seg_pte, seg_pgaddr, seg_pgsize, seg_p2align); + seg = ap->seg; + xpmem_seg_ref(seg); + seg_tg = seg->tg; + xpmem_tg_ref(seg_tg); - seg_phys = pte_get_phys(seg_pte); - XPMEM_DEBUG("seg_phys=0x%lx", seg_phys); + if ((seg->flags & XPMEM_FLAG_DESTROYING) || + (seg_tg->flags & XPMEM_FLAG_DESTROYING)) { + ret = -ENOENT; + goto out_2; } - att_pte = ihk_mc_pt_lookup_pte(vm->address_space->page_table, - (void *)vaddr, vmr->pgshift, &att_pgaddr, &att_pgsize, - &att_p2align); - XPMEM_DEBUG("att_pte=%p, att_pgaddr=0x%p, att_pgsize=%lu, " - "att_p2align=%d", - att_pte, att_pgaddr, att_pgsize, att_p2align); + att->at_vaddr = vmr->start; + att->at_vmr = vmr; - att_attr = arch_vrflag_to_ptattr(vmr->flag, reason, att_pte); - XPMEM_DEBUG("att_attr=0x%lx", att_attr); + if ((att->flags & XPMEM_FLAG_DESTROYING) || + (ap_tg->flags & XPMEM_FLAG_DESTROYING) || + (seg_tg->flags & XPMEM_FLAG_DESTROYING)) { + goto out_2; + } - if (att_pte) { - ret = ihk_mc_pt_set_pte(vm->address_space->page_table, att_pte, - att_pgsize, seg_phys, att_attr); + for (vaddr = vmr->start; vaddr < vmr->end; vaddr += pgsize) { + XPMEM_DEBUG("vmr: %lx-%lx, vaddr: %lx", + vmr->start, vmr->end, vaddr); + + ret = _xpmem_fault_process_memory_range(vm, vmr, vaddr, + 0, + xpmem_page_in_remote_on_attach); if (ret) { - ret = -EFAULT; - ekprintf("%s: ERROR: ihk_mc_pt_set_pte() failed %d\n", - __FUNCTION__, ret); - goto out; + ekprintf("%s: ERROR: " + "_xpmem_fault_process_memory_range() " + "failed %d\n", __func__, ret); } - // memory_stat_rss_add() is called by the process hosting the memory area - } - else { - ret = ihk_mc_pt_set_range(vm->address_space->page_table, vm, - att_pgaddr, att_pgaddr + att_pgsize, seg_phys, att_attr, - vmr->pgshift, vmr, 0); - if (ret) { - ret = -EFAULT; - ekprintf("%s: ERROR: ihk_mc_pt_set_range() failed %d\n", - __FUNCTION__, ret); - goto out; + + pte = ihk_mc_pt_lookup_pte(vm->address_space->page_table, + (void *)vaddr, vmr->pgshift, + NULL, &pgsize, NULL); + + /* when segment page is not resident and + * xpmem_page_in_remote_on_attach is specified + */ + if (!pte || pte_is_null(pte)) { + pgsize = PAGE_SIZE; } - // memory_stat_rss_add() is called by the process hosting the memory area } -out: - if (is_remote_vm(seg_tg->vm)) { - ihk_rwspinlock_read_unlock_noirq(&seg_tg->vm->memory_range_lock); - } +out_2: + xpmem_tg_deref(seg_tg); + xpmem_seg_deref(seg); + +out_1: + xpmem_att_deref(att); + xpmem_ap_deref(ap); + xpmem_tg_deref(ap_tg); XPMEM_DEBUG("return: ret=%d", ret); return ret; } - static int xpmem_ensure_valid_page( struct xpmem_segment *seg, - unsigned long vaddr) + unsigned long vaddr, + int page_in) { int ret; struct xpmem_thread_group *seg_tg = seg->tg; @@ -2005,7 +2091,8 @@ static int xpmem_ensure_valid_page( if (seg->flags & XPMEM_FLAG_DESTROYING) return -ENOENT; - ret = xpmem_pin_page(seg_tg, seg_tg->group_leader, seg_tg->vm, vaddr); + ret = xpmem_pin_page(seg_tg, seg_tg->group_leader, seg_tg->vm, vaddr, + page_in); XPMEM_DEBUG("return: ret=%d", ret); @@ -2043,8 +2130,7 @@ static pte_t * xpmem_vaddr_to_pte( } out: - - return pte; + return pte; } @@ -2052,21 +2138,26 @@ static int xpmem_pin_page( struct xpmem_thread_group *tg, struct thread *src_thread, struct process_vm *src_vm, - unsigned long vaddr) + unsigned long vaddr, + int page_in) { - int ret; + int ret = 0; struct vm_range *range; XPMEM_DEBUG("call: tgid=%d, vaddr=0x%lx", tg->tgid, vaddr); retry: - ihk_rwspinlock_read_lock_noirq(&src_vm->memory_range_lock); + if (is_remote_vm(src_vm)) { + ihk_rwspinlock_read_lock_noirq(&src_vm->memory_range_lock); + } range = lookup_process_memory_range(src_vm, vaddr, vaddr + 1); - ihk_rwspinlock_read_unlock_noirq(&src_vm->memory_range_lock); - if (!range || range->start > vaddr) { + if (is_remote_vm(src_vm)) { + ihk_rwspinlock_read_unlock_noirq(&src_vm->memory_range_lock); + } + /* * Grow the stack if address falls into stack region * so that we can lookup range successfully. @@ -2085,21 +2176,31 @@ retry: } if (xpmem_is_private_data(range)) { - return -ENOENT; + ret = -ENOENT; + goto out; } - ret = page_fault_process_vm(src_vm, (void *)vaddr, - PF_POPULATE | PF_WRITE | PF_USER); - if (!ret) { + /* Page-in remote area */ + if (page_in) { + /* skip read lock for the case src_vm is local + * because write lock is taken in do_mmap. + */ + ret = page_fault_process_memory_range(src_vm, range, + vaddr, + PF_POPULATE | PF_WRITE | + PF_USER); + if (ret) { + goto out; + } ihk_atomic_inc(&tg->n_pinned); } - else { - return -ENOENT; + +out: + if (is_remote_vm(src_vm)) { + ihk_rwspinlock_read_unlock_noirq(&src_vm->memory_range_lock); } - XPMEM_DEBUG("return: ret=%d", ret); - - return ret; + return ret; } @@ -2109,30 +2210,27 @@ static void xpmem_unpin_pages( unsigned long vaddr, size_t size) { - int n_pgs = (((offset_in_page(vaddr) + (size)) + (PAGE_SIZE - 1)) >> - PAGE_SHIFT); int n_pgs_unpinned = 0; size_t vsize = 0; + unsigned long end = vaddr + size; pte_t *pte = NULL; XPMEM_DEBUG("call: segid=0x%lx, vaddr=0x%lx, size=0x%lx", seg->segid, vaddr, size); - XPMEM_DEBUG("n_pgs=%d", n_pgs); - vaddr &= PAGE_MASK; - while (n_pgs > 0) { + /* attachment can't be straight-mapped because it's mapped + * with MAP_SHARED + */ + while (vaddr < end) { pte = xpmem_vaddr_to_pte(vm, vaddr, &vsize); if (pte && !pte_is_null(pte)) { n_pgs_unpinned++; - vaddr += PAGE_SIZE; - n_pgs--; + vaddr += vsize; } else { - vsize = ((vaddr + vsize) & (~(vsize - 1))); - n_pgs -= (vsize - vaddr) / PAGE_SIZE; - vaddr = vsize; + vaddr = ((vaddr + vsize) & (~(vsize - 1))); } } @@ -2196,8 +2294,8 @@ static void xpmem_tg_deref( { DBUG_ON(ihk_atomic_read(&tg->refcnt) <= 0); if (ihk_atomic_dec_return(&tg->refcnt) != 0) { - XPMEM_DEBUG("return: tg->refcnt=%d, tg->n_pinned=%d", - tg->refcnt, tg->n_pinned); + /*XPMEM_DEBUG("return: tg->refcnt=%d, tg->n_pinned=%d", + tg->refcnt, tg->n_pinned);*/ return; } @@ -2236,7 +2334,7 @@ static void xpmem_seg_deref(struct xpmem_segment *seg) { DBUG_ON(ihk_atomic_read(&seg->refcnt) <= 0); if (ihk_atomic_dec_return(&seg->refcnt) != 0) { - XPMEM_DEBUG("return: seg->refcnt=%d", seg->refcnt); + //XPMEM_DEBUG("return: seg->refcnt=%d", seg->refcnt); return; } @@ -2282,7 +2380,7 @@ static void xpmem_ap_deref(struct xpmem_access_permit *ap) { DBUG_ON(ihk_atomic_read(&ap->refcnt) <= 0); if (ihk_atomic_dec_return(&ap->refcnt) != 0) { - XPMEM_DEBUG("return: ap->refcnt=%d", ap->refcnt); + //XPMEM_DEBUG("return: ap->refcnt=%d", ap->refcnt); return; } @@ -2297,7 +2395,7 @@ static void xpmem_att_deref(struct xpmem_attachment *att) { DBUG_ON(ihk_atomic_read(&att->refcnt) <= 0); if (ihk_atomic_dec_return(&att->refcnt) != 0) { - XPMEM_DEBUG("return: att->refcnt=%d", att->refcnt); + //XPMEM_DEBUG("return: att->refcnt=%d", att->refcnt); return; } diff --git a/test/common.sh b/test/common.sh index 50726239..de7b913a 100644 --- a/test/common.sh +++ b/test/common.sh @@ -107,7 +107,7 @@ fi mcstop() { echo -n "mcstop+release.sh ... " - sudo "$SBIN/mcstop+release.sh" + "$SBIN/mcstop+release.sh" echo "done" if lsmod | grep mcctrl > /dev/null 2>&1; then @@ -118,7 +118,7 @@ mcstop() { mcreboot() { echo -n "mcreboot.sh $BOOTPARAM ... " - sudo "$SBIN/mcreboot.sh" $BOOTPARAM + "$SBIN/mcreboot.sh" $BOOTPARAM echo "done" if ! lsmod | grep mcctrl > /dev/null 2>&1; then diff --git a/test/issues/1259/C1259.sh b/test/issues/1259/C1259.sh new file mode 100755 index 00000000..49c1730d --- /dev/null +++ b/test/issues/1259/C1259.sh @@ -0,0 +1,190 @@ +#!/usr/bin/bash + +USELTP=0 +USEOSTEST=0 + +XPMEM_DIR=$HOME/usr +XPMEM_BUILD_DIR=/home/satoken/xpmem + +arch=`uname -p` +if [ -f "./${arch}_config" ]; then + . ./${arch}_config +else + echo "$1 is unexpected arch" + exit 1 +fi + +. ../../common.sh + +sudo insmod ${XPMEM_DIR}/lib/modules/`uname -r`/xpmem.ko +sudo chmod og+rw /dev/xpmem + +issue=1259 +tid=01 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem_attach to Huge mapped memory range" +echo "** end of range is aligned with Large page size" +for pgshift in ${PGSHIFT_LIST[@]} +do + ${IHKOSCTL} 0 clear_kmsg + log_file="./C${issue}T${tid}_${pgshift}.log" + echo pageshift: ${pgshift} + ${MCEXEC} ./huge_page_xpmem ${pgshift} 2 0 > ${log_file} + ${IHKOSCTL} 0 kmsg >> ${log_file} + + EXPECT_PGSIZE=`grep EXPECT_PAGE_SIZE ${log_file} | awk '{ print $2; }'` + + SEG_ADDR=`grep parent: ${log_file} | awk '{ print $3; }'` + SEG_PGSIZE=`cat ${log_file} | awk '/OK/,/DONE/' | \ +grep -o "large_page_allocation.*${SEG_ADDR}.*" | awk '{ print $5; }'` + + XPMEM_ADDR=`grep xpmem_attachment_addr ${log_file} | awk '{ print $NF; }'` + XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $NF; }'` + + if [ "${SEG_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + echo "** [ OK ] seg_addr ($SEG_ADDR) is allocated until xpmem_attach" + else + echo "** [ NG ] seg_addr ($SEG_ADDR) is NOT allocated until xpmem_attach" + let ng++ + fi + if [ "${XPMEM_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + echo "** [ OK ] xpmem_addr ($XPMEM_ADDR) is allocated using large pages" + else + echo "** [ NG ] xpmem_addr ($XPMEM_ADDR) is NOT allocated using large pages" + let ng++ + fi +done +if [ ${ng} -eq 0 ]; then + echo "*** C${issue}T${tid}: PASSED" +else + echo "*** C${issue}T${tid}: FAILED" +fi +echo "" + +tid=02 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem_attach to Huge mapped memory range" +echo "** end of range is NOT aligned with Large page size" +for pgshift in ${PGSHIFT_LIST[@]} +do + ${IHKOSCTL} 0 clear_kmsg + log_file="./C${issue}T${tid}_${pgshift}.log" + echo pageshift: ${pgshift} + ${MCEXEC} ./huge_page_xpmem ${pgshift} 2 ${SMALL_PGSIZE} > ${log_file} + ${IHKOSCTL} 0 kmsg >> ${log_file} + + EXPECT_PGSIZE=`grep EXPECT_PAGE_SIZE ${log_file} | awk '{ print $2; }'` + + SEG_ADDR=`grep parent: ${log_file} | awk '{ print $3; }'` + SEG_PGSIZE=`cat ${log_file} | awk '/OK/,/DONE/' | \ +grep -o "large_page_allocation.*${SEG_ADDR}.*" | awk '{ print $5; }'` + + XPMEM_ADDR=`grep xpmem_attachment_addr ${log_file} | awk '{ print $NF; }'` + XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $NF; }'` + + if [ "${SEG_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + printf "** [ OK ] " + else + printf "** [ NG ] " + let ng++ + fi + echo "size of 1st page of segment at ${SEG_ADDR}: ${SEG_PGSIZE}, expected: ${EXPECT_PGSIZE}" + + if [ "${XPMEM_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + printf "** [ OK ] " + else + printf "** [ NG ] " + let ng++ + fi + echo "size of 1st page of attachment at ${XPMEM_ADDR}: ${XPMEM_PGSIZE}, expected: ${EXPECT_PGSIZE}" +done +if [ ${ng} -eq 0 ]; then + echo "*** C${issue}T${tid}: PASSED" +else + echo "*** C${issue}T${tid}: FAILED" +fi +echo "" + +tid=03 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem_attach to small mapped memory range" +${IHKOSCTL} 0 clear_kmsg +log_file="./C${issue}T${tid}.log" +echo pageshift: small page +${MCEXEC} ./huge_page_xpmem -1 2 0 > ${log_file} +${IHKOSCTL} 0 kmsg >> ${log_file} + +EXPECT_PGSIZE=`grep EXPECT_PAGE_SIZE ${log_file} | awk '{ print $2; }'` + +XPMEM_ADDR=`grep xpmem_attachment_addr ${log_file} | awk '{ print $NF; }'` +XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $NF; }'` + +if [ "${XPMEM_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + echo "** [ OK ] xpmem_addr ($XPMEM_ADDR) is allocated using small pages" +else + echo "** [ NG ] xpmem_addr ($XPMEM_ADDR) is NOT allocated using small pages" + ng=1 +fi +if [ ${ng} -eq 0 ]; then + echo "*** C${issue}T${tid}: PASSED" +else + echo "*** C${issue}T${tid}: FAILED" +fi +echo "" + +tid=04 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem_attach to multi pagesize range" +pgshift=${PGSHIFT_LIST[0]} +${IHKOSCTL} 0 clear_kmsg +log_file="./C${issue}T${tid}_${pgshift}.log" +echo pageshift: ${pgshift} +${MCEXEC} ./multi_vmr_xpmem ${pgshift} 1 | tee ${log_file} +${IHKOSCTL} 0 kmsg >> ${log_file} + +EXPECT_PGSIZE=`grep EXPECT_PAGE_SIZE ${log_file} | awk '{ print $2; }'` + +XPMEM_ADDR=`grep xpmem_large ${log_file} | awk '{ print $NF; }'` +XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $NF; }'` + +if [ "${XPMEM_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + echo "** [ OK ] xpmem_addr ($XPMEM_ADDR) is allocated using large pages" +else + echo "** [ NG ] xpmem_addr ($XPMEM_ADDR) is NOT allocated using large pages" + let ng++ +fi +if [ ${ng} -eq 0 ]; then + echo "*** C${issue}T${tid}: PASSED" +else + echo "*** C${issue}T${tid}: FAILED" +fi +echo "" + +tid=05 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem testsuite" +cwd=`pwd` +cd ${XPMEM_BUILD_DIR}/test +. ${cwd}/mc_run.sh +cd ${cwd} + +# xpmem basic test +${MCEXEC} ./XTP_001 +${MCEXEC} ./XTP_002 +${MCEXEC} ./XTP_003 +${MCEXEC} ./XTP_004 +${MCEXEC} ./XTP_005 +${MCEXEC} ./XTP_006 +sleep 3 +${MCEXEC} ./XTP_007 +${MCEXEC} ./XTP_008 +${MCEXEC} ./XTP_009 +${MCEXEC} ./XTP_010 +${MCEXEC} ./XTP_011 + +sudo rmmod xpmem.ko diff --git a/test/issues/1259/Makefile b/test/issues/1259/Makefile new file mode 100644 index 00000000..77c9844b --- /dev/null +++ b/test/issues/1259/Makefile @@ -0,0 +1,12 @@ +XPMEM_DIR=$(HOME)/usr +CPPFLAGS=-I$(XPMEM_DIR)/include +LDFLAGS=-L$(XPMEM_DIR)/lib -Wl,-rpath -Wl,$(XPMEM_DIR)/lib -lxpmem + +TARGET=huge_page_xpmem multi_vmr_xpmem XTP_001 XTP_002 XTP_003 XTP_004 XTP_005 XTP_006 XTP_007 XTP_008 XTP_009 XTP_010 XTP_011 + +all: $(TARGET) +test: all + bash ./C1259.sh +clean: + rm -f $(TARGET) C*.log + diff --git a/test/issues/1259/README b/test/issues/1259/README new file mode 100644 index 00000000..cd780c1a --- /dev/null +++ b/test/issues/1259/README @@ -0,0 +1,104 @@ +【Issue#1259 動作確認】 +□ テスト内容 +1. Large pageでマップされたメモリ領域でのxpmemの動作確認 +C1259T01: + Large pageでマップされたメモリ領域に対してxpmem_attachを行った場合、 + attach先の領域がxpmem_makeでページインされることを確認する + また、xpmemでもLarge pageが利用されることを確認する + +C1259T02: + Large pageでかつ、最後のページがLarge pageサイズでアラインされていない + メモリ領域に対してxpmem_attachを行った場合、 + xpmemでもLarge pageが利用されることを確認する + +C1259T03: + Small pageでマップされたメモリ領域に対してxpmem_attachを行った場合、 + xpmemでもSmall pageが利用されることを確認する + +C1259T04: + small - large - small のように、異なるページサイズの複数のvm_rangeから + 構成されるメモリ領域に対してxpmem_attach を行った場合、 + xpmemでも同じ構成でLarge pageが利用されることを確認する + +2. xpmemのテストスイートによる動作確認 +xpmemに付属するテストスイートをMcKernelで実行し、PASSすることを確認する + +3. xpmemの基本操作の確認 +xpmemで操作するメモリ領域は、Large pageでマップする + +XTP_001: 単一プロセスでのXPMEM操作 + 1. 実行したプロセスがxpmem_make -> xpmem_get -> xpmem_attach -> xpmem_detach -> xpmem_remove + +XTP_002: 子プロセスでのXPMEM操作 + 1. 親プロセスがfork() + 2. 子プロセスがxpmem_make -> xpmem_get -> xpmem_attach -> xpmem_detach ->xpmem_remove + 3. 子プロセス終了後、親プロセスが終了 + +XTP_003: 親プロセスがmakeした共有領域への子プロセスによるXPMEM操作 + 1. 親プロセスがxpmem_make + 2. fork()で子プロセスを作成 + 3. 子プロセスで、xpmem_get -> xpmem_attach -> 値(TEST_VAL)の設定 -> xpmem_detach + 4. 子プロセスが終了 + 5. 親プロセスが、子プロセスによって設定された値(TEST_VAL)を確認 + 6. 親プロセスがxpmem_remove + +XTP_004: fork()後に親プロセスがmakeした共有領域への子プロセスによるXPMEM操作 + 1. fork()で子プロセスを作成 + 2. 親プロセスがxpmem_make + 3. 子プロセスで、xpmem_get -> xpmem_attach -> 値(TEST_VAL)の設定 -> xpmem_detach + 4. 子プロセスが終了 + 5. 親プロセスが、子プロセスによって設定された値(TEST_VAL)を確認 + 6. 親プロセスがxpmem_remove + +XTP_005: 子プロセスがxpmem_attach後、xpmem_detachをせずに終了 + 1. 親プロセスがxpmem_make + 2. fork()で子プロセスを作成 + 3. 子プロセスで、xpmem_get -> xpmem_attach + 4. 子プロセスが終了 + 5. 親プロセスがxpmem_remove + +XTP_006: 子プロセスがXPMEM操作を行う時点で、xpmem_makeをした親プロセスが終了している + 1. 親プロセスがxpmem_make + 2. fork()で子プロセスを作成 + 3. 親プロセスが終了 + 4. 子プロセスで、xpmem_get (失敗) + 5. 子プロセスが終了 + +XTP_007: xpmem_make 呼び出しの異常系 + 1. xpmem_make の第1引数に不正なアドレスを指定する (失敗) + 2. 1度xpmem_make を実施したメモリ領域に対して、再度xpmem_make を行う (成功) + +XTP_008: xpmem_get 呼び出しの異常系 + 1. xpmem_get の第1引数に不正なsegidを指定する (失敗) + 2. 1度xpmem_get を実施したsegidで、再度xpmem_get を行う (成功) + +XTP_009: xpmem_attach 呼び出しの異常系 + 1. xpmem_attach の第1引数に不正なapidを指定する (失敗) + 2. 1度xpmem_attach を実施したapidで、再度xpmem_attach を行う (成功) + +XTP_010: xpmem_detach 呼び出しの異常系 + 1. xpmem_detach の第1引数に不正なアドレスを指定する (成功) + 2. 1度xpmem_detach を実施したメモリ領域に対して、再度xpmem_detach を行う (成功) + +XTP_011: xpmem_remove 呼び出しの異常系 + 1. xpmem_remove の第1引数に不正なsegidを指定する (失敗) + 2. 1度xpmem_remove を実施したsegidで、再度xpmem_remove を行う (失敗) + +□ 実行手順 +1. xpmemのインストールディレクトリをMakefileとC1259.sh中のXPMEM_DIRに記載する +2. xpmemのビルドディレクトリをC1259.sh中のXPMEM_BUILD_DIRに記載する +3. 下記の手順でテストを実行する +$ cd +$ patch -p0 < test/issues/1259/large_page.patch +(build mckernel) +$ cd test/issues/1259 +$ make test + +McKernelのインストール先や、OSTEST, LTPの配置場所は、 +$HOME/.mck_test_config を参照している +.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを +$HOMEにコピーし、適宜編集する + +□ 実行結果 +x86_64_result.log, aarch64_result.log 参照。 +すべての項目をPASSしていることを確認。 diff --git a/test/issues/1259/XTP_001.c b/test/issues/1259/XTP_001.c new file mode 100644 index 00000000..41f87cbf --- /dev/null +++ b/test/issues/1259/XTP_001.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid == -1, "xpmem_make"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid == -1, "xpmem_get"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach == (void *)-1, "xpmem_attach"); + + rc = xpmem_detach(attach); + OKNG(rc == -1, "xpmem_detach"); + + rc = xpmem_remove(segid); + OKNG(rc == -1, "xpmem_remove"); + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_002.c b/test/issues/1259/XTP_002.c new file mode 100644 index 00000000..ce7d1f95 --- /dev/null +++ b/test/issues/1259/XTP_002.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init in child"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, + (void *)0666); + OKNG(segid == -1, "xpmem_make in child"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid == -1, "xpmem_get in child"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach == (void *)-1, "xpmem_attach in child"); + + rc = xpmem_detach(attach); + OKNG(rc == -1, "xpmem_detach in child"); + + rc = xpmem_remove(segid); + OKNG(rc == -1, "xpmem_remove in child"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_003.c b/test/issues/1259/XTP_003.c new file mode 100644 index 00000000..3bd58fc9 --- /dev/null +++ b/test/issues/1259/XTP_003.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid == -1, "xpmem_make"); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid == -1, "xpmem_get in child"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach == (void *)-1, "xpmem_attach in child"); + + *((unsigned long *)attach) = TEST_VAL; + + rc = xpmem_detach(attach); + OKNG(rc == -1, "xpmem_detach in child"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + + OKNG(*((unsigned long *)mem) != TEST_VAL, "validate TEST_VAL"); + + rc = xpmem_remove(segid); + OKNG(rc == -1, "xpmem_remove"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_004.c b/test/issues/1259/XTP_004.c new file mode 100644 index 00000000..a614b443 --- /dev/null +++ b/test/issues/1259/XTP_004.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +#define BUFF_SIZE 1024 + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + key_t key = ftok(argv[0], 0); + int shmid; + + printf("*** %s start ***\n", basename(argv[0])); + + shmid = shmget(key, SZ_MEM, IPC_CREAT | 0660); + CHKANDJUMP(shmid == -1, "shmget"); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + void *shm = shmat(shmid, NULL, 0); + + CHKANDJUMP(shm == (void *)-1, "shmat in child"); + + while ((segid = *(xpmem_segid_t *)shm) == 0) { + }; + + rc = shmdt(shm); + CHKANDJUMP(rc == -1, "shmdt"); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init in child"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid == -1, "xpmem_get in child"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach == (void *)-1, "xpmem_attach in child"); + + *((unsigned long *)attach) = TEST_VAL; + + rc = xpmem_detach(attach); + OKNG(rc == -1, "xpmem_detach in child"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + void *shm = shmat(shmid, NULL, 0); + struct shmid_ds buf; + + CHKANDJUMP(shm == (void *)-1, "shmat in parent"); + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, + (void *)0666); + OKNG(segid == -1, "xpmem_make"); + + *(xpmem_segid_t *)shm = segid; + + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + + OKNG(*((unsigned long *)mem) != TEST_VAL, "validate TEST_VAL"); + + rc = shmctl(shmid, IPC_RMID, &buf); + CHKANDJUMP(rc == -1, "shmctl"); + + rc = shmdt(shm); + CHKANDJUMP(rc == -1, "shmdt"); + + rc = xpmem_remove(segid); + OKNG(rc == -1, "xpmem_remove"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_005.c b/test/issues/1259/XTP_005.c new file mode 100644 index 00000000..e282c4b8 --- /dev/null +++ b/test/issues/1259/XTP_005.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid == -1, "xpmem_make"); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid == -1, "xpmem_get in child"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach == (void *)-1, "xpmem_attach in child"); + + *((unsigned long *)attach) = TEST_VAL; + + fflush(0); + _exit(0); + } else { + /* Parent process */ + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + + OKNG(*((unsigned long *)mem) != TEST_VAL, "validate TEST_VAL"); + + rc = xpmem_remove(segid); + OKNG(rc == -1, "xpmem_remove"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_006.c b/test/issues/1259/XTP_006.c new file mode 100644 index 00000000..454da321 --- /dev/null +++ b/test/issues/1259/XTP_006.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid == -1, "xpmem_make"); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + sleep(1); /* wait for parent process exit */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, + "xpmem_get in child failed (parent process exited already"); + fflush(0); + + } else { + /* Parent process */ + _exit(0); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_007.c b/test/issues/1259/XTP_007.c new file mode 100644 index 00000000..52c52cf2 --- /dev/null +++ b/test/issues/1259/XTP_007.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +#define BAD_ADDRESS ((void *)-1) + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(BAD_ADDRESS, SZ_MEM, XPMEM_PERMIT_MODE, + (void *)0666); + OKNG(segid != -1, "xpmem_make failed (invalid address)"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + CHKANDJUMP(segid == -1, "xpmem_make"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid == -1, "xpmem_make succeed(do twice to same address)"); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + CHKANDJUMP(apid == -1, "xpmem_get in child"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + CHKANDJUMP(attach == (void *)-1, "xpmem_attach in child"); + + *((unsigned long *)attach) = TEST_VAL; + + rc = xpmem_detach(attach); + CHKANDJUMP(rc == -1, "xpmem_detach in child"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + + CHKANDJUMP(*((unsigned long *)mem) != TEST_VAL, + "validate TEST_VAL"); + + rc = xpmem_remove(segid); + CHKANDJUMP(rc == -1, "xpmem_remove"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_008.c b/test/issues/1259/XTP_008.c new file mode 100644 index 00000000..4d4c82df --- /dev/null +++ b/test/issues/1259/XTP_008.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +#define BAD_SEGID -1 + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + CHKANDJUMP(segid == -1, "xpmem_make"); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(BAD_SEGID, XPMEM_RDWR, XPMEM_PERMIT_MODE, + NULL); + OKNG(apid != -1, "xpmem_get in child failed (invalid segid)"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + CHKANDJUMP(apid == -1, "xpmem_get in child"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid == -1, "xpmem_get in child (do twice to same segid"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + CHKANDJUMP(attach == (void *)-1, "xpmem_attach in child"); + + *((unsigned long *)attach) = TEST_VAL; + + rc = xpmem_detach(attach); + CHKANDJUMP(rc == -1, "xpmem_detach in child"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + + CHKANDJUMP(*((unsigned long *)mem) != TEST_VAL, + "validate TEST_VAL"); + + rc = xpmem_remove(segid); + CHKANDJUMP(rc == -1, "xpmem_remove"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_009.c b/test/issues/1259/XTP_009.c new file mode 100644 index 00000000..a5216a0a --- /dev/null +++ b/test/issues/1259/XTP_009.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + CHKANDJUMP(segid == -1, "xpmem_make"); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + CHKANDJUMP(apid == -1, "xpmem_get in child"); + + addr.apid = -1; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach != (void *)-1, + "xpmem_attach in childi failed (invalid apid)"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + CHKANDJUMP(attach == (void *)-1, "xpmem_attach in child"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach == (void *)-1, + "xpmem_attach in child succeed (do twice to same apid)"); + + *((unsigned long *)attach) = TEST_VAL; + + rc = xpmem_detach(attach); + CHKANDJUMP(rc == -1, "xpmem_detach in child"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + + CHKANDJUMP(*((unsigned long *)mem) != TEST_VAL, + "validate TEST_VAL"); + + rc = xpmem_remove(segid); + CHKANDJUMP(rc == -1, "xpmem_remove"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_010.c b/test/issues/1259/XTP_010.c new file mode 100644 index 00000000..5f20ddaa --- /dev/null +++ b/test/issues/1259/XTP_010.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +#define BAD_ADDRESS ((void *) -1) + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + CHKANDJUMP(segid == -1, "xpmem_make"); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + CHKANDJUMP(apid == -1, "xpmem_get in child"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + CHKANDJUMP(attach == (void *)-1, "xpmem_attach in child"); + + *((unsigned long *)attach) = TEST_VAL; + + rc = xpmem_detach(BAD_ADDRESS); + OKNG(rc == -1, + "xpmem_detach in child succeed (invalid address)"); + + rc = xpmem_detach(attach); + CHKANDJUMP(rc == -1, "xpmem_detach in child"); + + rc = xpmem_detach(attach); + OKNG(rc == -1, + "xpmem_detach in child succeed (do twice to same address)"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + + CHKANDJUMP(*((unsigned long *)mem) != TEST_VAL, + "validate TEST_VAL"); + + rc = xpmem_remove(segid); + CHKANDJUMP(rc == -1, "xpmem_remove"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/XTP_011.c b/test/issues/1259/XTP_011.c new file mode 100644 index 00000000..995173d3 --- /dev/null +++ b/test/issues/1259/XTP_011.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util2.h" + +#define BAD_SEGID -1 + +int main(int argc, char **argv) +{ + void *mem, *attach; + int rc = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + CHKANDJUMP(mem == NULL, "mmap"); + memset(mem, 0, SZ_MEM); + + rc = xpmem_init(); + CHKANDJUMP(rc != 0, "xpmem_init"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + CHKANDJUMP(segid == -1, "xpmem_make"); + + fflush(0); + pid = fork(); + CHKANDJUMP(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + CHKANDJUMP(apid == -1, "xpmem_get in child"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + CHKANDJUMP(attach == (void *)-1, "xpmem_attach in child"); + + *((unsigned long *)attach) = TEST_VAL; + + rc = xpmem_detach(attach); + CHKANDJUMP(rc == -1, "xpmem_detach in child"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + rc = waitpid(pid, &status, 0); + CHKANDJUMP(rc == -1, "waitpid failed\n"); + + CHKANDJUMP(*((unsigned long *)mem) != TEST_VAL, + "validate TEST_VAL"); + + rc = xpmem_remove(BAD_SEGID); + OKNG(rc != -1, "xpmem_remove failed (invalid segid)"); + + rc = xpmem_remove(segid); + CHKANDJUMP(rc == -1, "xpmem_remove"); + + rc = xpmem_remove(segid); + OKNG(rc != -1, "xpmem_remove failed (do twice to same segid)"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +fn_fail: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1259/aarch64_config b/test/issues/1259/aarch64_config new file mode 100644 index 00000000..84f3a03d --- /dev/null +++ b/test/issues/1259/aarch64_config @@ -0,0 +1,2 @@ +PGSHIFT_LIST=(21 29 34) +SMALL_PGSIZE=65536 diff --git a/test/issues/1259/aarch64_result.log b/test/issues/1259/aarch64_result.log index adbca9a7..7163515d 100644 --- a/test/issues/1259/aarch64_result.log +++ b/test/issues/1259/aarch64_result.log @@ -1,5 +1,9 @@ *** C1259T01 start ******************************* +<<<<<<< HEAD ** xpmem_attach to Huge mapped memory range +======= +** xpem_attach to Huge mapped memory range +>>>>>>> 5dfbb27... xpmem: Support large page attachment ** end of range is aligned with Large page size pageshift: 21 ** [ OK ] seg_addr (100000400000) is allocated until xpmem_attach @@ -13,7 +17,11 @@ pageshift: 34 *** C1259T01: PASSED *** C1259T02 start ******************************* +<<<<<<< HEAD ** xpmem_attach to Huge mapped memory range +======= +** xpem_attach to Huge mapped memory range +>>>>>>> 5dfbb27... xpmem: Support large page attachment ** end of range is NOT aligned with Large page size pageshift: 21 ** [ OK ] seg_addr (100000400000) is allocated until xpmem_attach @@ -27,15 +35,25 @@ pageshift: 34 *** C1259T02: PASSED *** C1259T03 start ******************************* +<<<<<<< HEAD ** xpmem_attach to small mapped memory range +======= +** xpem_attach to small mapped memory range +>>>>>>> 5dfbb27... xpmem: Support large page attachment pageshift: small page ** [ OK ] xpmem_addr (100000210000) is allocated using small pages *** C1259T03: PASSED *** C1259T04 start ******************************* +<<<<<<< HEAD ** xpmem_attach to multi pagesize range pageshift: 21 ** [ OK ] xpmem_addr (100000600000) is allocated using large pages +======= +** xpem_attach to multi pagesize range +pageshift: 21 +** [ OK ] xpmem_addr (100000400000) is allocated using large pages +>>>>>>> 5dfbb27... xpmem: Support large page attachment *** C1259T04: PASSED *** C1259T05 start ******************************* @@ -43,12 +61,21 @@ pageshift: 21 XPMEM version = 26003 ==== test_base STARTS ==== +<<<<<<< HEAD xpmem_proc1: mypid = 38514 xpmem_proc1: sharing 262144 bytes xpmem_proc1: segid = 200009672 at 0x100000210000 xpmem_proc2: mypid = 38711 xpmem_proc2: segid = 200009672 +======= +xpmem_proc1: mypid = 10105 +xpmem_proc1: sharing 262144 bytes +xpmem_proc1: segid = 200002779 at 0x100000210000 + +xpmem_proc2: mypid = 10303 +xpmem_proc2: segid = 200002779 +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: attached at 0x100000210000 xpmem_proc2: adding 1 to all elems @@ -56,12 +83,22 @@ xpmem_proc1: verifying data...done ==== test_base PASSED ==== ==== test_two_attach STARTS ==== +<<<<<<< HEAD xpmem_proc1: mypid = 39028 xpmem_proc1: sharing 262144 bytes xpmem_proc1: segid = 200009874 at 0x100000210000 xpmem_proc2: mypid = 39233 xpmem_proc2: segid = 200009874 +======= +xpmem_proc1: mypid = 10528 +xpmem_proc1: sharing 262144 bytes +xpmem_proc1: segid = 200002920 at 0x100000210000 + +xpmem_proc2: line 228: 11049 Segmentation fault rm -f "$progdir/$file" +xpmem_proc2: mypid = 10733 +xpmem_proc2: segid = 200002920 +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: attached at 0x100000210000 xpmem_proc2: attached at 0x100000250000 xpmem_proc2: adding 1 to all elems using 0x100000210000 @@ -71,6 +108,7 @@ xpmem_proc1: verifying data...done ==== test_two_attach PASSED ==== ==== test_two_shares STARTS ==== +<<<<<<< HEAD xpmem_proc1: mypid = 39429 xpmem_proc1: sharing 2 segments, 262144 bytes each xpmem_proc1: segid[0] = 200009a05 at 0x100000210000 @@ -79,6 +117,16 @@ xpmem_proc1: segid[1] = 400009a05 at 0x100000250000 xpmem_proc2: mypid = 39625 xpmem_proc2: segid[0] = 200009a05 xpmem_proc2: segid[1] = 400009a05 +======= +xpmem_proc1: mypid = 11064 +xpmem_proc1: sharing 2 segments, 262144 bytes each +xpmem_proc1: segid[0] = 200002b38 at 0x100000210000 +xpmem_proc1: segid[1] = 400002b38 at 0x100000250000 + +xpmem_proc2: mypid = 11261 +xpmem_proc2: segid[0] = 200002b38 +xpmem_proc2: segid[1] = 400002b38 +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: data[0] attached at 0x100000210000 xpmem_proc2: data[1] attached at 0x100000250000 xpmem_proc2: adding 1 to all elems using 0x100000210000 @@ -88,12 +136,21 @@ xpmem_proc1: verifying data...done ==== test_two_shares PASSED ==== ==== test_fork STARTS ==== +<<<<<<< HEAD xpmem_proc1: mypid = 39831 xpmem_proc1: sharing 262144 bytes xpmem_proc1: segid = 200009b97 at 0x100000210000 xpmem_proc2: mypid = 40027 xpmem_proc2: segid = 200009b97 +======= +xpmem_proc1: mypid = 11598 +xpmem_proc1: sharing 262144 bytes +xpmem_proc1: segid = 200002d4e at 0x100000210000 + +xpmem_proc2: mypid = 11803 +xpmem_proc2: segid = 200002d4e +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: attached at 0x100000220000 xpmem_proc2: reading to pin pages xpmem_proc2: waiting for COW... @@ -101,7 +158,11 @@ xpmem_proc2: waiting for COW... xpmem_proc1: forking a child xpmem_proc1: adding 1 to all elems to induce COW +<<<<<<< HEAD xpmem_child: hello from pid 40224 +======= +xpmem_child: hello from pid 12004 +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc1: give control back to xpmem_proc2 diff --git a/test/issues/1259/huge_page_xpmem.c b/test/issues/1259/huge_page_xpmem.c new file mode 100644 index 00000000..19d467e8 --- /dev/null +++ b/test/issues/1259/huge_page_xpmem.c @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" + +#define DEBUG + +#define SHM_SIZE (1UL << 12) + +#define MAP_HUGE_SHIFT 26 +#define KEYWORD 0x12345678UL + +void usage(void) +{ + printf("Usage: huge_page_map: \n"); + printf("\tpgshift : pageshift of map area (Using MAP_HUGETLB)\n"); + printf("\t -1 means using small pagesize\n"); + printf("\tpgnum : number of page of map area\n"); + printf("\tpgoffset: offset of last page\n"); +} + + +void *mmap_flag(size_t mapsize, int page_shift) +{ + char *addr_mmap; + int flags = MAP_ANONYMOUS | MAP_PRIVATE; + + if (page_shift >= 0) { + /* mean use MAP_HUGETLB */ + flags |= MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT); + } + + addr_mmap = mmap(0, mapsize, + PROT_READ | PROT_WRITE, + flags, -1, 0); + + return addr_mmap; +} + +int main(int argc, char **argv) +{ + void *mem; + int ret = 0; + pid_t pid; + int status; + key_t key = ftok(argv[0], 0); + void *shm; + int shmid; + xpmem_segid_t segid; + struct shmid_ds shmctl_buf; + int pgshift, pgnum; + size_t pgsize, map_size, pgoffset; + + if (argc < 4) { + printf("Err: Too few arguments\n"); + usage(); + return -1; + } + + pgshift = atoi(argv[1]); + pgnum = atoi(argv[2]); + pgoffset = atol(argv[3]); + if (pgshift > 0) { + pgsize = (1UL << pgshift); + } else { + pgsize = getpagesize(); + } + + if (pgoffset > 0) { + map_size = (pgsize * (pgnum - 1)) + pgoffset; + } else { + map_size = pgsize * pgnum; + } + + shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0660); + CHKANDJUMP(shmid == -1, EXIT_FAILURE, "shmget failed: %s\n", + strerror(errno)); + + printf("EXPECT_PAGE_SIZE: 0x%lx\n", pgsize); + fflush(stdout); + + pid = fork(); + CHKANDJUMP(pid == -1, EXIT_FAILURE, "fork failed\n"); + if (pid == 0) { + xpmem_apid_t apid; + struct xpmem_addr addr; + void *attach; + + shm = shmat(shmid, NULL, 0); + CHKANDJUMP(shm == (void *)-1, EXIT_FAILURE, + "shmat failed: %s\n", strerror(errno)); + + while ((segid = *(xpmem_segid_t *)shm) == 0) { + }; + + ret = shmdt(shm); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "shmdt failed\n"); + + apid = xpmem_get(segid, XPMEM_RDWR, + XPMEM_PERMIT_MODE, NULL); + CHKANDJUMP(apid == -1, EXIT_FAILURE, "xpmem_get failed: %s\n", + strerror(errno)); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, map_size, NULL); + + CHKANDJUMP(attach == (void *)-1, EXIT_FAILURE, + "xpmem_attach failed: %s\n", strerror(errno)); + + printf("child: xpmem_attachment_addr: %lx\n", + attach); + + *((unsigned long *)attach) = KEYWORD; + if (pgnum > 1 && pgshift > 0) { + *((unsigned long *)(attach + + (1UL << pgshift))) = KEYWORD; + } + *((unsigned long *)(attach + map_size + - sizeof(unsigned long *))) = KEYWORD; + + ret = xpmem_detach(attach); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "xpmem_detach failed\n"); + + exit(0); + } else { + mem = mmap_flag(map_size, pgshift); + CHKANDJUMP(mem == MAP_FAILED, EXIT_FAILURE, "mmap failed\n"); + printf("parent: anonymous_map_addr: %lx - %lx\n", + mem, mem + map_size); + + shm = shmat(shmid, NULL, 0); + + CHKANDJUMP(shm == (void *)-1, EXIT_FAILURE, + "shmat failed: %s\n", strerror(errno)); + + segid = xpmem_make(mem, map_size, XPMEM_PERMIT_MODE, + (void *)0666); + CHKANDJUMP(segid == -1, EXIT_FAILURE, + "xpmem_ioctl failed: %s\n", strerror(errno)); + + *(xpmem_segid_t *)shm = segid; + + ret = waitpid(pid, &status, 0); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "waitpid failed\n"); + + NG(*(unsigned long *)mem == KEYWORD, + "HEAD of xpmem area is INVALID. isn't shared?\n"); + if (pgnum > 1 && pgshift > 0) { + NG(*((unsigned long *)(mem + + (1UL << pgshift))) == KEYWORD, + "MIDDLE of xpmem area is INVALID. isn't shared?\n"); + } + NG(*((unsigned long *)(mem + map_size + - sizeof(unsigned long *))) == KEYWORD, + "TAIL of xpmem area is INVALID. isn't shared?\n"); + printf("xpmem area is shared: OK\n"); + + ret = shmctl(shmid, IPC_RMID, &shmctl_buf); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "shmctl failed\n"); + + ret = shmdt(shm); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "shmdt failed\n"); + + ret = xpmem_remove(segid); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "xpmem_remove failed\n"); + } + + ret = 0; + out: + return ret; +} diff --git a/test/issues/1259/large_page.patch b/test/issues/1259/large_page.patch new file mode 100644 index 00000000..f3df2f16 --- /dev/null +++ b/test/issues/1259/large_page.patch @@ -0,0 +1,117 @@ +diff --git arch/arm64/kernel/memory.c arch/arm64/kernel/memory.c +index a84bc21..f329fcf 100644 +--- arch/arm64/kernel/memory.c ++++ arch/arm64/kernel/memory.c +@@ -2701,6 +2701,16 @@ int set_range_l1(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start, + ptl1_set(ptep, pte); + + error = 0; ++ ++ if (args->attr[0] & PTE_CONT && ++ __page_offset(base, PTL1_CONT_SIZE) == 0) { ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx , phys: %lx\n", ++ __func__, base, PTL1_CONT_SIZE, phys); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL1_CONT_SIZE); ++ } ++ + // call memory_stat_rss_add() here because pgshift is resolved here + if (!(args->attr[0] & PTE_CONT)) { + if (rusage_memory_stat_add(args->range, phys, +@@ -2810,6 +2820,23 @@ retry: + level); + + error = 0; ++ ++ if (args->attr[level-1] & PTE_CONT) { ++ if (__page_offset(base, tbl.cont_pgsize) == 0) { ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx , phys: %lx\n", ++ __func__, base, tbl.cont_pgsize, phys); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, tbl.cont_pgsize); ++ } ++ } else { ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx , phys: %lx\n", ++ __func__, base, tbl.pgsize, phys); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, tbl.pgsize); ++ } ++ + dkprintf("set_range_middle(%lx,%lx,%lx,%d):" + "large page. %d %lx\n", + base, start, end, level, error, *ptep); +diff --git arch/x86_64/kernel/memory.c arch/x86_64/kernel/memory.c +index 6b34036..4ca3a1a 100644 +--- arch/x86_64/kernel/memory.c ++++ arch/x86_64/kernel/memory.c +@@ -1932,6 +1932,13 @@ retry: + dkprintf("set_range_l2(%lx,%lx,%lx):" + "2MiB page. %d %lx\n", + base, start, end, error, *ptep); ++ ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL2_SIZE); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL2_SIZE); ++ + // Call memory_stat_rss_add() here because pgshift is resolved here + if (rusage_memory_stat_add(args->range, phys, PTL2_SIZE, PTL2_SIZE)) { + dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL2_SIZE, PTL2_SIZE); +@@ -2021,6 +2028,12 @@ retry: + "1GiB page. %d %lx\n", + base, start, end, error, *ptep); + ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL3_SIZE); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL3_SIZE); ++ + // Call memory_stat_rss_add() here because pgshift is resolved here + if (rusage_memory_stat_add(args->range, phys, PTL3_SIZE, PTL3_SIZE)) { + dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL3_SIZE, PTL3_SIZE); +diff --git kernel/process.c kernel/process.c +index 1624726..d867b4d 100644 +--- kernel/process.c ++++ kernel/process.c +@@ -2138,6 +2138,12 @@ retry: + } + + dkprintf("%s: attr=%x\n", __FUNCTION__, attr); ++ ++ if (pgsize > PAGE_SIZE) { ++ kprintf("large_page_allocation, addr: %016lx, size: %d, phys: %lx\n", ++ pgaddr, pgsize, phys); ++ } ++ + error = ihk_mc_pt_set_pte(vm->address_space->page_table, ptep, + pgsize, phys, attr); + if (error) { +diff --git kernel/xpmem.c kernel/xpmem.c +index 9fedf26..a0a7990 100644 +--- kernel/xpmem.c ++++ kernel/xpmem.c +@@ -490,6 +490,7 @@ static int xpmem_make( + *segid_p = segid; + + XPMEM_DEBUG("return: ret=%d, segid=0x%lx", 0, *segid_p); ++ kprintf("%s: DONE\n", __func__); + + return 0; + } +@@ -1886,6 +1887,11 @@ static int _xpmem_fault_process_memory_range( + goto out; + } + ++ if (att_pgsize == PAGE_SIZE) { ++ kprintf("xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ vaddr, att_pgsize); ++ } ++ + XPMEM_DEBUG("att_pgaddr: %lx, att_pgsize: %lx, " + "seg_vaddr: %lx, seg_pgsize: %lx, seg_phys: %lx\n", + att_pgaddr, att_pgsize, seg_vaddr, diff --git a/test/issues/1259/mc_run.sh b/test/issues/1259/mc_run.sh new file mode 100755 index 00000000..ed530f4e --- /dev/null +++ b/test/issues/1259/mc_run.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +test -e /tmp/xpmem.share && rm -f /tmp/xpmem.share +test -e /tmp/xpmem.lock && rm -f /tmp/xpmem.lock + +# create TMP_SHARE_SIZE bytes defined in xpmem_test.h +for i in `seq 0 31` ; do + echo -n 0 >> /tmp/xpmem.share +done +echo 0 > /tmp/xpmem.lock + +# Run the main test app +${MCEXEC} $PWD/xpmem_master +exit 0 + diff --git a/test/issues/1259/multi_vmr_xpmem.c b/test/issues/1259/multi_vmr_xpmem.c new file mode 100644 index 00000000..5f7d6220 --- /dev/null +++ b/test/issues/1259/multi_vmr_xpmem.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" + +#define DEBUG + +#define SHM_SIZE (1UL << 12) + +#define MAP_HUGE_SHIFT 26 +#define KEYWORD 0x12345678UL + +void usage(void) +{ + printf("Usage: multi_vmr_xpmem: \n"); + printf("\tpgshift : pageshift of map area (Using MAP_HUGETLB)\n"); + printf("\t -1 means using small pagesize\n"); + printf("\tpgnum : number of page of map area\n"); +} + + +void *mmap_flag(size_t mapsize, int page_shift) +{ + char *addr_mmap; + int flags = MAP_ANONYMOUS | MAP_PRIVATE; + + if (page_shift >= 0) { + /* mean use MAP_HUGETLB */ + flags |= MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT); + } + + addr_mmap = mmap(0, mapsize * 2, + PROT_READ | PROT_WRITE, + flags, -1, 0); + + /* Make sure that area before addr_map is available to + * MAP_FIXED map + */ + return addr_mmap + mapsize; +} + +int main(int argc, char **argv) +{ + void *mem, *mem_1, *mem_2; + int ret = 0; + pid_t pid; + int status; + key_t key = ftok(argv[0], 10); + void *shm; + int shmid; + xpmem_segid_t segid; + struct shmid_ds shmctl_buf; + int pgshift, pgnum; + size_t extr_size, pgsize, map_size; + + if (argc < 3) { + printf("Err: Too few arguments\n"); + usage(); + return -1; + } + + pgshift = atoi(argv[1]); + pgnum = atoi(argv[2]); + extr_size = getpagesize() * 3; + if (pgshift > 0) { + pgsize = (1UL << pgshift); + } else { + pgsize = getpagesize(); + } + + map_size = pgsize * pgnum; + + shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0660); + CHKANDJUMP(shmid == -1, EXIT_FAILURE, "shmget failed: %s\n", + strerror(errno)); + + printf("EXPECT_PAGE_SIZE: 0x%lx\n", pgsize); + fflush(stdout); + + pid = fork(); + CHKANDJUMP(pid == -1, EXIT_FAILURE, "fork failed\n"); + if (pid == 0) { + xpmem_apid_t apid; + struct xpmem_addr addr; + void *attach; + + shm = shmat(shmid, NULL, 0); + CHKANDJUMP(shm == (void *)-1, EXIT_FAILURE, + "shmat failed: %s\n", strerror(errno)); + + while ((segid = *(xpmem_segid_t *)shm) == 0) { + }; + ret = shmdt(shm); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "shmdt failed\n"); + + apid = xpmem_get(segid, XPMEM_RDWR, + XPMEM_PERMIT_MODE, NULL); + CHKANDJUMP(apid == -1, EXIT_FAILURE, "xpmem_get failed: %s\n", + strerror(errno)); + + addr.apid = apid; + addr.offset = 0; + printf("child: attaching...\n"); + attach = xpmem_attach(addr, map_size + (extr_size * 2), NULL); + + CHKANDJUMP(attach == (void *)-1, EXIT_FAILURE, + "xpmem_attach failed: %s\n", strerror(errno)); + + printf("child: xpmem_attachment_addr: %lx - %lx\n", + attach, attach + map_size + (extr_size * 2)); + printf("child: xpmem_large: %lx\n", attach + extr_size); + + *((unsigned long *)attach) = KEYWORD; + *((unsigned long *)(attach + extr_size)) = KEYWORD; + *((unsigned long *)(attach + extr_size * 2 + map_size + - sizeof(unsigned long *))) = KEYWORD; + + ret = xpmem_detach(attach); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "xpmem_detach failed\n"); + + exit(0); + } else { + mem = mmap_flag(map_size, pgshift); + CHKANDJUMP(mem == MAP_FAILED, EXIT_FAILURE, "mmap failed\n"); + mem_1 = mmap(mem - extr_size, extr_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, + -1, 0); + mem_2 = mmap(mem + map_size, extr_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, + -1, 0); + if ((mem_1 + extr_size != mem) || (mem_2 != mem + map_size)) { + printf("vm_range is NOT contignuous!!\n"); + exit(1); + } + printf("parent: anonymous_map_addr: %lx - %lx\n", + mem_1, mem_2 + extr_size); + + shm = shmat(shmid, NULL, 0); + + CHKANDJUMP(shm == (void *)-1, EXIT_FAILURE, + "shmat failed: %s\n", strerror(errno)); + + printf("parent: making...\n"); + segid = xpmem_make(mem_1, map_size + (extr_size * 2), + XPMEM_PERMIT_MODE, (void *)0666); + CHKANDJUMP(segid == -1, EXIT_FAILURE, + "xpmem_ioctl failed: %s\n", strerror(errno)); + + *(xpmem_segid_t *)shm = segid; + + printf("parent: waiting...\n"); + ret = waitpid(pid, &status, 0); +printf("child exited\n"); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "waitpid failed\n"); + + NG(*(unsigned long *)mem_1 == KEYWORD, + "HEAD of xpmem area is INVALID. isn't shared?\n"); + NG(*(unsigned long *)mem == KEYWORD, + "MIDDLE of xpmem area is INVALID. isn't shared?\n"); + NG(*((unsigned long *)(mem_2 + extr_size + - sizeof(unsigned long *))) == KEYWORD, + "TAIL of xpmem area is INVALID. isn't shared?\n"); + printf("xpmem area is shared: OK\n"); + + ret = shmctl(shmid, IPC_RMID, &shmctl_buf); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "shmctl failed\n"); + + ret = shmdt(shm); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "shmdt failed\n"); + + ret = xpmem_remove(segid); + CHKANDJUMP(ret == -1, EXIT_FAILURE, "xpmem_remove failed\n"); + } + + ret = 0; + out: + return ret; +} diff --git a/test/issues/1259/util.h b/test/issues/1259/util.h new file mode 100644 index 00000000..d18cd7d6 --- /dev/null +++ b/test/issues/1259/util.h @@ -0,0 +1,28 @@ +#ifndef __UTIL_H_INCLUDED__ +#define __UTIL_H_INCLUDED__ + +#define CHKANDJUMP(cond, err, ...) do { \ + if (cond) { \ + printf(__VA_ARGS__); \ + ret = err; \ + goto out; \ + } \ +} while (0) + +#define _OKNG(verb, jump, cond, fmt, args...) do { \ + if (cond) { \ + if (verb) \ + printf("[ OK ] " fmt, ##args); \ + } else { \ + printf("[ NG ] " fmt, ##args); \ + if (jump) \ + goto out; \ + } \ +} while (0) + +#define OKNG(args...) _OKNG(1, 1, ##args) +#define NG(args...) _OKNG(0, 1, ##args) +#define OKNGNOJUMP(args...) _OKNG(1, 0, ##args) + +#endif + diff --git a/test/issues/1259/util2.h b/test/issues/1259/util2.h new file mode 100644 index 00000000..3fe5b718 --- /dev/null +++ b/test/issues/1259/util2.h @@ -0,0 +1,31 @@ +#define CHKANDJUMP(cond, ...) do { \ + if (cond) { \ + fprintf(stderr, " [NG] "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " failed\n"); \ + goto fn_fail; \ + } \ +} while (0) + +#define OKNG(cond, ...) do { \ + if (cond) { \ + CHKANDJUMP(cond, __VA_ARGS__); \ + } else { \ + fprintf(stdout, " [OK] "); \ + fprintf(stdout, __VA_ARGS__); \ + fprintf(stdout, "\n"); \ + } \ +} while (0) + + +#ifdef __aarch64__ +#define LARGE_PAGE_SHIFT 21 +#elif defined(__x86_64__) +#define LARGE_PAGE_SHIFT 21 +#else +#error "Non-compliant architecture." +#endif + +#define MAP_HUGE_SHIFT 26 +#define SZ_MEM (2 * (1ULL << LARGE_PAGE_SHIFT)) +#define TEST_VAL 0x1129 diff --git a/test/issues/1259/x86_64_config b/test/issues/1259/x86_64_config new file mode 100644 index 00000000..ff8734b7 --- /dev/null +++ b/test/issues/1259/x86_64_config @@ -0,0 +1,2 @@ +PGSHIFT_LIST=(21 30) +SMALL_PGSIZE=4096 diff --git a/test/issues/1259/x86_64_result.log b/test/issues/1259/x86_64_result.log index 2308bd3d..c093e2d9 100644 --- a/test/issues/1259/x86_64_result.log +++ b/test/issues/1259/x86_64_result.log @@ -1,5 +1,9 @@ *** C1259T01 start ******************************* +<<<<<<< HEAD ** xpmem_attach to Huge mapped memory range +======= +** xpem_attach to Huge mapped memory range +>>>>>>> 5dfbb27... xpmem: Support large page attachment ** end of range is aligned with Large page size pageshift: 21 ** [ OK ] seg_addr (2aaaab000000) is allocated until xpmem_attach @@ -10,7 +14,11 @@ pageshift: 30 *** C1259T01: PASSED *** C1259T02 start ******************************* +<<<<<<< HEAD ** xpmem_attach to Huge mapped memory range +======= +** xpem_attach to Huge mapped memory range +>>>>>>> 5dfbb27... xpmem: Support large page attachment ** end of range is NOT aligned with Large page size pageshift: 21 ** [ OK ] seg_addr (2aaaab000000) is allocated until xpmem_attach @@ -21,15 +29,25 @@ pageshift: 30 *** C1259T02: PASSED *** C1259T03 start ******************************* +<<<<<<< HEAD ** xpmem_attach to small mapped memory range +======= +** xpem_attach to small mapped memory range +>>>>>>> 5dfbb27... xpmem: Support large page attachment pageshift: small page ** [ OK ] xpmem_addr (2aaaaafee000) is allocated using small pages *** C1259T03: PASSED *** C1259T04 start ******************************* +<<<<<<< HEAD ** xpmem_attach to multi pagesize range pageshift: 21 ** [ OK ] xpmem_addr (2aaaab200000) is allocated using large pages +======= +** xpem_attach to multi pagesize range +pageshift: 21 +** [ OK ] xpmem_addr (2aaaab000000) is allocated using large pages +>>>>>>> 5dfbb27... xpmem: Support large page attachment *** C1259T04: PASSED *** C1259T05 start ******************************* @@ -37,12 +55,21 @@ pageshift: 21 XPMEM version = 26003 ==== test_base STARTS ==== +<<<<<<< HEAD xpmem_proc1: mypid = 20070 xpmem_proc1: sharing 16384 bytes xpmem_proc1: segid = 200004e66 at 0x2aaaaafee000 xpmem_proc2: mypid = 20490 xpmem_proc2: segid = 200004e66 +======= +xpmem_proc1: mypid = 13702 +xpmem_proc1: sharing 16384 bytes +xpmem_proc1: segid = 200003586 at 0x2aaaaafee000 + +xpmem_proc2: mypid = 14123 +xpmem_proc2: segid = 200003586 +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: attached at 0x2aaaaafee000 xpmem_proc2: adding 1 to all elems @@ -50,12 +77,21 @@ xpmem_proc1: verifying data...done ==== test_base PASSED ==== ==== test_two_attach STARTS ==== +<<<<<<< HEAD xpmem_proc1: mypid = 20913 xpmem_proc1: sharing 16384 bytes xpmem_proc1: segid = 2000051b1 at 0x2aaaaafee000 xpmem_proc2: mypid = 21336 xpmem_proc2: segid = 2000051b1 +======= +xpmem_proc1: mypid = 14543 +xpmem_proc1: sharing 16384 bytes +xpmem_proc1: segid = 2000038cf at 0x2aaaaafee000 + +xpmem_proc2: mypid = 14963 +xpmem_proc2: segid = 2000038cf +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: attached at 0x2aaaaafee000 xpmem_proc2: attached at 0x2aaaaaff2000 xpmem_proc2: adding 1 to all elems using 0x2aaaaafee000 @@ -65,6 +101,7 @@ xpmem_proc1: verifying data...done ==== test_two_attach PASSED ==== ==== test_two_shares STARTS ==== +<<<<<<< HEAD xpmem_proc1: mypid = 21758 xpmem_proc1: sharing 2 segments, 16384 bytes each xpmem_proc1: segid[0] = 2000054fe at 0x2aaaaafee000 @@ -73,6 +110,16 @@ xpmem_proc1: segid[1] = 4000054fe at 0x2aaaaaff2000 xpmem_proc2: mypid = 22179 xpmem_proc2: segid[0] = 2000054fe xpmem_proc2: segid[1] = 4000054fe +======= +xpmem_proc1: mypid = 15383 +xpmem_proc1: sharing 2 segments, 16384 bytes each +xpmem_proc1: segid[0] = 200003c17 at 0x2aaaaafee000 +xpmem_proc1: segid[1] = 400003c17 at 0x2aaaaaff2000 + +xpmem_proc2: mypid = 15807 +xpmem_proc2: segid[0] = 200003c17 +xpmem_proc2: segid[1] = 400003c17 +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: data[0] attached at 0x2aaaaafee000 xpmem_proc2: data[1] attached at 0x2aaaaaff2000 xpmem_proc2: adding 1 to all elems using 0x2aaaaafee000 @@ -82,23 +129,40 @@ xpmem_proc1: verifying data...done ==== test_two_shares PASSED ==== ==== test_fork STARTS ==== +<<<<<<< HEAD xpmem_proc1: mypid = 22599 xpmem_proc1: sharing 16384 bytes xpmem_proc1: segid = 200005847 at 0x2aaaaafee000 xpmem_proc2: mypid = 23022 xpmem_proc2: segid = 200005847 +======= +xpmem_proc1: mypid = 16227 +xpmem_proc1: sharing 16384 bytes +xpmem_proc1: segid = 200003f63 at 0x2aaaaafee000 + +xpmem_proc2: mypid = 16647 +xpmem_proc2: segid = 200003f63 +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: attached at 0x2aaaaafef000 xpmem_proc2: reading to pin pages xpmem_proc2: waiting for COW... xpmem_proc1: forking a child xpmem_proc1: adding 1 to all elems to induce COW +<<<<<<< HEAD xpmem_proc1: give control back to xpmem_proc2 xpmem_child: hello from pid 23443 +======= +xpmem_proc1: give control back to xpmem_proc2 + + +xpmem_child: hello from pid 17067 + +>>>>>>> 5dfbb27... xpmem: Support large page attachment xpmem_proc2: adding 1 to all elems xpmem_proc1: verifying data...done diff --git a/test/issues/1473/CMakeLists.txt b/test/issues/1473/CMakeLists.txt new file mode 100644 index 00000000..4d4c486b --- /dev/null +++ b/test/issues/1473/CMakeLists.txt @@ -0,0 +1,164 @@ +cmake_policy(SET CMP0005 NEW) + +# Options: -DWITH_XPMEM= +add_definitions(-DWITH_XPMEM=${WITH_XPMEM}) + +# Options: -DWITH_XPMEM= +add_definitions(-DWITH_XPMEM_BUILD=${WITH_XPMEM_BUILD}) + +# Options: -DWITH_MCK= +add_definitions(-DWITH_MCK=${WITH_MCK}) + +# Options: -DWITH_MCK_SRC= +add_definitions(-DWITH_MCK_SRC=${WITH_MCK_SRC}) + +# not used when integrated with autotest +# Options: -DWITH_MCK_BUILD= +add_definitions(-DWITH_MCK_BUILD=${WITH_MCK_BUILD}) + +# for autotest +if(NOT DEFINED CMAKE_INSTALL_PREFIX_SCRIPTS) + set(CMAKE_INSTALL_PREFIX_SCRIPTS ${CMAKE_INSTALL_PREFIX}/scripts) +endif() + +cmake_minimum_required(VERSION 2.0) + +project(xpmemtest C) + +# CPPFLAGS + +set(UNAME_R ${CMAKE_SYSTEM_VERSION} CACHE STRING "Kernel version to build against") +set(KERNEL_DIR "/lib/modules/${UNAME_R}/build" CACHE STRING "kernel build directory") +execute_process(COMMAND awk -F= "$1 == \"CONFIG_ARM64_64K_PAGES\" { print $2; exit; }" "${KERNEL_DIR}/.config" + OUTPUT_VARIABLE CONFIG_ARM64_64K_PAGES OUTPUT_STRIP_TRAILING_WHITESPACE) +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + if(CONFIG_ARM64_64K_PAGES STREQUAL "y") + set(PAGE_SIZE "65536") + else() + set(PAGE_SIZE "4096") + endif() +else() + set(PAGE_SIZE "4096") +endif() +message("PAGE_SIZE: ${PAGE_SIZE}") + +# CFLAGS +set(CFLAGS_WARNING "-Wall" "-Wextra" "-Wno-unused-parameter" "-Wno-sign-compare" "-Wno-unused-function" ${EXTRA_WARNINGS} CACHE STRING "Warning flags") +add_compile_options(-O2 -g ${CFLAGS_WARNING}) + +# -L, this must be done before adding dependants +link_directories("${WITH_XPMEM}/lib") + +# -Wl,--rpath=, this must be done before adding dependants +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +foreach(target IN ITEMS + xpmem_make01 + xpmem_attach01 + xpmem_attach02 + ) + + # Add target + add_executable(${target} ${target}.c) + + # -D + target_compile_definitions(${target} + PRIVATE -DPAGE_SIZE=${PAGE_SIZE} + ) + + # -I + target_include_directories(${target} + PRIVATE "${WITH_XPMEM}/include" + ) + + # -l + target_link_libraries(${target} + PRIVATE xpmem + ) + + # String replacement and install + configure_file(${target}.sh.in xpmem-${target} @ONLY) + + # Install + install(TARGETS ${target} DESTINATION bin) + install(PROGRAMS ${CMAKE_BINARY_DIR}/xpmem-${target} DESTINATION ${CMAKE_INSTALL_PREFIX_SCRIPTS}) +endforeach() + +foreach(target IN ITEMS + xpmem_attach03 + ) + # String replacement and install + configure_file(${target}.sh.in xpmem-${target} @ONLY) + + # Install + install(PROGRAMS ${CMAKE_BINARY_DIR}/xpmem-${target} DESTINATION ${CMAKE_INSTALL_PREFIX_SCRIPTS}) +endforeach() + +foreach(target IN ITEMS + util + ) + # String replacement and install + configure_file(${target}.sh.in ${target}.sh @ONLY) + + # Install + install(PROGRAMS ${CMAKE_BINARY_DIR}/${target}.sh DESTINATION bin) +endforeach() + +foreach(target IN ITEMS + huge_page_xpmem + multi_vmr_xpmem + XTP_001 + XTP_002 + XTP_003 + XTP_004 + XTP_005 + XTP_006 + XTP_007 + XTP_008 + XTP_009 + XTP_010 + XTP_011 + ) + + # Add target + add_executable(${target} ${target}.c) + + # -D + target_compile_definitions(${target} + PRIVATE -DPAGE_SIZE=${PAGE_SIZE} + ) + + # -I + target_include_directories(${target} + PRIVATE "${WITH_XPMEM}/include" + ) + + # -l + target_link_libraries(${target} + PRIVATE xpmem + ) + + # Install + install(TARGETS ${target} DESTINATION bin) +endforeach() + +foreach(target IN ITEMS + common.sh + ) + configure_file(${target}.in ${target} @ONLY) + install(PROGRAMS ${CMAKE_BINARY_DIR}/${target} DESTINATION bin) +endforeach() + +foreach(target IN ITEMS + aarch64.conf + ) + install(FILES ${target} DESTINATION etc) +endforeach() + +# patches +foreach(target IN ITEMS + large_page.patch + ihk_kmsg_size.patch + ) + install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/${target} DESTINATION bin) +endforeach() diff --git a/test/issues/1473/README b/test/issues/1473/README new file mode 100644 index 00000000..ec8d540e --- /dev/null +++ b/test/issues/1473/README @@ -0,0 +1,35 @@ +【Issue#1473 動作確認】 +縮退確認のため、1259のテストも合わせて行うことを勧める。 + +□ テスト内容 +xpmem_make01: + サイズ-1でxpmem_makeした際にpage-inしないことを確認する +xpmem_attach01: + s < lの関係にあるページサイズサイズs、lについて、ページサイズ + s、サイズlの物理連続領域をxpmem_makeして、当該領域を + xpmem_attachした際にページサイズがsになることを確認する +xpmem_attach02: + s < lの関係にあるページサイズサイズs, lについて、ページサイズl、 + サイズl * 3のマップのうち最初のページの最後のサイズs * 3の部分、 + 次のページの全体、最後のページの最初のサイズs * 3の部分を束ねて + xpmem_makeして、xpmem_attachした際にページサイズがs,s,s,l,s,s,s + になるか、またぞれぞれのマップが期待する物理ページを指しているか + 確認する + +□ 実行手順 +1. McKernelをビルドした際に生成されるmck_test_config.sample ファイルを + $HOME/.mck_test_configとしてコピーし、パスを編集する。 + mcreboot.shのオプションは、-e 'xpmem_remote_on_demand anon_on_demand' + をつけた場合とつけない場合の両方を試すこと。 + +2. 以下の手順でビルドと実行を行う +$ cd +$ patch -p0 < test/issues/1473/large_page.patch +$ (build mckernel) +$ cd /test/issues +$ mkdir build && cd build +$ cmake ../1473 -DWITH_MCK=/work/mcktest/work/mck -DWITH_MCK_SRC=/work/mcktest/work/src/mckernel -DWITH_MCK_BUILD=/work/mcktest/xpmem/mckernel/build -DWITH_XPMEM=/work/mcktest/xpmem/xpmem/install -DWITH_XPMEM_BUILD=/work/mcktest/xpmem/xpmem/xpmem -DCMAKE_INSTALL_PREFIX=/work/mcktest/xpmem/install -DCMAKE_INSTALL_PREFIX_SCRIPTS=/work/mcktest/data/scripts +$ make install +$ /scripts/xpmem-xpmem_make01 +$ /scripts/xpmem-xpmem_attach01 +$ /scripts/xpmem-xpmem_attach02 diff --git a/test/issues/1473/XTP_001.c b/test/issues/1473/XTP_001.c new file mode 100644 index 00000000..167ef0b6 --- /dev/null +++ b/test/issues/1473/XTP_001.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid != -1, "segid: %lx\n", (unsigned long)segid); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, "apid: %lx\n", (unsigned long)apid); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach != (void *)-1, "attach: %lx\n", (unsigned long)attach); + + ret = xpmem_detach(attach); + OKNG(ret != -1, "xpmem_detach\n"); + + ret = xpmem_remove(segid); + OKNG(ret != -1, "xpmem_remove\n"); + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_002.c b/test/issues/1473/XTP_002.c new file mode 100644 index 00000000..8ba35b42 --- /dev/null +++ b/test/issues/1473/XTP_002.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + INTERR(ret != 0, "xpmem_init in child\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, + (void *)0666); + OKNG(segid != -1, "child: xpmem_make\n"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, "child: xpmem_get\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach != (void *)-1, "xpmem_attach in child\n"); + + ret = xpmem_detach(attach); + OKNG(ret != -1, "xpmem_detach in child\n"); + + ret = xpmem_remove(segid); + OKNG(ret != -1, "xpmem_remove in child\n"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_003.c b/test/issues/1473/XTP_003.c new file mode 100644 index 00000000..a45e9ba0 --- /dev/null +++ b/test/issues/1473/XTP_003.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + INTERR(ret != 0, "xpmem_init failed\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid != -1, "xpmem_make failed\n"); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, "xpmem_get in child\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach != (void *)-1, "xpmem_attach in child\n"); + + *((unsigned long *)attach) = TEST_VAL; + + ret = xpmem_detach(attach); + OKNG(ret != -1, "xpmem_detach in child\n"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + OKNG(*((unsigned long *)mem) == TEST_VAL, + "TEST_VAL found\n"); + + ret = xpmem_remove(segid); + OKNG(ret != -1, "xpmem_remove\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_004.c b/test/issues/1473/XTP_004.c new file mode 100644 index 00000000..135f875f --- /dev/null +++ b/test/issues/1473/XTP_004.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +#define BUFF_SIZE 1024 + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + key_t key = ftok(argv[0], 0); + int shmid; + + printf("*** %s start ***\n", basename(argv[0])); + + shmid = shmget(key, SZ_MEM, IPC_CREAT | 0660); + INTERR(shmid == -1, "shmget failed\n"); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + void *shm = shmat(shmid, NULL, 0); + + INTERR(shm == (void *)-1, "shmat in child failed\n"); + + while ((segid = *(xpmem_segid_t *)shm) == 0) { + sched_yield(); + }; + + ret = shmdt(shm); + INTERR(ret == -1, "shmdt failed\n"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, "xpmem_get in child\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach != (void *)-1, "xpmem_attach in child\n"); + + *((unsigned long *)attach) = TEST_VAL; + + ret = xpmem_detach(attach); + OKNG(ret != -1, "xpmem_detach in child\n"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + void *shm = shmat(shmid, NULL, 0); + struct shmid_ds buf; + + INTERR(shm == (void *)-1, "shmat in parent failed\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, + (void *)0666); + OKNG(segid != -1, "xpmem_make in parent\n"); + + *(xpmem_segid_t *)shm = segid; + + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + OKNG(*((unsigned long *)mem) == TEST_VAL, + "TEST_VAL found\n"); + + ret = shmctl(shmid, IPC_RMID, &buf); + INTERR(ret == -1, "shmctl failed\n"); + + ret = shmdt(shm); + INTERR(ret == -1, "shmdt failed\n"); + + ret = xpmem_remove(segid); + OKNG(ret != -1, "xpmem_remove in parent\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_005.c b/test/issues/1473/XTP_005.c new file mode 100644 index 00000000..ea509973 --- /dev/null +++ b/test/issues/1473/XTP_005.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + INTERR(ret != 0, "xpmem_init failed\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid != -1, "xpmem_make\n"); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, "xpmem_get in child\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach != (void *)-1, "xpmem_attach in child\n"); + + *((unsigned long *)attach) = TEST_VAL; + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + OKNG(*((unsigned long *)mem) == TEST_VAL, + "TEST_VAL found\n"); + + ret = xpmem_remove(segid); + OKNG(ret != -1, "xpmem_remove in parent\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_006.c b/test/issues/1473/XTP_006.c new file mode 100644 index 00000000..bf919236 --- /dev/null +++ b/test/issues/1473/XTP_006.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +int main(int argc, char **argv) +{ + void *mem; + int ret = 0; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + INTERR(ret != 0, "xpmem_init failed\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid != -1, "xpmem_make\n"); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + sleep(1); /* wait for parent process exit */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid == -1, + "xpmem_get in child failed as expected because parent process exited already\n"); + fflush(0); + + } else { + /* Parent process */ + _exit(0); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_007.c b/test/issues/1473/XTP_007.c new file mode 100644 index 00000000..cf99f1e6 --- /dev/null +++ b/test/issues/1473/XTP_007.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +#define BAD_ADDRESS ((void *)-1) + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + INTERR(ret != 0, "xpmem_init failed\n"); + + segid = xpmem_make(BAD_ADDRESS, SZ_MEM, XPMEM_PERMIT_MODE, + (void *)0666); + OKNG(segid == -1, + "xpmem_make with invalid address failed as expected\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + INTERR(segid == -1, "xpmem_make failed\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid != -1, "duplicated xpmem_make call succeeded as expected\n"); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + INTERR(apid == -1, "xpmem_get in child failed\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + INTERR(attach == (void *)-1, + "xpmem_attach in child failed\n"); + + *((unsigned long *)attach) = TEST_VAL; + + ret = xpmem_detach(attach); + INTERR(ret == -1, "xpmem_detach in child failed\n"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + INTERR(*((unsigned long *)mem) != TEST_VAL, + "TEST_VAL not found\n"); + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_008.c b/test/issues/1473/XTP_008.c new file mode 100644 index 00000000..4ca56a02 --- /dev/null +++ b/test/issues/1473/XTP_008.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +#define BAD_SEGID -1 + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + INTERR(ret != 0, "xpmem_init failed\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + INTERR(segid == -1, "xpmem_make failed\n"); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(BAD_SEGID, XPMEM_RDWR, XPMEM_PERMIT_MODE, + NULL); + OKNG(apid == -1, + "xpmem_get with invalid segid failed as expected\n"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + INTERR(apid == -1, "xpmem_get in child failed\n"); + + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, + "duplicated xpmem_get succeeded as expected\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + INTERR(attach == (void *)-1, "xpmem_attach in child failed\n"); + + *((unsigned long *)attach) = TEST_VAL; + + ret = xpmem_detach(attach); + INTERR(ret == -1, "xpmem_detach in child failed\n"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + INTERR(*((unsigned long *)mem) != TEST_VAL, + "TEST_VAL not found\n"); + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_009.c b/test/issues/1473/XTP_009.c new file mode 100644 index 00000000..40b569d0 --- /dev/null +++ b/test/issues/1473/XTP_009.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + INTERR(ret != 0, "xpmem_init failed\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + INTERR(segid == -1, "xpmem_make failed\n"); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + INTERR(apid == -1, "xpmem_get in child failed\n"); + + addr.apid = -1; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach == (void *)-1, + "xpmem_attach with invalid apid failed as expected\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + INTERR(attach == (void *)-1, "xpmem_attach in child failed\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach != (void *)-1, + "duplicated xpmem_attach call succeeded as expected\n"); + + *((unsigned long *)attach) = TEST_VAL; + + ret = xpmem_detach(attach); + INTERR(ret == -1, "xpmem_detach in child failed\n"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + INTERR(*((unsigned long *)mem) != TEST_VAL, + "TEST_VAL not found\n"); + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_010.c b/test/issues/1473/XTP_010.c new file mode 100644 index 00000000..af412f0f --- /dev/null +++ b/test/issues/1473/XTP_010.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +#define BAD_ADDRESS ((void *) -1) + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + INTERR(segid == -1, "xpmem_make failed\n"); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + INTERR(apid == -1, "xpmem_get in child failed\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + INTERR(attach == (void *)-1, "xpmem_attach in child failed\n"); + + *((unsigned long *)attach) = TEST_VAL; + + ret = xpmem_detach(BAD_ADDRESS); + OKNG(ret != -1, + "xpmem_detach with invalid address succeeded as expected\n"); + + ret = xpmem_detach(attach); + INTERR(ret == -1, "xpmem_detach in child failed\n"); + + ret = xpmem_detach(attach); + OKNG(ret != -1, + "duplicated xpmem_detach succeeded as expected\n"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + INTERR(*((unsigned long *)mem) != TEST_VAL, + "TEST_VAL not found\n"); + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/XTP_011.c b/test/issues/1473/XTP_011.c new file mode 100644 index 00000000..ac232c58 --- /dev/null +++ b/test/issues/1473/XTP_011.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +#define BAD_SEGID -1 + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret = 0; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + printf("*** %s start ***\n", basename(argv[0])); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == NULL, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + INTERR(ret != 0, "xpmem_init failed\n"); + + segid = xpmem_make(mem, SZ_MEM, XPMEM_PERMIT_MODE, (void *)0666); + INTERR(segid == -1, "xpmem_make failed\n"); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + INTERR(apid == -1, "xpmem_get in child failed\n"); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, SZ_MEM, NULL); + INTERR(attach == (void *)-1, "xpmem_attach in child failed\n"); + + *((unsigned long *)attach) = TEST_VAL; + + ret = xpmem_detach(attach); + INTERR(ret == -1, "xpmem_detach in child failed\n"); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + INTERR(*((unsigned long *)mem) != TEST_VAL, + "TEST_VAL not found\n"); + + ret = xpmem_remove(BAD_SEGID); + OKNG(ret == -1, + "xpmem_remove with invalid segid failed as expected\n"); + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + + ret = xpmem_remove(segid); + OKNG(ret == -1, + "duplicated xpmem_remove call failed as expected\n"); + } + + printf("*** %s PASSED\n\n", basename(argv[0])); + return 0; + +out: + printf("*** %s FAILED\n\n", basename(argv[0])); + + return -1; +} diff --git a/test/issues/1473/aarch64.conf b/test/issues/1473/aarch64.conf new file mode 100644 index 00000000..e6b1d061 --- /dev/null +++ b/test/issues/1473/aarch64.conf @@ -0,0 +1,3 @@ +PGSHIFT_LIST="16 21 29" +PAGE_SIZE=65536 +PAGE_SHIFT=16 diff --git a/test/issues/1473/common.sh.in b/test/issues/1473/common.sh.in new file mode 100644 index 00000000..f1482074 --- /dev/null +++ b/test/issues/1473/common.sh.in @@ -0,0 +1,19 @@ +#!/usr/bin/sh + +# define WORKDIR expecting this script is on /data/scripts/ +SCRIPT_PATH=$(readlink -m "${BASH_SOURCE[0]}") +AUTOTEST_HOME="${SCRIPT_PATH%/*/*/*/*}" +if [[ -e ${AUTOTEST_HOME}/bin/config.sh ]]; then + . ${AUTOTEST_HOME}/bin/config.sh +else + WORKDIR=$(pwd) +fi + +arch=`uname -p` +if [ -f @CMAKE_INSTALL_PREFIX@/etc/${arch}.conf ]; then + . @CMAKE_INSTALL_PREFIX@/etc/${arch}.conf +else + echo "unknown arch: $1" + exit 1 +fi + diff --git a/test/issues/1473/huge_page_xpmem.c b/test/issues/1473/huge_page_xpmem.c new file mode 100644 index 00000000..02530f4c --- /dev/null +++ b/test/issues/1473/huge_page_xpmem.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +#define DEBUG + +#define SHM_SIZE (1UL << 12) + +#define MAP_HUGE_SHIFT 26 +#define KEYWORD 0x12345678UL + +void usage(void) +{ + printf("Usage: huge_page_map: \n"); + printf("\tpgshift : pageshift of map area (Using MAP_HUGETLB)\n"); + printf("\t -1 means using small pagesize\n"); + printf("\tpgnum : number of page of map area\n"); + printf("\tpgoffset: offset of last page\n"); +} + + +void *mmap_flag(size_t mapsize, int page_shift) +{ + char *addr_mmap; + int flags = MAP_ANONYMOUS | MAP_PRIVATE; + + if (page_shift >= 0) { + /* mean use MAP_HUGETLB */ + flags |= MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT); + } + + addr_mmap = mmap(0, mapsize, + PROT_READ | PROT_WRITE, + flags, -1, 0); + + return addr_mmap; +} + +int main(int argc, char **argv) +{ + void *mem; + int ret = 0; + pid_t pid; + int status; + key_t key = ftok(argv[0], 0); + void *shm; + int shmid; + xpmem_segid_t segid; + struct shmid_ds shmctl_buf; + int pgshift, pgnum; + size_t pgsize, map_size, pgoffset; + + if (argc < 4) { + printf("Err: Too few arguments\n"); + usage(); + return -1; + } + + pgshift = atoi(argv[1]); + pgnum = atoi(argv[2]); + pgoffset = atol(argv[3]); + if (pgshift > 0) { + pgsize = (1UL << pgshift); + } else { + pgsize = getpagesize(); + } + + if (pgoffset > 0) { + map_size = (pgsize * (pgnum - 1)) + pgoffset; + } else { + map_size = pgsize * pgnum; + } + INFO("map_size: %lx\n", map_size); + + shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0660); + INTERR(shmid == -1, "shmget failed: %s\n", + strerror(errno)); + + printf("EXPECT_PAGE_SIZE: 0x%lx\n", pgsize); + fflush(stdout); + + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + if (pid == 0) { + xpmem_apid_t apid; + struct xpmem_addr addr; + void *attach; + + shm = shmat(shmid, NULL, 0); + INTERR(shm == (void *)-1, + "shmat failed: %s\n", strerror(errno)); + + INFO("child: wait until segid is posted\n"); + while ((segid = *(xpmem_segid_t *)shm) == 0) { + sched_yield(); + }; + + INFO("child: segid: %lx\n", (unsigned long)segid); + + ret = shmdt(shm); + INTERR(ret == -1, "shmdt failed\n"); + + apid = xpmem_get(segid, XPMEM_RDWR, + XPMEM_PERMIT_MODE, NULL); + INTERR(apid == -1, "xpmem_get failed: %s\n", + strerror(errno)); + + addr.apid = apid; + addr.offset = 0; + attach = xpmem_attach(addr, map_size, NULL); + + INTERR(attach == (void *)-1, + "xpmem_attach failed: %s\n", strerror(errno)); + + printf("child: xpmem_attachment_addr: %lx\n", + (unsigned long)attach); + + *((unsigned long *)attach) = KEYWORD; + if (pgnum > 1 && pgshift > 0) { + *((unsigned long *)(attach + + (1UL << pgshift))) = KEYWORD; + } + *((unsigned long *)(attach + map_size + - sizeof(unsigned long *))) = KEYWORD; + + ret = xpmem_detach(attach); + INTERR(ret == -1, "xpmem_detach failed\n"); + + exit(0); + } else { + mem = mmap_flag(map_size, pgshift); + INTERR(mem == MAP_FAILED, "mmap failed\n"); + INFO("parent: anonymous_map_addr: %lx - %lx\n", + (unsigned long)mem, (unsigned long)(mem + map_size)); + + shm = shmat(shmid, NULL, 0); + + INTERR(shm == (void *)-1, + "shmat failed: %s\n", strerror(errno)); + + segid = xpmem_make(mem, map_size, XPMEM_PERMIT_MODE, + (void *)0666); + INTERR(segid == -1, + "xpmem_ioctl failed: %s\n", strerror(errno)); + + INFO("parent: posting segid of %lx\n", (unsigned long)segid); + *(xpmem_segid_t *)shm = segid; + + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + ret = shmctl(shmid, IPC_RMID, &shmctl_buf); + INTERR(ret == -1, "shmctl failed\n"); + + ret = shmdt(shm); + INTERR(ret == -1, "shmdt failed\n"); + + OKNG(*(unsigned long *)mem == KEYWORD, + "HEAD of xpmem area is shared\n"); + if (pgnum > 1 && pgshift > 0) { + OKNG(*((unsigned long *)(mem + + (1UL << pgshift))) == KEYWORD, + "MIDDLE of xpmem area is shared\n"); + } + OKNG(*((unsigned long *)(mem + map_size + - sizeof(unsigned long *))) == KEYWORD, + "TAIL of xpmem area is shared\n"); + printf("xpmem area is shared: OK\n"); + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + } + + ret = 0; + out: + return ret; +} diff --git a/test/issues/1473/ihk_kmsg_size.patch b/test/issues/1473/ihk_kmsg_size.patch new file mode 100644 index 00000000..17c210a2 --- /dev/null +++ b/test/issues/1473/ihk_kmsg_size.patch @@ -0,0 +1,13 @@ +diff --git linux/include/ihk/ihk_debug.h linux/include/ihk/ihk_debug.h +index 9b53dd7..305a3a9 100644 +--- linux/include/ihk/ihk_debug.h ++++ linux/include/ihk/ihk_debug.h +@@ -8,7 +8,7 @@ + #ifndef IHK_DEBUG_H_INCLUDED + #define IHK_DEBUG_H_INCLUDED + +-#define IHK_KMSG_SIZE 8192 ++#define IHK_KMSG_SIZE (4UL<<20) + #define IHK_KMSG_HIGH_WATER_MARK (IHK_KMSG_SIZE / 2) + #define IHK_KMSG_NOTIFY_DELAY 400 /* Unit is us, 400 us would avoid overloading fwrite of ihkmond */ + diff --git a/test/issues/1473/large_page.patch b/test/issues/1473/large_page.patch new file mode 100644 index 00000000..f3df2f16 --- /dev/null +++ b/test/issues/1473/large_page.patch @@ -0,0 +1,117 @@ +diff --git arch/arm64/kernel/memory.c arch/arm64/kernel/memory.c +index a84bc21..f329fcf 100644 +--- arch/arm64/kernel/memory.c ++++ arch/arm64/kernel/memory.c +@@ -2701,6 +2701,16 @@ int set_range_l1(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start, + ptl1_set(ptep, pte); + + error = 0; ++ ++ if (args->attr[0] & PTE_CONT && ++ __page_offset(base, PTL1_CONT_SIZE) == 0) { ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx , phys: %lx\n", ++ __func__, base, PTL1_CONT_SIZE, phys); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL1_CONT_SIZE); ++ } ++ + // call memory_stat_rss_add() here because pgshift is resolved here + if (!(args->attr[0] & PTE_CONT)) { + if (rusage_memory_stat_add(args->range, phys, +@@ -2810,6 +2820,23 @@ retry: + level); + + error = 0; ++ ++ if (args->attr[level-1] & PTE_CONT) { ++ if (__page_offset(base, tbl.cont_pgsize) == 0) { ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx , phys: %lx\n", ++ __func__, base, tbl.cont_pgsize, phys); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, tbl.cont_pgsize); ++ } ++ } else { ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx , phys: %lx\n", ++ __func__, base, tbl.pgsize, phys); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, tbl.pgsize); ++ } ++ + dkprintf("set_range_middle(%lx,%lx,%lx,%d):" + "large page. %d %lx\n", + base, start, end, level, error, *ptep); +diff --git arch/x86_64/kernel/memory.c arch/x86_64/kernel/memory.c +index 6b34036..4ca3a1a 100644 +--- arch/x86_64/kernel/memory.c ++++ arch/x86_64/kernel/memory.c +@@ -1932,6 +1932,13 @@ retry: + dkprintf("set_range_l2(%lx,%lx,%lx):" + "2MiB page. %d %lx\n", + base, start, end, error, *ptep); ++ ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL2_SIZE); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL2_SIZE); ++ + // Call memory_stat_rss_add() here because pgshift is resolved here + if (rusage_memory_stat_add(args->range, phys, PTL2_SIZE, PTL2_SIZE)) { + dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL2_SIZE, PTL2_SIZE); +@@ -2021,6 +2028,12 @@ retry: + "1GiB page. %d %lx\n", + base, start, end, error, *ptep); + ++ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL3_SIZE); ++ if (args->range->private_data) ++ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ __func__, base, PTL3_SIZE); ++ + // Call memory_stat_rss_add() here because pgshift is resolved here + if (rusage_memory_stat_add(args->range, phys, PTL3_SIZE, PTL3_SIZE)) { + dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL3_SIZE, PTL3_SIZE); +diff --git kernel/process.c kernel/process.c +index 1624726..d867b4d 100644 +--- kernel/process.c ++++ kernel/process.c +@@ -2138,6 +2138,12 @@ retry: + } + + dkprintf("%s: attr=%x\n", __FUNCTION__, attr); ++ ++ if (pgsize > PAGE_SIZE) { ++ kprintf("large_page_allocation, addr: %016lx, size: %d, phys: %lx\n", ++ pgaddr, pgsize, phys); ++ } ++ + error = ihk_mc_pt_set_pte(vm->address_space->page_table, ptep, + pgsize, phys, attr); + if (error) { +diff --git kernel/xpmem.c kernel/xpmem.c +index 9fedf26..a0a7990 100644 +--- kernel/xpmem.c ++++ kernel/xpmem.c +@@ -490,6 +490,7 @@ static int xpmem_make( + *segid_p = segid; + + XPMEM_DEBUG("return: ret=%d, segid=0x%lx", 0, *segid_p); ++ kprintf("%s: DONE\n", __func__); + + return 0; + } +@@ -1886,6 +1887,11 @@ static int _xpmem_fault_process_memory_range( + goto out; + } + ++ if (att_pgsize == PAGE_SIZE) { ++ kprintf("xpmem_page_attach, addr: %016lx, size: 0x%lx\n", ++ vaddr, att_pgsize); ++ } ++ + XPMEM_DEBUG("att_pgaddr: %lx, att_pgsize: %lx, " + "seg_vaddr: %lx, seg_pgsize: %lx, seg_phys: %lx\n", + att_pgaddr, att_pgsize, seg_vaddr, diff --git a/test/issues/1473/multi_vmr_xpmem.c b/test/issues/1473/multi_vmr_xpmem.c new file mode 100644 index 00000000..66438577 --- /dev/null +++ b/test/issues/1473/multi_vmr_xpmem.c @@ -0,0 +1,199 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +#define DEBUG + +#define SHM_SIZE (1UL << 12) + +#define MAP_HUGE_SHIFT 26 +#define KEYWORD 0x12345678UL + +void usage(void) +{ + printf("Usage: multi_vmr_xpmem: \n"); + printf("\tpgshift : pageshift of map area (Using MAP_HUGETLB)\n"); + printf("\t -1 means using small pagesize\n"); + printf("\tpgnum : number of page of map area\n"); +} + + +void *mmap_flag(size_t mapsize, int page_shift) +{ + char *addr_mmap; + int flags = MAP_ANONYMOUS | MAP_PRIVATE; + + if (page_shift >= 0) { + /* mean use MAP_HUGETLB */ + flags |= MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT); + } + + addr_mmap = mmap(0, mapsize * 2, + PROT_READ | PROT_WRITE, + flags, -1, 0); + + /* Make sure that area before addr_map is available to + * MAP_FIXED map + */ + return addr_mmap + mapsize; +} + +int main(int argc, char **argv) +{ + void *mem, *mem_1, *mem_2; + int ret = 0; + pid_t pid; + int status; + key_t key = ftok(argv[0], 10); + void *shm; + int shmid; + xpmem_segid_t segid; + struct shmid_ds shmctl_buf; + int pgshift, pgnum; + size_t extr_size, pgsize, map_size; + + if (argc < 3) { + printf("Err: Too few arguments\n"); + usage(); + return -1; + } + + pgshift = atoi(argv[1]); + pgnum = atoi(argv[2]); + extr_size = getpagesize() * 3; + if (pgshift > 0) { + pgsize = (1UL << pgshift); + } else { + pgsize = getpagesize(); + } + + map_size = pgsize * pgnum; + + shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0660); + INTERR(shmid == -1, "shmget failed: %s\n", + strerror(errno)); + + printf("EXPECT_PAGE_SIZE: 0x%lx\n", pgsize); + fflush(stdout); + + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + if (pid == 0) { + xpmem_apid_t apid; + struct xpmem_addr addr; + void *attach; + + shm = shmat(shmid, NULL, 0); + INTERR(shm == (void *)-1, + "shmat failed: %s\n", strerror(errno)); + + INFO("child: wait until segid is posted\n"); + while ((segid = *(xpmem_segid_t *)shm) == 0) { + sched_yield(); + }; + + INFO("child: segid: %lx\n", (unsigned long)segid); + + ret = shmdt(shm); + INTERR(ret == -1, "shmdt failed\n"); + + apid = xpmem_get(segid, XPMEM_RDWR, + XPMEM_PERMIT_MODE, NULL); + INTERR(apid == -1, "xpmem_get failed: %s\n", + strerror(errno)); + + addr.apid = apid; + addr.offset = 0; + printf("child: attaching...\n"); + attach = xpmem_attach(addr, map_size + (extr_size * 2), NULL); + + INTERR(attach == (void *)-1, + "xpmem_attach failed: %s\n", strerror(errno)); + + printf("child: xpmem_attachment_addr: %lx - %lx\n", + (unsigned long)attach, + (unsigned long)(attach + map_size + (extr_size * 2))); + printf("child: xpmem_large: %lx\n", + (unsigned long)(attach + extr_size)); + + *((unsigned long *)attach) = KEYWORD; + *((unsigned long *)(attach + extr_size)) = KEYWORD; + *((unsigned long *)(attach + extr_size * 2 + map_size + - sizeof(unsigned long *))) = KEYWORD; + + ret = xpmem_detach(attach); + INTERR(ret == -1, "xpmem_detach failed\n"); + + exit(0); + } else { + mem = mmap_flag(map_size, pgshift); + INTERR(mem == MAP_FAILED, "mmap failed\n"); + mem_1 = mmap(mem - extr_size, extr_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, + -1, 0); + mem_2 = mmap(mem + map_size, extr_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, + -1, 0); + if ((mem_1 + extr_size != mem) || (mem_2 != mem + map_size)) { + printf("vm_range is NOT contignuous!!\n"); + exit(1); + } + INFO("parent: anonymous_map_addr: %lx - %lx\n", + (unsigned long)mem_1, + (unsigned long)(mem_2 + extr_size)); + + shm = shmat(shmid, NULL, 0); + + INTERR(shm == (void *)-1, + "shmat failed: %s\n", strerror(errno)); + + segid = xpmem_make(mem_1, map_size + (extr_size * 2), + XPMEM_PERMIT_MODE, (void *)0666); + INTERR(segid == -1, + "xpmem_ioctl failed: %s\n", strerror(errno)); + + INFO("parent: posting segid of %lx\n", (unsigned long)segid); + *(xpmem_segid_t *)shm = segid; + + ret = waitpid(pid, &status, 0); + printf("child exited\n"); + INTERR(ret == -1, "waitpid failed\n"); + + ret = shmctl(shmid, IPC_RMID, &shmctl_buf); + INTERR(ret == -1, "shmctl failed\n"); + + ret = shmdt(shm); + INTERR(ret == -1, "shmdt failed\n"); + + OKNG(*(unsigned long *)mem_1 == KEYWORD, + "HEAD of xpmem area is shared\n"); + OKNG(*(unsigned long *)mem == KEYWORD, + "MIDDLE of xpmem area is shared\n"); + OKNG(*((unsigned long *)(mem_2 + extr_size + - sizeof(unsigned long *))) == KEYWORD, + "TAIL of xpmem area is shared\n"); + printf("xpmem area is shared: OK\n"); + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + } + + ret = 0; + out: + return ret; +} diff --git a/test/issues/1473/okng.h b/test/issues/1473/okng.h new file mode 100644 index 00000000..27fdd697 --- /dev/null +++ b/test/issues/1473/okng.h @@ -0,0 +1,32 @@ +#ifndef __OKNG_H_INCLUDED__ +#define __OKNG_H_INCLUDED__ + +#include + +#define _OKNG(verb, jump, cond, fmt, args...) do { \ + if (cond) { \ + if (verb) \ + printf("[ OK ] " fmt, ##args); \ + } else { \ + printf("[ NG ] " fmt, ##args); \ + if (jump) { \ + ret = 1; \ + goto out; \ + } \ + } \ +} while (0) + +#define OKNG(args...) _OKNG(1, 1, ##args) +#define INFO(fmt, args...) printf("[ INFO ] " fmt, ##args) +#define START(fmt, args...) printf("[ START] " fmt, ##args) +#define INTERR(cond, fmt, args...) do { \ + if (cond) { \ + char msg[4096]; \ + sprintf(msg, fmt, ##args); \ + printf("[INTERR] %s:%d %s", __FILE__, __LINE__, msg); \ + ret = 1; \ + goto out; \ + } \ +} while (0) + +#endif diff --git a/test/issues/1473/util.h b/test/issues/1473/util.h new file mode 100644 index 00000000..80ee28e6 --- /dev/null +++ b/test/issues/1473/util.h @@ -0,0 +1,11 @@ +#ifdef __aarch64__ +#define LARGE_PAGE_SHIFT 21 +#elif defined(__x86_64__) +#define LARGE_PAGE_SHIFT 21 +#else +#error "Non-compliant architecture." +#endif + +#define MAP_HUGE_SHIFT 26 +#define SZ_MEM (2 * (1ULL << LARGE_PAGE_SHIFT)) +#define TEST_VAL 0x1129 diff --git a/test/issues/1473/util.sh.in b/test/issues/1473/util.sh.in new file mode 100644 index 00000000..05b8a828 --- /dev/null +++ b/test/issues/1473/util.sh.in @@ -0,0 +1,122 @@ +function patch_and_build() +{ + fn_mckernel=$1 + fn_ihk=$2 + + if [ "$fn_mckernel" != "" ]; then + pushd @WITH_MCK_SRC@ + patch -p0 < @CMAKE_INSTALL_PREFIX@/bin/${fn_mckernel}.patch + ret=$? + if [ $ret -ne 0 ]; then + echo "[INTERR] patch failed" + patch -p0 -R < @CMAKE_INSTALL_PREFIX@/bin/${fn_mckernel}.patch + return $ret + fi + popd + fi + + if [ "$fn_ihk" != "" ]; then + pushd @WITH_MCK_SRC@/ihk + patch -p0 < @CMAKE_INSTALL_PREFIX@/bin/${fn_ihk}.patch + ret=$? + if [ $ret -ne 0 ]; then + echo "[INTERR] patch failed" + patch -p0 -R < @CMAKE_INSTALL_PREFIX@/bin/${fn_ihk}.patch + return $ret + fi + popd + fi + + if [ -f ${AUTOTEST_HOME}/bin/config.sh ]; then + BUILDDIR=$WORKDIR/build/$(uname -r) + else + BUILDDIR=@WITH_MCK_BUILD@ + fi + + pushd $BUILDDIR + make -j install + popd + + if [ "$fn_mckernel" != "" ]; then + pushd @WITH_MCK_SRC@ + patch -R -p0 < @CMAKE_INSTALL_PREFIX@/bin/${fn_mckernel}.patch + popd + fi + + if [ "$fn_ihk" != "" ]; then + pushd @WITH_MCK_SRC@/ihk + patch -R -p0 < @CMAKE_INSTALL_PREFIX@/bin/${fn_ihk}.patch + popd + fi + + return 0 +} + +function detect_cpu_model() +{ + implementer=$(gawk '/CPU implementer/ { print $4; exit; }' /proc/cpuinfo) + arch=$(gawk '/CPU architecture/ { print $3; exit; }' /proc/cpuinfo) + var=$(gawk '/CPU variant/ { print $4; exit; }' /proc/cpuinfo) + part=$(gawk '/CPU part/ { print $4; exit; }' /proc/cpuinfo) + + if [[ "$implementer" == "0x46" ]] && [[ "$arch" == "8" ]] && + [[ "$var" == "0x1" ]] && [[ "$part" == "0x001" ]]; then + cpu_model="a64fx" + elif [[ "$implementer" == "0x43" ]] && [[ "$arch" == "8" ]] && + [[ "$var" == "0x1" ]] && [[ "$part" == "0x0a1" ]]; then + cpu_model="thunderx" + else + cpu_model="unknown" + fi +} + +function init_oom_killer() +{ + echo "[ INFO ] performing \"echo 0 > /proc/sys/vm/min_free_kbytes\"" + min_free_kbytes=$(cat /proc/sys/vm/min_free_kbytes) + sudo bash -c 'echo 0 > /proc/sys/vm/min_free_kbytes' +} + +function fini_oom_killer() +{ + echo "[ INFO ] performing \"echo $min_free_kbytes > /proc/sys/vm/min_free_kbytes\"" + sudo bash -c "echo $min_free_kbytes > /proc/sys/vm/min_free_kbytes" +} + +function check_dump() { + dump=$1 + interactive=$2 + + if [ $interactive -eq 1 ]; then + eclair_opt="-i" + else + eclair_opt= + fi + + expect -c " +set timeout 20 +spawn sudo @WITH_MCK@/bin/eclair -d ${dump} -k @WITH_MCK@/smp-arm64/kernel/mckernel.img -l $eclair_opt + +expect \"(eclair)\" +send \"set pagination 0\n\" + +expect \"(eclair)\" +send \"info threads\n\" + +expect \"(eclair)\" +send \"thread 3\n\" + +expect \"(eclair)\" +send \"bt\n\" + +expect \"(eclair)\" +send \"p/x _end\n\" + +expect \"(eclair)\" +send \"quit\n\" + +" > ${WORKDIR}/log + + awk -f @CMAKE_INSTALL_PREFIX@/bin/check_dump.awk ${WORKDIR}/log + ret=$? +} diff --git a/test/issues/1473/x86_64.conf b/test/issues/1473/x86_64.conf new file mode 100644 index 00000000..30168202 --- /dev/null +++ b/test/issues/1473/x86_64.conf @@ -0,0 +1,3 @@ +PGSHIFT_LIST=(21 30) +PAGE_SIZE=4096 +PAGE_SHIFT=12 diff --git a/test/issues/1473/xpmem_attach01.c b/test/issues/1473/xpmem_attach01.c new file mode 100644 index 00000000..3feb5804 --- /dev/null +++ b/test/issues/1473/xpmem_attach01.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "okng.h" +#include "util.h" + +#define DEBUG + +#define MAP_HUGE_SHIFT 26 +#define MAGIC_HEAD 0x12345678UL +#define MAGIC_TAIL 0x9abcdef0UL + +int main(int argc, char **argv) +{ + int i; + void *mem; + int ret; + pid_t pid; + int status; + xpmem_segid_t segid; + int att_pgshift, seg_pgshift; + size_t att_pgsize, seg_pgsize; + + if (argc < 3) { + printf("Err: Too few arguments\n"); + printf("Usage: %s \n", + basename(argv[0])); + printf("\tpgshift : page-shift of attachment\n"); + printf("\tpgshift : page-shift of segment\n"); + return 1; + } + + seg_pgshift = atoi(argv[1]); + seg_pgsize = (1UL << seg_pgshift); + att_pgshift = atoi(argv[2]); + att_pgsize = (1UL << att_pgshift); + + INTERR(seg_pgsize > att_pgsize, + "seg_pgsize (%lx) > att_pgsize (%lx)\n", + seg_pgsize, att_pgsize); + + printf("parent: seg_pgsize: 0x%lx\n", seg_pgsize); + printf("parent: att_pgsize: 0x%lx\n", att_pgsize); + + mem = mmap(0, att_pgsize, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (att_pgshift << MAP_HUGE_SHIFT), + -1, 0); + + INTERR(mem == MAP_FAILED, "mapping att_pgsize memory failed\n"); + printf("parent: anonymous_map_addr: %lx - %lx\n", + (unsigned long)mem, + (unsigned long)mem + att_pgsize); + + /* Create physically-contiguous maps with smaller page-size */ + for (i = 0; i < att_pgsize / seg_pgsize; i++) { + void *smaller; + void *addr = mem + i * seg_pgsize; + + smaller = mmap(addr, seg_pgsize, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, + -1, 0); + INTERR(smaller == MAP_FAILED, + "mapping seg_pgsize memory failed\n"); + + /* to distinguish from the large page at mem */ + if (i == 1) { + printf("parent: seg_addr: %lx\n", + (unsigned long)addr); + } + } + + segid = xpmem_make((void *)mem, + att_pgsize, XPMEM_PERMIT_MODE, (void *)0666); + INTERR(segid == -1, "xpmem_make: addr: %lx, size: %lx, error: %s\n", + (unsigned long)mem, att_pgsize, strerror(errno)); + + fflush(stdout); /* to prevent buffer from getting duplicated */ + + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + xpmem_apid_t apid; + struct xpmem_addr addr; + void *attach; + + apid = xpmem_get(segid, XPMEM_RDWR, + XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, "apid: %lx\n", (unsigned long)apid); + + addr.apid = apid; + addr.offset = 0; + + INFO("child: attaching...\n"); + attach = xpmem_attach(addr, att_pgsize, NULL); + INTERR(attach == (void *)-1, + "xpmem_attach: size: %lx, error: %s\n", + att_pgsize, strerror(errno)); + + printf("child: att_addr: %lx\n", (unsigned long)attach); + + *((unsigned long *)attach) = MAGIC_HEAD; + *((unsigned long *)(attach + att_pgsize + - sizeof(unsigned long *))) = MAGIC_TAIL; + + ret = xpmem_detach(attach); + INTERR(ret == -1, "xpmem_detach failed\n"); + + exit(0); + } else { + INFO("parent: waiting...\n"); + ret = waitpid(pid, &status, 0); + INFO("parent: children found\n"); + INTERR(ret == -1, "waitpid failed\n"); + + OKNG(*(unsigned long *)mem == MAGIC_HEAD, + "HEAD of xpmem area is shared\n"); + OKNG(*((unsigned long *)(mem + att_pgsize + - sizeof(unsigned long *))) == + MAGIC_TAIL, "TAIL of xpmem area is shared\n"); + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + } + + ret = 0; + out: + return ret; +} diff --git a/test/issues/1473/xpmem_attach01.sh.in b/test/issues/1473/xpmem_attach01.sh.in new file mode 100644 index 00000000..815ede27 --- /dev/null +++ b/test/issues/1473/xpmem_attach01.sh.in @@ -0,0 +1,66 @@ +#!/usr/bin/bash + +SCRIPT_PATH=$(readlink -m "${BASH_SOURCE[0]}") +SCRIPT_NAME="${SCRIPT_PATH##*/}" + +# prepare recorddir +. @CMAKE_INSTALL_PREFIX@/bin/common.sh +recorddir=$WORKDIR/output/$SCRIPT_NAME +[[ ! -d $recorddir ]] && mkdir -p $recorddir + +# define patch function +. @CMAKE_INSTALL_PREFIX@/bin/util.sh +patch_and_build large_page ihk_kmsg_size || exit 1 + +# boot patched McKernel +if [[ -e ${AUTOTEST_HOME}/bin/config.sh ]]; then + ${AUTOTEST_HOME}/bin/boot.sh reboot +else + . @WITH_MCK_SRC@/test/common.sh +fi + +sudo insmod @WITH_XPMEM@/lib/modules/`uname -r`/xpmem.ko +sudo chmod og+rw /dev/xpmem + +for seg_pgshift in $PGSHIFT_LIST; do + for att_pgshift in $PGSHIFT_LIST; do + if (( seg_pgshift < att_pgshift )); then + echo "seg_pgshift: $seg_pgshift, att_pgshift: $att_pgshift" + log_file=$recorddir/${SCRIPT_NAME%.sh}-${seg_pgshift}-${att_pgshift}.log + @WITH_MCK@/sbin/ihkosctl 0 clear_kmsg + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/xpmem_attach01 $seg_pgshift $att_pgshift | tee $log_file + @WITH_MCK@/sbin/ihkosctl 0 kmsg >> $log_file + + seg_addr=$(grep 'parent.*seg_addr' $log_file | awk '{ print $NF; }') + seg_pgsize=$(grep 'parent.*seg_pgsize' $log_file | awk '{ print $NF; }') + # note that showing DONE is done by the patch + seg_pgsize_kmsg=$(awk '!/DONE/{print $0} /DONE/{exit}' $log_file | grep -o "large_page_allocation.*${seg_addr}.*" | awk '{ print $5; }') + [[ "$seg_pgsize_kmsg" == "" ]] && seg_pgsize_kmsg=$PAGE_SIZE + + att_addr=$(grep 'child.*att_addr' $log_file | awk '{ print $NF; }') + att_pgsize_kmsg=$(grep -o "xpmem_page_attach.*${att_addr}.*" $log_file | awk '{ print $NF; }') + [[ "$att_pgsize_kmsg" == "" ]] && att_pgsize_kmsg=$PAGE_SIZE + + if (( seg_pgsize == seg_pgsize_kmsg )); then + printf "[ OK ] " + else + printf "[ NG ] " + let ng++ + fi + echo "page-size of $seg_addr: $seg_pgsize_kmsg, expected: $seg_pgsize" + + if (( att_pgsize_kmsg == seg_pgsize )); then + printf "[ OK ] " + else + printf "[ NG ] " + let ng++ + fi + echo "page-size of attachment at $att_addr: $att_pgsize_kmsg, expected: $seg_pgsize" + + fi + done +done + +sudo rmmod xpmem.ko + +exit $ng diff --git a/test/issues/1473/xpmem_attach02.c b/test/issues/1473/xpmem_attach02.c new file mode 100644 index 00000000..4e2f5f52 --- /dev/null +++ b/test/issues/1473/xpmem_attach02.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "okng.h" +#include "util.h" + +#define DEBUG + +#define MAP_HUGE_SHIFT 26 +#define MAGIC_HEAD 0x12345678UL +#define MAGIC_MIDDLE 0x9abcdef0UL +#define MAGIC_TAIL 0x87654321UL + +int main(int argc, char **argv) +{ + int i; + int ret; + void *mem; + void *seg_addr; + size_t seg_size; + xpmem_segid_t segid; + pid_t pid; + int status; + int large_pgshift, small_pgshift; + size_t large_pgsize, small_pgsize; + + if (argc < 3) { + printf("Err: Too few arguments\n"); + printf("Usage: %s \n", + basename(argv[0])); + printf("\tpgshift : page-shift of head and tail part\n"); + printf("\tpgshift : page-shift of middle part\n"); + return 1; + } + + small_pgshift = atoi(argv[1]); + small_pgsize = (1UL << small_pgshift); + large_pgshift = atoi(argv[2]); + large_pgsize = (1UL << large_pgshift); + + INTERR(small_pgsize > large_pgsize, + "small_pgsize (%lx) > large_pgsize (%lx)\n", + small_pgsize, large_pgsize); + + printf("parent: small_pgsize: 0x%lx\n", small_pgsize); + printf("parent: large_pgsize: 0x%lx\n", large_pgsize); + + mem = mmap(0, 3 * large_pgsize, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (large_pgshift << MAP_HUGE_SHIFT), + -1, 0); + + INTERR(mem == MAP_FAILED, "anonymous mmap failed\n"); + printf("parent: anonymous: addr: %lx, size: %lx\n", + (unsigned long)mem, 3 * large_pgsize); + + seg_addr = mem + large_pgsize - 3 * small_pgsize; + seg_size = 3 * small_pgsize + large_pgsize + 3 * small_pgsize; + segid = xpmem_make(seg_addr, seg_size, + XPMEM_PERMIT_MODE, (void *)0666); + INTERR(segid == -1, "xpmem_make: addr: %lx, size: %lx, error: %s\n", + (unsigned long)seg_addr, seg_size, strerror(errno)); + + fflush(stdout); /* to prevent buffer from getting duplicated */ + + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + xpmem_apid_t apid; + struct xpmem_addr xpmem_addr; + void *head_addr, *middle_addr, *tail_addr; + void *addr; + + apid = xpmem_get(segid, XPMEM_RDWR, + XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, "apid: %lx\n", (unsigned long)apid); + + xpmem_addr.apid = apid; + xpmem_addr.offset = 0; + + INFO("child: attaching...\n"); + head_addr = xpmem_attach(xpmem_addr, seg_size, NULL); + INTERR(head_addr == (void *)-1, + "xpmem_attach: size: %lx, error: %s\n", + seg_size, strerror(errno)); + + printf("child: head_addr: %lx\n", (unsigned long)head_addr); + + middle_addr = head_addr + 3 * small_pgsize; + printf("child: middle_addr: %lx\n", (unsigned long)middle_addr); + + tail_addr = head_addr + 3 * small_pgsize + large_pgsize; + printf("child: tail_addr: %lx\n", (unsigned long)tail_addr); + + fflush(stdout); + + for (i = 0; i < 3; i++) { + addr = head_addr + i * small_pgsize; + *((unsigned long *)addr) = MAGIC_HEAD + i; + } + *((unsigned long *)middle_addr) = MAGIC_MIDDLE; + for (i = 0; i < 3; i++) { + addr = tail_addr + i * small_pgsize; + *((unsigned long *)addr) = MAGIC_TAIL + i; + } + + ret = xpmem_detach(head_addr); + INTERR(ret == -1, "xpmem_detach failed\n"); + + exit(0); + } else { + void *head_addr = seg_addr; + void *middle_addr = seg_addr + 3 * small_pgsize; + void *tail_addr = seg_addr + 3 * small_pgsize + large_pgsize; + void *addr; + + INFO("parent: waiting...\n"); + ret = waitpid(pid, &status, 0); + INFO("parent: children reaped\n"); + INTERR(ret == -1, "waitpid failed\n"); + + for (i = 0; i < 3; i++) { + addr = head_addr + i * small_pgsize; + OKNG(*((unsigned long *)addr) == MAGIC_HEAD + i, + "%lx: %lx, expected: %lx\n", + (unsigned long)addr, *((unsigned long *)addr), + MAGIC_HEAD + i); + } + OKNG(*((unsigned long *)middle_addr) == MAGIC_MIDDLE, + "%lx: %lx, expected: %lx\n", + (unsigned long)middle_addr, + *((unsigned long *)middle_addr), + MAGIC_MIDDLE); + for (i = 0; i < 3; i++) { + addr = tail_addr + i * small_pgsize; + OKNG(*((unsigned long *)addr) == MAGIC_TAIL + i, + "%lx: %lx, expected: %lx\n", + (unsigned long)addr, *((unsigned long *)addr), + MAGIC_TAIL + i); + } + + ret = xpmem_remove(segid); + INTERR(ret == -1, "xpmem_remove failed\n"); + } + + ret = 0; + out: + return ret; +} diff --git a/test/issues/1473/xpmem_attach02.sh.in b/test/issues/1473/xpmem_attach02.sh.in new file mode 100644 index 00000000..b43c79d1 --- /dev/null +++ b/test/issues/1473/xpmem_attach02.sh.in @@ -0,0 +1,63 @@ +#!/usr/bin/bash + +declare -A addr=() +declare -A pgsize_kmsg=() +declare -A pgsize_expected=() + +SCRIPT_PATH=$(readlink -m "${BASH_SOURCE[0]}") +SCRIPT_NAME="${SCRIPT_PATH##*/}" + +# prepare recorddir +. @CMAKE_INSTALL_PREFIX@/bin/common.sh +recorddir=$WORKDIR/output/$SCRIPT_NAME +[[ ! -d $recorddir ]] && mkdir -p $recorddir + +# define patch function +. @CMAKE_INSTALL_PREFIX@/bin/util.sh +patch_and_build large_page ihk_kmsg_size || exit 1 + +# boot patched McKernel +if [[ -e ${AUTOTEST_HOME}/bin/config.sh ]]; then + ${AUTOTEST_HOME}/bin/boot.sh reboot +else + . @WITH_MCK_SRC@/test/common.sh +fi + +sudo insmod @WITH_XPMEM@/lib/modules/`uname -r`/xpmem.ko +sudo chmod og+rw /dev/xpmem + +for small_pgshift in $PGSHIFT_LIST; do + for large_pgshift in $PGSHIFT_LIST; do + if (( small_pgshift < large_pgshift )); then + echo "small_pgshift: $small_pgshift, large_pgshift: $large_pgshift" + log_file=$recorddir/${SCRIPT_NAME%.sh}-${small_pgshift}-${large_pgshift}.log + @WITH_MCK@/sbin/ihkosctl 0 clear_kmsg + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/xpmem_attach02 $small_pgshift $large_pgshift | tee $log_file + @WITH_MCK@/sbin/ihkosctl 0 kmsg >> $log_file + + pgsize_expected[head]=$((1 << $small_pgshift)) + pgsize_expected[middle]=$((1 << $large_pgshift)) + pgsize_expected[tail]=$((1 << $small_pgshift)) + + for i in head middle tail; do + addr[$i]=$(grep "child.*${i}_addr" $log_file | awk '{ print $NF; }') + pgsize_kmsg[$i]=$(grep -o "xpmem_page_attach.*${addr[$i]}.*" $log_file | awk '{ print $NF; }') + [[ "${pgsize_kmsg[$i]}" == "" ]] && pgsize_kmsg[$i]=$PAGE_SIZE + + echo "pgsize_kmsg[$i]: ${pgsize_kmsg[$i]}, pgsize_expected[$i]: ${pgsize_expected[$i]}" + + if ((pgsize_kmsg[$i] == pgsize_expected[$i])); then + printf "[ OK ] " + else + printf "[ NG ] " + let ng++ + fi + echo "page-size of attachment at ${addr[$i]}: ${pgsize_kmsg[$i]}, expected: ${pgsize_expected[$i]}" + done + fi + done +done + +sudo rmmod xpmem.ko + +exit $ng diff --git a/test/issues/1473/xpmem_attach03.sh.in b/test/issues/1473/xpmem_attach03.sh.in new file mode 100644 index 00000000..82a8617b --- /dev/null +++ b/test/issues/1473/xpmem_attach03.sh.in @@ -0,0 +1,230 @@ +#!/usr/bin/bash + +run() { + tid=05 + ng=0 + echo "*** C${issue}T${tid} start *******************************" + echo "** xpmem testsuite" + + pushd @WITH_XPMEM_BUILD@/test + + test -e /tmp/xpmem.share && rm -f /tmp/xpmem.share + test -e /tmp/xpmem.lock && rm -f /tmp/xpmem.lock + + # create TMP_SHARE_SIZE bytes defined in xpmem_test.h + for i in `seq 0 31` ; do + echo -n 0 >> /tmp/xpmem.share + done + echo 0 > /tmp/xpmem.lock + + # Run the main test app + @WITH_MCK@/bin/mcexec $PWD/xpmem_master + + popd + + + # xpmem basic test + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_001 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_002 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_003 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_004 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_005 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_006 + sleep 3 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_007 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_008 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_009 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_010 + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/XTP_011 +} + +SCRIPT_PATH=$(readlink -m "${BASH_SOURCE[0]}") +SCRIPT_NAME="${SCRIPT_PATH##*/}" + +# prepare recorddir +. @CMAKE_INSTALL_PREFIX@/bin/common.sh +recorddir=$WORKDIR/output/$SCRIPT_NAME +[[ ! -d $recorddir ]] && mkdir -p $recorddir +recordfile=$WORKDIR/output/$SCRIPT_NAME.log + +# define patch function +. @CMAKE_INSTALL_PREFIX@/bin/util.sh +patch_and_build large_page ihk_kmsg_size || exit 1 + +# boot patched McKernel +if [[ -e ${AUTOTEST_HOME}/bin/config.sh ]]; then + ${AUTOTEST_HOME}/bin/boot.sh reboot +else + . @WITH_MCK_SRC@/test/common.sh +fi + +sudo insmod @WITH_XPMEM@/lib/modules/`uname -r`/xpmem.ko +sudo chmod og+rw /dev/xpmem + +sum_ng=0 + +issue=1259 +tid=01 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem_attach to Huge mapped memory range" +echo "** end of range is aligned with Large page size" +for pgshift in $PGSHIFT_LIST; do + ((pgshift == $PAGE_SHIFT)) && continue + + @WITH_MCK@/sbin/ihkosctl 0 clear_kmsg + log_file=$recorddir/C${issue}T${tid}_${pgshift}.log + echo pageshift: ${pgshift} + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/huge_page_xpmem ${pgshift} 2 0 > ${log_file} + @WITH_MCK@/sbin/ihkosctl 0 kmsg >> ${log_file} + + EXPECT_PGSIZE=`grep EXPECT_PAGE_SIZE ${log_file} | awk '{ print $2; }'` + + SEG_ADDR=$(grep -o "anonymous_map_addr: [^ ]* " $log_file | awk '{ print $2; }') + SEG_PGSIZE=`cat ${log_file} | awk '/OK/,/DONE/' | \ +grep -o "large_page_allocation.*${SEG_ADDR}.*" | awk '{ print $5; }'` + + XPMEM_ADDR=`grep xpmem_attachment_addr ${log_file} | awk '{ print $NF; }'` + XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $NF; }'` + + if [ "${SEG_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + echo "** [ OK ] seg_addr ($SEG_ADDR) is allocated before xpmem_attach" + else + echo "** [ NG ] seg_addr ($SEG_ADDR) is not allocated before xpmem_attach" + let ng++ + fi + if [ "${XPMEM_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + echo "** [ OK ] xpmem_addr ($XPMEM_ADDR) is allocated using large pages" + else + echo "** [ NG ] xpmem_addr ($XPMEM_ADDR) is NOT allocated using large pages" + let ng++ + fi +done + +((sum_ng += ng)) + +if [ ${ng} -eq 0 ]; then + echo "*** C${issue}T${tid}: PASSED" +else + echo "*** C${issue}T${tid}: FAILED" +fi +echo "" + +tid=02 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem_attach to Huge mapped memory range" +echo "** end of range is NOT aligned with Large page size" +for pgshift in $PGSHIFT_LIST; do + ((pgshift == $PAGE_SHIFT)) && continue + + @WITH_MCK@/sbin/ihkosctl 0 clear_kmsg + log_file=$recorddir/C${issue}T${tid}_${pgshift}.log + echo pageshift: ${pgshift} + @WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/huge_page_xpmem ${pgshift} 2 $PAGE_SIZE > ${log_file} + @WITH_MCK@/sbin/ihkosctl 0 kmsg >> ${log_file} + + EXPECT_PGSIZE=`grep EXPECT_PAGE_SIZE ${log_file} | awk '{ print $2; }'` + + SEG_ADDR=$(grep -o "anonymous_map_addr: [^ ]* " $log_file | awk '{ print $2; }') + SEG_PGSIZE=`cat ${log_file} | awk '/OK/,/DONE/' | \ +grep -o "large_page_allocation.*${SEG_ADDR}.*" | awk '{ print $5; }'` + + XPMEM_ADDR=`grep xpmem_attachment_addr ${log_file} | awk '{ print $NF; }'` + XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $NF; }'` + + if [ "${SEG_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + printf "** [ OK ] " + else + printf "** [ NG ] " + let ng++ + fi + echo "size of 1st page of segment at ${SEG_ADDR}: ${SEG_PGSIZE}, expected: ${EXPECT_PGSIZE}" + + if [ "${XPMEM_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + printf "** [ OK ] " + else + printf "** [ NG ] " + let ng++ + fi + echo "size of 1st page of attachment at ${XPMEM_ADDR}: ${XPMEM_PGSIZE}, expected: ${EXPECT_PGSIZE}" +done + +((sum_ng += ng)) + +if [ ${ng} -eq 0 ]; then + echo "*** C${issue}T${tid}: PASSED" +else + echo "*** C${issue}T${tid}: FAILED" +fi +echo "" + +tid=03 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem_attach to small mapped memory range" +@WITH_MCK@/sbin/ihkosctl 0 clear_kmsg +log_file=$recorddir/C${issue}T${tid}.log +echo pageshift: small page +@WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/huge_page_xpmem -1 2 0 > ${log_file} +@WITH_MCK@/sbin/ihkosctl 0 kmsg >> ${log_file} + +EXPECT_PGSIZE=`grep EXPECT_PAGE_SIZE ${log_file} | awk '{ print $2; }'` + +XPMEM_ADDR=`grep xpmem_attachment_addr ${log_file} | awk '{ print $NF; }'` +XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $NF; }'` + +if [ "${XPMEM_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + echo "** [ OK ] xpmem_addr ($XPMEM_ADDR) is allocated using small pages" +else + echo "** [ NG ] xpmem_addr ($XPMEM_ADDR) is NOT allocated using small pages" + ((ng++)) +fi + +((sum_ng += ng)) + +if [ ${ng} -eq 0 ]; then + echo "*** C${issue}T${tid}: PASSED" +else + echo "*** C${issue}T${tid}: FAILED" +fi +echo "" + +tid=04 +ng=0 +echo "*** C${issue}T${tid} start *******************************" +echo "** xpmem_attach to multi pagesize range" +pgshift=$(echo $PGSHIFT_LIST | awk '{print $2}') +@WITH_MCK@/sbin/ihkosctl 0 clear_kmsg +log_file=$recorddir/C${issue}T${tid}_${pgshift}.log +echo pageshift: ${pgshift} +@WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/multi_vmr_xpmem ${pgshift} 1 | tee ${log_file} +@WITH_MCK@/sbin/ihkosctl 0 kmsg >> ${log_file} + +EXPECT_PGSIZE=`grep EXPECT_PAGE_SIZE ${log_file} | awk '{ print $2; }'` + +XPMEM_ADDR=`grep xpmem_large ${log_file} | awk '{ print $NF; }'` +XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $NF; }'` + +if [ "${XPMEM_PGSIZE}" = "${EXPECT_PGSIZE}" ]; then + echo "** [ OK ] xpmem_addr ($XPMEM_ADDR) is allocated using large pages" +else + echo "** [ NG ] xpmem_addr ($XPMEM_ADDR) is NOT allocated using large pages" + let ng++ +fi + +((sum_ng += ng)) + +if [ ${ng} -eq 0 ]; then + echo "*** C${issue}T${tid}: PASSED" +else + echo "*** C${issue}T${tid}: FAILED" +fi +echo "" + +run 2>&1 | tee $recordfile +grep -E '(FAIL| NG )' $recordfile && ((sum_ng++)) + +sudo rmmod xpmem.ko + +exit $sum_ng diff --git a/test/issues/1473/xpmem_make01.c b/test/issues/1473/xpmem_make01.c new file mode 100644 index 00000000..46a9b468 --- /dev/null +++ b/test/issues/1473/xpmem_make01.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "okng.h" + +int main(int argc, char **argv) +{ + void *mem, *attach; + int ret; + int status; + pid_t pid; + xpmem_segid_t segid; + xpmem_apid_t apid; + struct xpmem_addr addr; + + START("xpmem_make size: -1\n"); + + mem = mmap(0, SZ_MEM, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_HUGETLB | (LARGE_PAGE_SHIFT << MAP_HUGE_SHIFT), -1, 0); + INTERR(mem == MAP_FAILED, "mmap failed\n"); + memset(mem, 0, SZ_MEM); + + segid = xpmem_make(0, -1, XPMEM_PERMIT_MODE, (void *)0666); + OKNG(segid != -1, "xpmem_make returned %lx\n", (unsigned long)segid); + + fflush(0); + pid = fork(); + INTERR(pid == -1, "fork failed\n"); + + if (pid == 0) { + /* Child process */ + apid = xpmem_get(segid, XPMEM_RDWR, XPMEM_PERMIT_MODE, NULL); + OKNG(apid != -1, "child: xpmem_get returned %lx\n", + (unsigned long)apid); + + addr.apid = apid; + addr.offset = (unsigned long)mem; + attach = xpmem_attach(addr, SZ_MEM, NULL); + OKNG(attach != (void *)-1, "child: xpmem_attach returned %lx\n", + (unsigned long)attach); + + *((unsigned long *)attach) = TEST_VAL; + + ret = xpmem_detach(attach); + OKNG(ret != -1, "child: xpmem_detach returned %d\n", + ret); + + fflush(0); + _exit(0); + } else { + /* Parent process */ + ret = waitpid(pid, &status, 0); + INTERR(ret == -1, "waitpid failed\n"); + + OKNG(*((unsigned long *)mem) == TEST_VAL, + "parent: TEST_VAL found\n"); + + ret = xpmem_remove(segid); + OKNG(ret != -1, "parent: xpmem_remove returned %d\n", + errno); + } + + return 0; + +out: + return 1; +} diff --git a/test/issues/1473/xpmem_make01.sh.in b/test/issues/1473/xpmem_make01.sh.in new file mode 100644 index 00000000..9edbc856 --- /dev/null +++ b/test/issues/1473/xpmem_make01.sh.in @@ -0,0 +1,8 @@ +#!/usr/bin/bash + +. @CMAKE_INSTALL_PREFIX@/bin/common.sh + +@WITH_MCK@/bin/mcexec @CMAKE_INSTALL_PREFIX@/bin/xpmem_make01 +ret=$? + +exit $ret