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
This commit is contained in:
committed by
Masamichi Takagi
parent
3aaa5350f0
commit
d2db639853
@ -15,6 +15,7 @@
|
||||
#include <limits.h>
|
||||
#include <uio.h>
|
||||
#include <syscall.h>
|
||||
#include <bitops.h>
|
||||
#include <rusage_private.h>
|
||||
#include <memory.h>
|
||||
#include <ihk/debug.h>
|
||||
@ -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:
|
||||
|
||||
@ -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");
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include <page.h>
|
||||
#include <limits.h>
|
||||
#include <syscall.h>
|
||||
#include <bitops.h>
|
||||
#include <rusage_private.h>
|
||||
#include <memory.h>
|
||||
#include <ihk/debug.h>
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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;
|
||||
@ -2145,6 +2146,11 @@ void mem_init(void)
|
||||
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")) {
|
||||
kprintf("Demand paging on hugetlbfs mappings enabled.\n");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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",
|
||||
|
||||
506
kernel/xpmem.c
506
kernel/xpmem.c
@ -25,6 +25,7 @@
|
||||
#include <kmalloc.h>
|
||||
#include <limits.h>
|
||||
#include <memobj.h>
|
||||
#include <process.h>
|
||||
#include <mman.h>
|
||||
#include <page.h>
|
||||
#include <string.h>
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
190
test/issues/1259/C1259.sh
Executable file
190
test/issues/1259/C1259.sh
Executable file
@ -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
|
||||
12
test/issues/1259/Makefile
Normal file
12
test/issues/1259/Makefile
Normal file
@ -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
|
||||
|
||||
104
test/issues/1259/README
Normal file
104
test/issues/1259/README
Normal file
@ -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 <mckernel>
|
||||
$ 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していることを確認。
|
||||
60
test/issues/1259/XTP_001.c
Normal file
60
test/issues/1259/XTP_001.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
76
test/issues/1259/XTP_002.c
Normal file
76
test/issues/1259/XTP_002.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
79
test/issues/1259/XTP_003.c
Normal file
79
test/issues/1259/XTP_003.c
Normal file
@ -0,0 +1,79 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
112
test/issues/1259/XTP_004.c
Normal file
112
test/issues/1259/XTP_004.c
Normal file
@ -0,0 +1,112 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
76
test/issues/1259/XTP_005.c
Normal file
76
test/issues/1259/XTP_005.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
64
test/issues/1259/XTP_006.c
Normal file
64
test/issues/1259/XTP_006.c
Normal file
@ -0,0 +1,64 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
89
test/issues/1259/XTP_007.c
Normal file
89
test/issues/1259/XTP_007.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
89
test/issues/1259/XTP_008.c
Normal file
89
test/issues/1259/XTP_008.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
92
test/issues/1259/XTP_009.c
Normal file
92
test/issues/1259/XTP_009.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
90
test/issues/1259/XTP_010.c
Normal file
90
test/issues/1259/XTP_010.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
88
test/issues/1259/XTP_011.c
Normal file
88
test/issues/1259/XTP_011.c
Normal file
@ -0,0 +1,88 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
2
test/issues/1259/aarch64_config
Normal file
2
test/issues/1259/aarch64_config
Normal file
@ -0,0 +1,2 @@
|
||||
PGSHIFT_LIST=(21 29 34)
|
||||
SMALL_PGSIZE=65536
|
||||
@ -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
|
||||
|
||||
|
||||
182
test/issues/1259/huge_page_xpmem.c
Normal file
182
test/issues/1259/huge_page_xpmem.c
Normal file
@ -0,0 +1,182 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#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: <pgshift> <pgnum> <pgoffset>\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;
|
||||
}
|
||||
117
test/issues/1259/large_page.patch
Normal file
117
test/issues/1259/large_page.patch
Normal file
@ -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,
|
||||
15
test/issues/1259/mc_run.sh
Executable file
15
test/issues/1259/mc_run.sh
Executable file
@ -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
|
||||
|
||||
190
test/issues/1259/multi_vmr_xpmem.c
Normal file
190
test/issues/1259/multi_vmr_xpmem.c
Normal file
@ -0,0 +1,190 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#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: <pgshift> <pgnum>\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;
|
||||
}
|
||||
28
test/issues/1259/util.h
Normal file
28
test/issues/1259/util.h
Normal file
@ -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
|
||||
|
||||
31
test/issues/1259/util2.h
Normal file
31
test/issues/1259/util2.h
Normal file
@ -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
|
||||
2
test/issues/1259/x86_64_config
Normal file
2
test/issues/1259/x86_64_config
Normal file
@ -0,0 +1,2 @@
|
||||
PGSHIFT_LIST=(21 30)
|
||||
SMALL_PGSIZE=4096
|
||||
@ -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
|
||||
|
||||
164
test/issues/1473/CMakeLists.txt
Normal file
164
test/issues/1473/CMakeLists.txt
Normal file
@ -0,0 +1,164 @@
|
||||
cmake_policy(SET CMP0005 NEW)
|
||||
|
||||
# Options: -DWITH_XPMEM=<XPMEM install directory>
|
||||
add_definitions(-DWITH_XPMEM=${WITH_XPMEM})
|
||||
|
||||
# Options: -DWITH_XPMEM=<XPMEM build directory>
|
||||
add_definitions(-DWITH_XPMEM_BUILD=${WITH_XPMEM_BUILD})
|
||||
|
||||
# Options: -DWITH_MCK=<McKernel install directory>
|
||||
add_definitions(-DWITH_MCK=${WITH_MCK})
|
||||
|
||||
# Options: -DWITH_MCK_SRC=<McKernel source directory>
|
||||
add_definitions(-DWITH_MCK_SRC=${WITH_MCK_SRC})
|
||||
|
||||
# not used when integrated with autotest
|
||||
# Options: -DWITH_MCK_BUILD=<McKernel build directory>
|
||||
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()
|
||||
35
test/issues/1473/README
Normal file
35
test/issues/1473/README
Normal file
@ -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 <mckernel>
|
||||
$ patch -p0 < test/issues/1473/large_page.patch
|
||||
$ (build mckernel)
|
||||
$ cd <mckernel>/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
|
||||
$ <install>/scripts/xpmem-xpmem_make01
|
||||
$ <install>/scripts/xpmem-xpmem_attach01
|
||||
$ <install>/scripts/xpmem-xpmem_attach02
|
||||
57
test/issues/1473/XTP_001.c
Normal file
57
test/issues/1473/XTP_001.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
76
test/issues/1473/XTP_002.c
Normal file
76
test/issues/1473/XTP_002.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
80
test/issues/1473/XTP_003.c
Normal file
80
test/issues/1473/XTP_003.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
111
test/issues/1473/XTP_004.c
Normal file
111
test/issues/1473/XTP_004.c
Normal file
@ -0,0 +1,111 @@
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
77
test/issues/1473/XTP_005.c
Normal file
77
test/issues/1473/XTP_005.c
Normal file
@ -0,0 +1,77 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
62
test/issues/1473/XTP_006.c
Normal file
62
test/issues/1473/XTP_006.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
91
test/issues/1473/XTP_007.c
Normal file
91
test/issues/1473/XTP_007.c
Normal file
@ -0,0 +1,91 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
91
test/issues/1473/XTP_008.c
Normal file
91
test/issues/1473/XTP_008.c
Normal file
@ -0,0 +1,91 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
92
test/issues/1473/XTP_009.c
Normal file
92
test/issues/1473/XTP_009.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
88
test/issues/1473/XTP_010.c
Normal file
88
test/issues/1473/XTP_010.c
Normal file
@ -0,0 +1,88 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
90
test/issues/1473/XTP_011.c
Normal file
90
test/issues/1473/XTP_011.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
3
test/issues/1473/aarch64.conf
Normal file
3
test/issues/1473/aarch64.conf
Normal file
@ -0,0 +1,3 @@
|
||||
PGSHIFT_LIST="16 21 29"
|
||||
PAGE_SIZE=65536
|
||||
PAGE_SHIFT=16
|
||||
19
test/issues/1473/common.sh.in
Normal file
19
test/issues/1473/common.sh.in
Normal file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/sh
|
||||
|
||||
# define WORKDIR expecting this script is on <autotest>/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
|
||||
|
||||
190
test/issues/1473/huge_page_xpmem.c
Normal file
190
test/issues/1473/huge_page_xpmem.c
Normal file
@ -0,0 +1,190 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sched.h>
|
||||
#include <xpmem.h>
|
||||
#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: <pgshift> <pgnum> <pgoffset>\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;
|
||||
}
|
||||
13
test/issues/1473/ihk_kmsg_size.patch
Normal file
13
test/issues/1473/ihk_kmsg_size.patch
Normal file
@ -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 */
|
||||
|
||||
117
test/issues/1473/large_page.patch
Normal file
117
test/issues/1473/large_page.patch
Normal file
@ -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,
|
||||
199
test/issues/1473/multi_vmr_xpmem.c
Normal file
199
test/issues/1473/multi_vmr_xpmem.c
Normal file
@ -0,0 +1,199 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sched.h>
|
||||
#include <xpmem.h>
|
||||
#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: <pgshift> <pgnum>\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;
|
||||
}
|
||||
32
test/issues/1473/okng.h
Normal file
32
test/issues/1473/okng.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __OKNG_H_INCLUDED__
|
||||
#define __OKNG_H_INCLUDED__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#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
|
||||
11
test/issues/1473/util.h
Normal file
11
test/issues/1473/util.h
Normal file
@ -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
|
||||
122
test/issues/1473/util.sh.in
Normal file
122
test/issues/1473/util.sh.in
Normal file
@ -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=$?
|
||||
}
|
||||
3
test/issues/1473/x86_64.conf
Normal file
3
test/issues/1473/x86_64.conf
Normal file
@ -0,0 +1,3 @@
|
||||
PGSHIFT_LIST=(21 30)
|
||||
PAGE_SIZE=4096
|
||||
PAGE_SHIFT=12
|
||||
143
test/issues/1473/xpmem_attach01.c
Normal file
143
test/issues/1473/xpmem_attach01.c
Normal file
@ -0,0 +1,143 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <libgen.h>
|
||||
#include <xpmem.h>
|
||||
#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 <seg_pgshift> <att_pgshift>\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;
|
||||
}
|
||||
66
test/issues/1473/xpmem_attach01.sh.in
Normal file
66
test/issues/1473/xpmem_attach01.sh.in
Normal file
@ -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
|
||||
162
test/issues/1473/xpmem_attach02.c
Normal file
162
test/issues/1473/xpmem_attach02.c
Normal file
@ -0,0 +1,162 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <libgen.h>
|
||||
#include <xpmem.h>
|
||||
#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 <small_pgshift> <large_pgshift>\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;
|
||||
}
|
||||
63
test/issues/1473/xpmem_attach02.sh.in
Normal file
63
test/issues/1473/xpmem_attach02.sh.in
Normal file
@ -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
|
||||
230
test/issues/1473/xpmem_attach03.sh.in
Normal file
230
test/issues/1473/xpmem_attach03.sh.in
Normal file
@ -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
|
||||
79
test/issues/1473/xpmem_make01.c
Normal file
79
test/issues/1473/xpmem_make01.c
Normal file
@ -0,0 +1,79 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <xpmem.h>
|
||||
#include <libgen.h>
|
||||
#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;
|
||||
}
|
||||
8
test/issues/1473/xpmem_make01.sh.in
Normal file
8
test/issues/1473/xpmem_make01.sh.in
Normal file
@ -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
|
||||
Reference in New Issue
Block a user