xpmem: Support large page attachment
Change-Id: I4d672eee1c905160ece204d278f0afd9b6d7dc01 Refs: #1259
This commit is contained in:
committed by
Ken Sato
parent
569dc33a9c
commit
a8696d811d
@@ -15,6 +15,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <uio.h>
|
#include <uio.h>
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
|
#include <bitops.h>
|
||||||
#include <rusage_private.h>
|
#include <rusage_private.h>
|
||||||
#include <ihk/debug.h>
|
#include <ihk/debug.h>
|
||||||
|
|
||||||
@@ -2049,7 +2050,7 @@ SYSCALL_DECLARE(mmap)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = do_mmap(addr, len, prot, flags, fd, off0);
|
addr = do_mmap(addr, len, prot, flags, fd, off0, 0, NULL);
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
out:
|
out:
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ int arch_map_vdso(struct process_vm *vm)
|
|||||||
flag = VR_REMOTE | VR_PROT_READ;
|
flag = VR_REMOTE | VR_PROT_READ;
|
||||||
flag |= VRFLAG_PROT_TO_MAXPROT(flag);
|
flag |= VRFLAG_PROT_TO_MAXPROT(flag);
|
||||||
ret = add_process_memory_range(vm, start, end, vdso.vvar_phys, 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){
|
if (ret != 0){
|
||||||
dkprintf("ERROR: adding memory range for tod_data\n");
|
dkprintf("ERROR: adding memory range for tod_data\n");
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -167,7 +167,7 @@ int arch_map_vdso(struct process_vm *vm)
|
|||||||
flag = VR_REMOTE | VR_PROT_READ | VR_PROT_EXEC;
|
flag = VR_REMOTE | VR_PROT_READ | VR_PROT_EXEC;
|
||||||
flag |= VRFLAG_PROT_TO_MAXPROT(flag);
|
flag |= VRFLAG_PROT_TO_MAXPROT(flag);
|
||||||
ret = add_process_memory_range(vm, start, end, vdso.vdso_physlist[0], 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) {
|
if (ret != 0) {
|
||||||
dkprintf("ERROR: adding memory range for vdso_text\n");
|
dkprintf("ERROR: adding memory range for vdso_text\n");
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <page.h>
|
#include <page.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
|
#include <bitops.h>
|
||||||
#include <rusage_private.h>
|
#include <rusage_private.h>
|
||||||
#include <ihk/debug.h>
|
#include <ihk/debug.h>
|
||||||
|
|
||||||
@@ -1791,7 +1792,7 @@ recheck:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = do_mmap(addr, len, prot, flags, fd, off0);
|
addr = do_mmap(addr, len, prot, flags, fd, off0, 0, NULL);
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
out:
|
out:
|
||||||
@@ -2120,7 +2121,7 @@ int arch_map_vdso(struct process_vm *vm)
|
|||||||
vrflags |= VR_PROT_READ | VR_PROT_EXEC;
|
vrflags |= VR_PROT_READ | VR_PROT_EXEC;
|
||||||
vrflags |= VRFLAG_PROT_TO_MAXPROT(vrflags);
|
vrflags |= VRFLAG_PROT_TO_MAXPROT(vrflags);
|
||||||
error = add_process_memory_range(vm, (intptr_t)s, (intptr_t)e,
|
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) {
|
if (error) {
|
||||||
ekprintf("ERROR: adding memory range for vdso. %d\n", error);
|
ekprintf("ERROR: adding memory range for vdso. %d\n", error);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -2152,7 +2153,8 @@ int arch_map_vdso(struct process_vm *vm)
|
|||||||
vrflags |= VR_PROT_READ;
|
vrflags |= VR_PROT_READ;
|
||||||
vrflags |= VRFLAG_PROT_TO_MAXPROT(vrflags);
|
vrflags |= VRFLAG_PROT_TO_MAXPROT(vrflags);
|
||||||
error = add_process_memory_range(vm, (intptr_t)s, (intptr_t)e,
|
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) {
|
if (error) {
|
||||||
ekprintf("ERROR: adding memory range for vvar. %d\n", error);
|
ekprintf("ERROR: adding memory range for vvar. %d\n", error);
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
|||||||
if (add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0,
|
if (add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0,
|
||||||
pn->sections[i].len > LARGE_PAGE_SIZE ?
|
pn->sections[i].len > LARGE_PAGE_SIZE ?
|
||||||
LARGE_PAGE_SHIFT : PAGE_SHIFT,
|
LARGE_PAGE_SHIFT : PAGE_SHIFT,
|
||||||
&range) != 0) {
|
NULL, &range) != 0) {
|
||||||
kprintf("ERROR: adding memory range for ELF section %i\n", i);
|
kprintf("ERROR: adding memory range for ELF section %i\n", i);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
|||||||
dkprintf("%s: args_envs: %d pages\n",
|
dkprintf("%s: args_envs: %d pages\n",
|
||||||
__func__, argenv_page_count);
|
__func__, argenv_page_count);
|
||||||
if(add_process_memory_range(vm, addr, e, args_envs_p,
|
if(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);
|
ihk_mc_free_pages_user(args_envs, argenv_page_count);
|
||||||
kprintf("ERROR: adding memory range for args/envs\n");
|
kprintf("ERROR: adding memory range for args/envs\n");
|
||||||
goto err;
|
goto err;
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#define VR_MEMTYPE_MASK 0x0f000000
|
#define VR_MEMTYPE_MASK 0x0f000000
|
||||||
#define VR_PAGEOUT 0x10000000
|
#define VR_PAGEOUT 0x10000000
|
||||||
#define VR_DONTDUMP 0x20000000
|
#define VR_DONTDUMP 0x20000000
|
||||||
|
#define VR_XPMEM 0x40000000
|
||||||
|
|
||||||
#define PROT_TO_VR_FLAG(prot) (((unsigned long)(prot) << 16) & VR_PROT_MASK)
|
#define PROT_TO_VR_FLAG(prot) (((unsigned long)(prot) << 16) & VR_PROT_MASK)
|
||||||
#define VRFLAG_PROT_TO_MAXPROT(vrflag) (((vrflag) & VR_PROT_MASK) << 4)
|
#define VRFLAG_PROT_TO_MAXPROT(vrflag) (((vrflag) & VR_PROT_MASK) << 4)
|
||||||
@@ -800,7 +801,7 @@ int add_process_memory_range(struct process_vm *vm,
|
|||||||
unsigned long start, unsigned long end,
|
unsigned long start, unsigned long end,
|
||||||
unsigned long phys, unsigned long flag,
|
unsigned long phys, unsigned long flag,
|
||||||
struct memobj *memobj, off_t offset,
|
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,
|
int remove_process_memory_range(struct process_vm *vm, unsigned long start,
|
||||||
unsigned long end, int *ro_freedp);
|
unsigned long end, int *ro_freedp);
|
||||||
int split_process_memory_range(struct process_vm *vm,
|
int split_process_memory_range(struct process_vm *vm,
|
||||||
|
|||||||
@@ -486,7 +486,7 @@ enum set_cputime_mode {
|
|||||||
void set_cputime(enum set_cputime_mode mode);
|
void set_cputime(enum set_cputime_mode mode);
|
||||||
int do_munmap(void *addr, size_t len, int holding_memory_range_lock);
|
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,
|
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);
|
void clear_host_pte(uintptr_t addr, size_t len, int holding_memory_range_lock);
|
||||||
typedef int32_t key_t;
|
typedef int32_t key_t;
|
||||||
int do_shmget(key_t key, size_t size, int shmflg);
|
int do_shmget(key_t key, size_t size, int shmflg);
|
||||||
|
|||||||
@@ -27,6 +27,20 @@ int xpmem_remove_process_memory_range(struct process_vm *vm,
|
|||||||
struct vm_range *vmr);
|
struct vm_range *vmr);
|
||||||
int xpmem_fault_process_memory_range(struct process_vm *vm,
|
int xpmem_fault_process_memory_range(struct process_vm *vm,
|
||||||
struct vm_range *vmr, unsigned long vaddr, uint64_t reason);
|
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 {
|
||||||
|
mcs_rwlock_lock_t at_lock; /* att lock */
|
||||||
|
unsigned long vaddr; /* starting address of seg attached */
|
||||||
|
unsigned long at_vaddr; /* address where seg is attached */
|
||||||
|
size_t at_size; /* size of seg attachment */
|
||||||
|
struct vm_range *at_vmr; /* vm_range where seg is attachment */
|
||||||
|
int flags; /* att attributes and state */
|
||||||
|
ihk_atomic_t refcnt; /* references to att */
|
||||||
|
struct xpmem_access_permit *ap; /* associated access permit */
|
||||||
|
struct list_head att_list; /* atts linked to access permit */
|
||||||
|
struct process_vm *vm; /* process_vm attached to */
|
||||||
|
};
|
||||||
#endif /* _XPMEM_H */
|
#endif /* _XPMEM_H */
|
||||||
|
|
||||||
|
|||||||
@@ -177,19 +177,6 @@ struct xpmem_access_permit {
|
|||||||
struct list_head ap_hashlist; /* access permit hash list */
|
struct list_head ap_hashlist; /* access permit hash list */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xpmem_attachment {
|
|
||||||
mcs_rwlock_lock_t at_lock; /* att lock */
|
|
||||||
unsigned long vaddr; /* starting address of seg attached */
|
|
||||||
unsigned long at_vaddr; /* address where seg is attached */
|
|
||||||
size_t at_size; /* size of seg attachment */
|
|
||||||
struct vm_range *at_vmr; /* vm_range where seg is attachment */
|
|
||||||
volatile int flags; /* att attributes and state */
|
|
||||||
ihk_atomic_t refcnt; /* references to att */
|
|
||||||
struct xpmem_access_permit *ap; /* associated access permit */
|
|
||||||
struct list_head att_list; /* atts linked to access permit */
|
|
||||||
struct process_vm *vm; /* process_vm attached to */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct xpmem_partition {
|
struct xpmem_partition {
|
||||||
ihk_atomic_t n_opened; /* # of /dev/xpmem opened */
|
ihk_atomic_t n_opened; /* # of /dev/xpmem opened */
|
||||||
struct xpmem_hashlist tg_hashtable[]; /* locks + tg hash lists */
|
struct xpmem_hashlist tg_hashtable[]; /* locks + tg hash lists */
|
||||||
@@ -331,6 +318,7 @@ static void xpmem_ap_deref(struct xpmem_access_permit *ap);
|
|||||||
static void xpmem_att_deref(struct xpmem_attachment *att);
|
static void xpmem_att_deref(struct xpmem_attachment *att);
|
||||||
static int xpmem_validate_access(struct xpmem_access_permit *, off_t, size_t,
|
static int xpmem_validate_access(struct xpmem_access_permit *, off_t, size_t,
|
||||||
int, unsigned long *);
|
int, unsigned long *);
|
||||||
|
static int is_remote_vm(struct process_vm *vm);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inlines that mark an internal driver structure as being destroyable or not.
|
* Inlines that mark an internal driver structure as being destroyable or not.
|
||||||
|
|||||||
@@ -1301,7 +1301,7 @@ int add_process_memory_range(struct process_vm *vm,
|
|||||||
unsigned long start, unsigned long end,
|
unsigned long start, unsigned long end,
|
||||||
unsigned long phys, unsigned long flag,
|
unsigned long phys, unsigned long flag,
|
||||||
struct memobj *memobj, off_t offset,
|
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);
|
dkprintf("%s: start=%lx,end=%lx,phys=%lx,flag=%lx\n", __FUNCTION__, start, end, phys, flag);
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
@@ -1329,7 +1329,7 @@ int add_process_memory_range(struct process_vm *vm,
|
|||||||
range->memobj = memobj;
|
range->memobj = memobj;
|
||||||
range->objoff = offset;
|
range->objoff = offset;
|
||||||
range->pgshift = pgshift;
|
range->pgshift = pgshift;
|
||||||
range->private_data = NULL;
|
range->private_data = private_data;
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
if (phys == NOPHYS) {
|
if (phys == NOPHYS) {
|
||||||
@@ -1341,6 +1341,10 @@ int add_process_memory_range(struct process_vm *vm,
|
|||||||
else if (flag & VR_IO_NOCACHE) {
|
else if (flag & VR_IO_NOCACHE) {
|
||||||
rc = update_process_page_table(vm, range, phys, PTATTR_UNCACHABLE);
|
rc = update_process_page_table(vm, range, phys, PTATTR_UNCACHABLE);
|
||||||
}
|
}
|
||||||
|
else if (flag & VR_XPMEM) {
|
||||||
|
range->memobj->flags |= MF_XPMEM;
|
||||||
|
rc = xpmem_update_process_page_table(vm, range);
|
||||||
|
}
|
||||||
else if (flag & VR_DEMAND_PAGING) {
|
else if (flag & VR_DEMAND_PAGING) {
|
||||||
dkprintf("%s: range: 0x%lx - 0x%lx is demand paging\n",
|
dkprintf("%s: range: 0x%lx - 0x%lx is demand paging\n",
|
||||||
__FUNCTION__, range->start, range->end);
|
__FUNCTION__, range->start, range->end);
|
||||||
@@ -1368,7 +1372,8 @@ int add_process_memory_range(struct process_vm *vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Clear content! */
|
/* 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)) {
|
&& ((flag & VR_PROT_MASK) != VR_PROT_NONE)) {
|
||||||
#if 1
|
#if 1
|
||||||
memset((void *)phys_to_virt(phys), 0, end - start);
|
memset((void *)phys_to_virt(phys), 0, end - start);
|
||||||
@@ -2384,7 +2389,8 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
|||||||
vrflag |= VR_MAXPROT_READ | VR_MAXPROT_WRITE | VR_MAXPROT_EXEC;
|
vrflag |= VR_MAXPROT_READ | VR_MAXPROT_WRITE | VR_MAXPROT_EXEC;
|
||||||
#define NOPHYS ((uintptr_t)-1)
|
#define NOPHYS ((uintptr_t)-1)
|
||||||
if ((rc = add_process_memory_range(thread->vm, start, end, NOPHYS,
|
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);
|
ihk_mc_free_pages_user(stack, minsz >> PAGE_SHIFT);
|
||||||
kprintf("%s: error addding process memory range: %d\n", rc);
|
kprintf("%s: error addding process memory range: %d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2548,7 +2554,7 @@ unsigned long extend_process_region(struct process_vm *vm,
|
|||||||
|
|
||||||
if ((rc = add_process_memory_range(vm, end_allocated, new_end_allocated,
|
if ((rc = add_process_memory_range(vm, end_allocated, new_end_allocated,
|
||||||
(p == 0 ? 0 : virt_to_phys(p)), flag, NULL, 0,
|
(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, (new_end_allocated - end_allocated) >> PAGE_SHIFT);
|
ihk_mc_free_pages_user(p, (new_end_allocated - end_allocated) >> PAGE_SHIFT);
|
||||||
return end_allocated;
|
return end_allocated;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1549,6 +1549,12 @@ static int search_free_space(size_t len, int pgshift, uintptr_t *addrp)
|
|||||||
/* try given addr first */
|
/* try given addr first */
|
||||||
addr = *addrp;
|
addr = *addrp;
|
||||||
if (addr != 0) {
|
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);
|
range = lookup_process_memory_range(thread->vm, addr, addr+len);
|
||||||
if (range == NULL)
|
if (range == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1584,7 +1590,8 @@ out:
|
|||||||
|
|
||||||
intptr_t
|
intptr_t
|
||||||
do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
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 thread *thread = cpu_local_var(current);
|
||||||
struct vm_regions *region = &thread->vm->region;
|
struct vm_regions *region = &thread->vm->region;
|
||||||
@@ -1643,7 +1650,8 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
|||||||
pgshift = (flags >> MAP_HUGE_SHIFT) & 0x3F;
|
pgshift = (flags >> MAP_HUGE_SHIFT) & 0x3F;
|
||||||
p2align = pgshift - PAGE_SHIFT;
|
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) {
|
&& !proc->thp_disable) {
|
||||||
pgshift = 0; /* transparent huge page */
|
pgshift = 0; /* transparent huge page */
|
||||||
p2align = PAGE_P2ALIGN;
|
p2align = PAGE_P2ALIGN;
|
||||||
@@ -1674,7 +1682,29 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
|||||||
}
|
}
|
||||||
else if (flags & MAP_ANONYMOUS) {
|
else if (flags & MAP_ANONYMOUS) {
|
||||||
/* Obtain mapping address */
|
/* Obtain mapping address */
|
||||||
error = search_free_space(len, PAGE_SHIFT + p2align, &addr);
|
if (vrf0 && VR_XPMEM) {
|
||||||
|
/* Fit address format to segment area */
|
||||||
|
struct xpmem_attachment *att;
|
||||||
|
uintptr_t prev_addr;
|
||||||
|
|
||||||
|
att = (struct xpmem_attachment *)private_data;
|
||||||
|
|
||||||
|
addr = att->vaddr;
|
||||||
|
while (!error) {
|
||||||
|
prev_addr = addr;
|
||||||
|
error = search_free_space(len,
|
||||||
|
PAGE_SHIFT + p2align, &addr);
|
||||||
|
if (prev_addr == addr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
addr = prev_addr +
|
||||||
|
(1UL << (PAGE_SHIFT + p2align));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error = search_free_space(len,
|
||||||
|
PAGE_SHIFT + p2align, &addr);
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
ekprintf("do_mmap:search_free_space(%lx,%lx,%d) failed. %d\n",
|
ekprintf("do_mmap:search_free_space(%lx,%lx,%d) failed. %d\n",
|
||||||
len, region->map_end, p2align, error);
|
len, region->map_end, p2align, error);
|
||||||
@@ -1684,12 +1714,13 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
|||||||
|
|
||||||
/* do the map */
|
/* do the map */
|
||||||
vrflags = VR_NONE;
|
vrflags = VR_NONE;
|
||||||
|
vrflags |= vrf0;
|
||||||
vrflags |= PROT_TO_VR_FLAG(prot);
|
vrflags |= PROT_TO_VR_FLAG(prot);
|
||||||
vrflags |= (flags & MAP_PRIVATE)? VR_PRIVATE: 0;
|
vrflags |= (flags & MAP_PRIVATE)? VR_PRIVATE: 0;
|
||||||
vrflags |= (flags & MAP_LOCKED)? VR_LOCKED: 0;
|
vrflags |= (flags & MAP_LOCKED)? VR_LOCKED: 0;
|
||||||
vrflags |= VR_DEMAND_PAGING;
|
vrflags |= VR_DEMAND_PAGING;
|
||||||
if (flags & MAP_ANONYMOUS) {
|
if (flags & MAP_ANONYMOUS && !anon_on_demand) {
|
||||||
if (!anon_on_demand && (flags & MAP_PRIVATE)) {
|
if (flags & MAP_PRIVATE || vrflags & VR_XPMEM) {
|
||||||
vrflags &= ~VR_DEMAND_PAGING;
|
vrflags &= ~VR_DEMAND_PAGING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1812,6 +1843,7 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
|||||||
}
|
}
|
||||||
/* Prepopulated ANONYMOUS mapping */
|
/* Prepopulated ANONYMOUS mapping */
|
||||||
else if (!(vrflags & VR_DEMAND_PAGING)
|
else if (!(vrflags & VR_DEMAND_PAGING)
|
||||||
|
&& !(flags & MAP_SHARED)
|
||||||
&& ((vrflags & VR_PROT_MASK) != VR_PROT_NONE)) {
|
&& ((vrflags & VR_PROT_MASK) != VR_PROT_NONE)) {
|
||||||
npages = len >> PAGE_SHIFT;
|
npages = len >> PAGE_SHIFT;
|
||||||
/* Small allocations mostly benefit from closest RAM,
|
/* Small allocations mostly benefit from closest RAM,
|
||||||
@@ -1890,7 +1922,7 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
|||||||
vrflags |= VRFLAG_PROT_TO_MAXPROT(PROT_TO_VR_FLAG(maxprot));
|
vrflags |= VRFLAG_PROT_TO_MAXPROT(PROT_TO_VR_FLAG(maxprot));
|
||||||
|
|
||||||
error = add_process_memory_range(thread->vm, addr, addr+len, phys,
|
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) {
|
if (error) {
|
||||||
kprintf("%s: add_process_memory_range failed for 0x%lx:%lu"
|
kprintf("%s: add_process_memory_range failed for 0x%lx:%lu"
|
||||||
" flags: %lx, vrflags: %lx, pgshift: %d, error: %d\n",
|
" flags: %lx, vrflags: %lx, pgshift: %d, error: %d\n",
|
||||||
@@ -4205,7 +4237,7 @@ perf_mmap(struct mckfd *sfd, ihk_mc_user_context_t *ctx)
|
|||||||
|
|
||||||
flags |= MAP_ANONYMOUS;
|
flags |= MAP_ANONYMOUS;
|
||||||
prot |= PROT_WRITE;
|
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
|
// setup perf_event_mmap_page
|
||||||
page = (struct perf_event_mmap_page *)rc;
|
page = (struct perf_event_mmap_page *)rc;
|
||||||
@@ -5488,7 +5520,7 @@ SYSCALL_DECLARE(shmat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
error = add_process_memory_range(vm, addr, addr+len, -1,
|
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 (error) {
|
||||||
if (!(prot & PROT_WRITE)) {
|
if (!(prot & PROT_WRITE)) {
|
||||||
(void)set_host_vma(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC, 1/* holding memory_range_lock */);
|
(void)set_host_vma(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC, 1/* holding memory_range_lock */);
|
||||||
@@ -8252,7 +8284,7 @@ SYSCALL_DECLARE(mremap)
|
|||||||
error = add_process_memory_range(thread->vm, newstart, newend, -1,
|
error = add_process_memory_range(thread->vm, newstart, newend, -1,
|
||||||
range->flag, range->memobj,
|
range->flag, range->memobj,
|
||||||
range->objoff + (oldstart - range->start),
|
range->objoff + (oldstart - range->start),
|
||||||
range->pgshift, NULL);
|
range->pgshift, NULL, NULL);
|
||||||
if (error) {
|
if (error) {
|
||||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||||
"add failed. %d\n",
|
"add failed. %d\n",
|
||||||
|
|||||||
247
kernel/xpmem.c
247
kernel/xpmem.c
@@ -423,6 +423,11 @@ static int xpmem_make(
|
|||||||
struct xpmem_thread_group *seg_tg;
|
struct xpmem_thread_group *seg_tg;
|
||||||
struct xpmem_segment *seg;
|
struct xpmem_segment *seg;
|
||||||
struct mcs_rwlock_node_irqsave lock;
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
|
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||||
|
int ret;
|
||||||
|
pte_t *seg_pte = NULL;
|
||||||
|
size_t pgsize = 0, seg_size = 0;
|
||||||
|
unsigned long pf_addr;
|
||||||
|
|
||||||
XPMEM_DEBUG("call: vaddr=0x%lx, size=0x%lx, permit_type=%d, "
|
XPMEM_DEBUG("call: vaddr=0x%lx, size=0x%lx, permit_type=%d, "
|
||||||
"permit_value=0%04lo",
|
"permit_value=0%04lo",
|
||||||
@@ -452,6 +457,27 @@ static int xpmem_make(
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Page-in segment area */
|
||||||
|
pf_addr = vaddr;
|
||||||
|
while (pf_addr < vaddr + size) {
|
||||||
|
ret = page_fault_process_vm(vm, (void *)pf_addr,
|
||||||
|
PF_POPULATE | PF_WRITE | PF_USER);
|
||||||
|
if (ret) {
|
||||||
|
xpmem_tg_deref(seg_tg);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
seg_pte = xpmem_vaddr_to_pte(vm, pf_addr, &pgsize);
|
||||||
|
if (!seg_pte || pte_is_null(seg_pte)) {
|
||||||
|
xpmem_tg_deref(seg_tg);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
pf_addr += pgsize;
|
||||||
|
seg_size += pgsize;
|
||||||
|
}
|
||||||
|
if (seg_size > size) {
|
||||||
|
size = seg_size;
|
||||||
|
}
|
||||||
|
|
||||||
segid = xpmem_make_segid(seg_tg);
|
segid = xpmem_make_segid(seg_tg);
|
||||||
if (segid < 0) {
|
if (segid < 0) {
|
||||||
xpmem_tg_deref(seg_tg);
|
xpmem_tg_deref(seg_tg);
|
||||||
@@ -1009,7 +1035,6 @@ static int xpmem_attach(
|
|||||||
struct xpmem_segment *seg;
|
struct xpmem_segment *seg;
|
||||||
struct xpmem_attachment *att;
|
struct xpmem_attachment *att;
|
||||||
struct mcs_rwlock_node_irqsave at_lock;
|
struct mcs_rwlock_node_irqsave at_lock;
|
||||||
struct vm_range *vmr;
|
|
||||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||||
|
|
||||||
XPMEM_DEBUG("call: apid=0x%lx, offset=0x%lx, size=0x%lx, vaddr=0x%lx, "
|
XPMEM_DEBUG("call: apid=0x%lx, offset=0x%lx, size=0x%lx, vaddr=0x%lx, "
|
||||||
@@ -1124,37 +1149,15 @@ static int xpmem_attach(
|
|||||||
XPMEM_DEBUG("do_mmap(): vaddr=0x%lx, size=0x%lx, prot_flags=0x%lx, "
|
XPMEM_DEBUG("do_mmap(): vaddr=0x%lx, size=0x%lx, prot_flags=0x%lx, "
|
||||||
"flags=0x%lx, fd=%d, offset=0x%lx",
|
"flags=0x%lx, fd=%d, offset=0x%lx",
|
||||||
vaddr, size, prot_flags, flags, mckfd->fd, offset);
|
vaddr, size, prot_flags, flags, mckfd->fd, offset);
|
||||||
/* The new range uses on-demand paging and is associated with shmobj because of
|
/* The new range is associated with shmobj because of
|
||||||
MAP_ANONYMOUS && !MAP_PRIVATE && MAP_SHARED */
|
MAP_ANONYMOUS && !MAP_PRIVATE && MAP_SHARED */
|
||||||
at_vaddr = do_mmap(vaddr, size, prot_flags, flags, mckfd->fd, offset);
|
at_vaddr = do_mmap(vaddr, size, prot_flags, flags, mckfd->fd,
|
||||||
|
offset, VR_XPMEM, att);
|
||||||
if (IS_ERR((void *)(uintptr_t)at_vaddr)) {
|
if (IS_ERR((void *)(uintptr_t)at_vaddr)) {
|
||||||
ret = at_vaddr;
|
ret = at_vaddr;
|
||||||
goto out_2;
|
goto out_2;
|
||||||
}
|
}
|
||||||
XPMEM_DEBUG("at_vaddr=0x%lx", at_vaddr);
|
XPMEM_DEBUG("at_vaddr=0x%lx", at_vaddr);
|
||||||
att->at_vaddr = at_vaddr;
|
|
||||||
|
|
||||||
ihk_mc_spinlock_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_mc_spinlock_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);
|
*at_vaddr_p = at_vaddr + offset_in_page(att->vaddr);
|
||||||
|
|
||||||
@@ -1180,7 +1183,6 @@ out_1:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int xpmem_detach(
|
static int xpmem_detach(
|
||||||
unsigned long at_vaddr)
|
unsigned long at_vaddr)
|
||||||
{
|
{
|
||||||
@@ -1876,6 +1878,117 @@ out_1:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xpmem_update_process_page_table(
|
||||||
|
struct process_vm *vm, struct vm_range *vmr)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
unsigned long seg_vaddr = 0;
|
||||||
|
unsigned long vaddr = vmr->start;
|
||||||
|
pte_t *pte = NULL;
|
||||||
|
pte_t *seg_pte = NULL;
|
||||||
|
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 seg_pgsize;
|
||||||
|
size_t pgsize;
|
||||||
|
|
||||||
|
XPMEM_DEBUG("call: vmr=0x%p", vmr);
|
||||||
|
|
||||||
|
att = (struct xpmem_attachment *)vmr->private_data;
|
||||||
|
if (att == NULL) {
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
xpmem_att_ref(att);
|
||||||
|
ap = att->ap;
|
||||||
|
xpmem_ap_ref(ap);
|
||||||
|
ap_tg = ap->tg;
|
||||||
|
xpmem_tg_ref(ap_tg);
|
||||||
|
|
||||||
|
if ((ap->flags & XPMEM_FLAG_DESTROYING) ||
|
||||||
|
(ap_tg->flags & XPMEM_FLAG_DESTROYING)) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto out_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_ON(cpu_local_var(current)->proc->pid != ap_tg->tgid);
|
||||||
|
DBUG_ON(ap->mode != XPMEM_RDWR);
|
||||||
|
|
||||||
|
seg = ap->seg;
|
||||||
|
xpmem_seg_ref(seg);
|
||||||
|
seg_tg = seg->tg;
|
||||||
|
xpmem_tg_ref(seg_tg);
|
||||||
|
|
||||||
|
if ((seg->flags & XPMEM_FLAG_DESTROYING) ||
|
||||||
|
(seg_tg->flags & XPMEM_FLAG_DESTROYING)) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
att->at_vaddr = vmr->start;
|
||||||
|
att->at_vmr = vmr;
|
||||||
|
|
||||||
|
if ((att->flags & XPMEM_FLAG_DESTROYING) ||
|
||||||
|
(ap_tg->flags & XPMEM_FLAG_DESTROYING) ||
|
||||||
|
(seg_tg->flags & XPMEM_FLAG_DESTROYING)) {
|
||||||
|
goto out_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
seg_vaddr = (att->vaddr & PAGE_MASK) + (vaddr - att->at_vaddr);
|
||||||
|
XPMEM_DEBUG("vaddr=%lx, seg_vaddr=%lx", vaddr, seg_vaddr);
|
||||||
|
while (vaddr < vmr->end) {
|
||||||
|
ret = xpmem_ensure_valid_page(seg, seg_vaddr);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto out_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
seg_pte = xpmem_vaddr_to_pte(seg_tg->vm, seg_vaddr,
|
||||||
|
&seg_pgsize);
|
||||||
|
|
||||||
|
if (seg_pte && !pte_is_null(seg_pte)) {
|
||||||
|
pte = xpmem_vaddr_to_pte(cpu_local_var(current)->vm,
|
||||||
|
vaddr, &pgsize);
|
||||||
|
if (pte && !pte_is_null(pte)) {
|
||||||
|
if (*seg_pte != *pte) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
ekprintf("%s: ERROR: pte mismatch: "
|
||||||
|
"0x%lx != 0x%lx\n",
|
||||||
|
__func__, *seg_pte, *pte);
|
||||||
|
}
|
||||||
|
|
||||||
|
ihk_atomic_dec(&seg->tg->n_pinned);
|
||||||
|
goto out_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = xpmem_remap_pte(vm, vmr, vaddr,
|
||||||
|
0, seg, seg_vaddr);
|
||||||
|
if (ret) {
|
||||||
|
ekprintf("%s: ERROR: xpmem_remap_pte() failed %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flush_tlb_single(vaddr);
|
||||||
|
att->flags |= XPMEM_FLAG_VALIDPTEs;
|
||||||
|
|
||||||
|
seg_vaddr += seg_pgsize;
|
||||||
|
vaddr += seg_pgsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_remap_pte(
|
static int xpmem_remap_pte(
|
||||||
struct process_vm *vm,
|
struct process_vm *vm,
|
||||||
@@ -1903,12 +2016,16 @@ static int xpmem_remap_pte(
|
|||||||
"seg_vaddr=0x%lx",
|
"seg_vaddr=0x%lx",
|
||||||
vmr, vaddr, reason, seg->segid, seg_vaddr);
|
vmr, vaddr, reason, seg->segid, seg_vaddr);
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&seg_tg->vm->memory_range_lock);
|
if (is_remote_vm(seg_tg->vm)) {
|
||||||
|
ihk_mc_spinlock_lock_noirq(&seg_tg->vm->memory_range_lock);
|
||||||
|
}
|
||||||
|
|
||||||
seg_vmr = lookup_process_memory_range(seg_tg->vm, seg_vaddr,
|
seg_vmr = lookup_process_memory_range(seg_tg->vm, seg_vaddr,
|
||||||
seg_vaddr + 1);
|
seg_vaddr + 1);
|
||||||
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&seg_tg->vm->memory_range_lock);
|
if (is_remote_vm(seg_tg->vm)) {
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&seg_tg->vm->memory_range_lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (!seg_vmr) {
|
if (!seg_vmr) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
@@ -1943,28 +2060,27 @@ static int xpmem_remap_pte(
|
|||||||
att_attr = arch_vrflag_to_ptattr(vmr->flag, reason, att_pte);
|
att_attr = arch_vrflag_to_ptattr(vmr->flag, reason, att_pte);
|
||||||
XPMEM_DEBUG("att_attr=0x%lx", att_attr);
|
XPMEM_DEBUG("att_attr=0x%lx", att_attr);
|
||||||
|
|
||||||
if (att_pte) {
|
if (att_pte && !pgsize_is_contiguous(seg_pgsize)) {
|
||||||
ret = ihk_mc_pt_set_pte(vm->address_space->page_table, att_pte,
|
ret = ihk_mc_pt_set_pte(vm->address_space->page_table, att_pte,
|
||||||
att_pgsize, seg_phys, att_attr);
|
seg_pgsize, seg_phys, att_attr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
ekprintf("%s: ERROR: ihk_mc_pt_set_pte() failed %d\n",
|
ekprintf("%s: ERROR: ihk_mc_pt_set_pte() failed %d\n",
|
||||||
__FUNCTION__, ret);
|
__func__, ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
// memory_stat_rss_add() is called by the process hosting the memory area
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = ihk_mc_pt_set_range(vm->address_space->page_table, vm,
|
ret = ihk_mc_pt_set_range(vm->address_space->page_table, vm,
|
||||||
att_pgaddr, att_pgaddr + att_pgsize, seg_phys, att_attr,
|
att_pgaddr, att_pgaddr + seg_pgsize,
|
||||||
vmr->pgshift, vmr, 0);
|
seg_phys, att_attr,
|
||||||
|
pgsize_to_pgshift(seg_pgsize), vmr, 1);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
ekprintf("%s: ERROR: ihk_mc_pt_set_range() failed %d\n",
|
ekprintf("%s: ERROR: ihk_mc_pt_set_range() failed %d\n",
|
||||||
__FUNCTION__, ret);
|
__func__, ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
// memory_stat_rss_add() is called by the process hosting the memory area
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -2024,8 +2140,7 @@ static pte_t * xpmem_vaddr_to_pte(
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
return pte;
|
||||||
return pte;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2035,37 +2150,35 @@ static int xpmem_pin_page(
|
|||||||
struct process_vm *src_vm,
|
struct process_vm *src_vm,
|
||||||
unsigned long vaddr)
|
unsigned long vaddr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
|
|
||||||
XPMEM_DEBUG("call: tgid=%d, vaddr=0x%lx", tg->tgid, vaddr);
|
XPMEM_DEBUG("call: tgid=%d, vaddr=0x%lx", tg->tgid, vaddr);
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&src_vm->memory_range_lock);
|
if (is_remote_vm(src_vm)) {
|
||||||
|
ihk_mc_spinlock_lock_noirq(&src_vm->memory_range_lock);
|
||||||
|
}
|
||||||
|
|
||||||
range = lookup_process_memory_range(src_vm, vaddr, vaddr + 1);
|
range = lookup_process_memory_range(src_vm, vaddr, vaddr + 1);
|
||||||
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&src_vm->memory_range_lock);
|
|
||||||
|
|
||||||
if (!range || range->start > vaddr) {
|
if (!range || range->start > vaddr) {
|
||||||
return -ENOENT;
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xpmem_is_private_data(range)) {
|
if (xpmem_is_private_data(range)) {
|
||||||
return -ENOENT;
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = page_fault_process_vm(src_vm, (void *)vaddr,
|
ihk_atomic_inc(&tg->n_pinned);
|
||||||
PF_POPULATE | PF_WRITE | PF_USER);
|
out:
|
||||||
if (!ret) {
|
if (is_remote_vm(src_vm)) {
|
||||||
ihk_atomic_inc(&tg->n_pinned);
|
ihk_mc_spinlock_unlock_noirq(&src_vm->memory_range_lock);
|
||||||
}
|
|
||||||
else {
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XPMEM_DEBUG("return: ret=%d", ret);
|
XPMEM_DEBUG("return: ret=%d", ret);
|
||||||
|
return ret;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2075,30 +2188,24 @@ static void xpmem_unpin_pages(
|
|||||||
unsigned long vaddr,
|
unsigned long vaddr,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
int n_pgs = (((offset_in_page(vaddr) + (size)) + (PAGE_SIZE - 1)) >>
|
|
||||||
PAGE_SHIFT);
|
|
||||||
int n_pgs_unpinned = 0;
|
int n_pgs_unpinned = 0;
|
||||||
size_t vsize = 0;
|
size_t vsize = 0;
|
||||||
|
unsigned long end = vaddr + size;
|
||||||
pte_t *pte = NULL;
|
pte_t *pte = NULL;
|
||||||
|
|
||||||
XPMEM_DEBUG("call: segid=0x%lx, vaddr=0x%lx, size=0x%lx",
|
XPMEM_DEBUG("call: segid=0x%lx, vaddr=0x%lx, size=0x%lx",
|
||||||
seg->segid, vaddr, size);
|
seg->segid, vaddr, size);
|
||||||
|
|
||||||
XPMEM_DEBUG("n_pgs=%d", n_pgs);
|
|
||||||
|
|
||||||
vaddr &= PAGE_MASK;
|
vaddr &= PAGE_MASK;
|
||||||
|
|
||||||
while (n_pgs > 0) {
|
while (vaddr < end) {
|
||||||
pte = xpmem_vaddr_to_pte(vm, vaddr, &vsize);
|
pte = xpmem_vaddr_to_pte(vm, vaddr, &vsize);
|
||||||
if (pte && !pte_is_null(pte)) {
|
if (pte && !pte_is_null(pte)) {
|
||||||
n_pgs_unpinned++;
|
n_pgs_unpinned++;
|
||||||
vaddr += PAGE_SIZE;
|
vaddr += vsize;
|
||||||
n_pgs--;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vsize = ((vaddr + vsize) & (~(vsize - 1)));
|
vaddr = ((vaddr + vsize) & (~(vsize - 1)));
|
||||||
n_pgs -= (vsize - vaddr) / PAGE_SIZE;
|
|
||||||
vaddr = vsize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2300,3 +2407,15 @@ static int xpmem_validate_access(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_remote_vm(struct process_vm *vm)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (cpu_local_var(current)->proc->vm != vm) {
|
||||||
|
/* vm is not mine */
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
187
test/issues/1259/C1259.sh
Executable file
187
test/issues/1259/C1259.sh
Executable file
@@ -0,0 +1,187 @@
|
|||||||
|
#!/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 $3; }'`
|
||||||
|
XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $5; }'`
|
||||||
|
|
||||||
|
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 $3; }'`
|
||||||
|
XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $5; }'`
|
||||||
|
|
||||||
|
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=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 $3; }'`
|
||||||
|
XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $5; }'`
|
||||||
|
|
||||||
|
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 > ${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 $3; }'`
|
||||||
|
XPMEM_PGSIZE=`grep -o "xpmem_page_attach.*${XPMEM_ADDR}.*" ${log_file} | awk '{ print $5; }'`
|
||||||
|
|
||||||
|
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
|
||||||
185
test/issues/1259/aarch64_result.log
Normal file
185
test/issues/1259/aarch64_result.log
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
*** C1259T01 start *******************************
|
||||||
|
** xpem_attach to Huge mapped memory range
|
||||||
|
** end of range is aligned with Large page size
|
||||||
|
pageshift: 21
|
||||||
|
** [ OK ] seg_addr (100000400000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (100000400000) is allocated using large pages
|
||||||
|
pageshift: 29
|
||||||
|
** [ OK ] seg_addr (100020000000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (100020000000) is allocated using large pages
|
||||||
|
pageshift: 34
|
||||||
|
** [ OK ] seg_addr (100400000000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (100400000000) is allocated using large pages
|
||||||
|
*** C1259T01: PASSED
|
||||||
|
|
||||||
|
*** C1259T02 start *******************************
|
||||||
|
** xpem_attach to Huge mapped memory range
|
||||||
|
** end of range is NOT aligned with Large page size
|
||||||
|
pageshift: 21
|
||||||
|
** [ OK ] seg_addr (100000400000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (100000400000) is allocated using large pages
|
||||||
|
pageshift: 29
|
||||||
|
** [ OK ] seg_addr (100020000000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (100020000000) is allocated using large pages
|
||||||
|
pageshift: 34
|
||||||
|
** [ OK ] seg_addr (100400000000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (100400000000) is allocated using large pages
|
||||||
|
*** C1259T02: PASSED
|
||||||
|
|
||||||
|
*** C1259T03 start *******************************
|
||||||
|
** xpem_attach to small mapped memory range
|
||||||
|
pageshift: small page
|
||||||
|
** [ OK ] xpmem_addr (100000210000) is allocated using small pages
|
||||||
|
*** C1259T03: PASSED
|
||||||
|
|
||||||
|
*** C1259T04 start *******************************
|
||||||
|
** xpem_attach to multi pagesize range
|
||||||
|
pageshift: 21
|
||||||
|
** [ OK ] xpmem_addr (100000400000) is allocated using large pages
|
||||||
|
*** C1259T04: PASSED
|
||||||
|
|
||||||
|
*** C1259T05 start *******************************
|
||||||
|
** xpmem testsuite
|
||||||
|
XPMEM version = 26003
|
||||||
|
|
||||||
|
==== test_base STARTS ====
|
||||||
|
xpmem_proc1: mypid = 10105
|
||||||
|
xpmem_proc1: sharing 262144 bytes
|
||||||
|
xpmem_proc1: segid = 200002779 at 0x100000210000
|
||||||
|
|
||||||
|
xpmem_proc2: mypid = 10303
|
||||||
|
xpmem_proc2: segid = 200002779
|
||||||
|
xpmem_proc2: attached at 0x100000210000
|
||||||
|
xpmem_proc2: adding 1 to all elems
|
||||||
|
|
||||||
|
xpmem_proc1: verifying data...done
|
||||||
|
==== test_base PASSED ====
|
||||||
|
|
||||||
|
==== test_two_attach STARTS ====
|
||||||
|
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
|
||||||
|
xpmem_proc2: attached at 0x100000210000
|
||||||
|
xpmem_proc2: attached at 0x100000250000
|
||||||
|
xpmem_proc2: adding 1 to all elems using 0x100000210000
|
||||||
|
xpmem_proc2: adding 1 to all elems using 0x100000250000
|
||||||
|
|
||||||
|
xpmem_proc1: verifying data...done
|
||||||
|
==== test_two_attach PASSED ====
|
||||||
|
|
||||||
|
==== test_two_shares STARTS ====
|
||||||
|
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
|
||||||
|
xpmem_proc2: data[0] attached at 0x100000210000
|
||||||
|
xpmem_proc2: data[1] attached at 0x100000250000
|
||||||
|
xpmem_proc2: adding 1 to all elems using 0x100000210000
|
||||||
|
xpmem_proc2: adding 1 to all elems using 0x100000250000
|
||||||
|
|
||||||
|
xpmem_proc1: verifying data...done
|
||||||
|
==== test_two_shares PASSED ====
|
||||||
|
|
||||||
|
==== test_fork STARTS ====
|
||||||
|
xpmem_proc1: mypid = 11598
|
||||||
|
xpmem_proc1: sharing 262144 bytes
|
||||||
|
xpmem_proc1: segid = 200002d4e at 0x100000210000
|
||||||
|
|
||||||
|
xpmem_proc2: mypid = 11803
|
||||||
|
xpmem_proc2: segid = 200002d4e
|
||||||
|
xpmem_proc2: attached at 0x100000220000
|
||||||
|
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
|
||||||
|
|
||||||
|
xpmem_child: hello from pid 12004
|
||||||
|
|
||||||
|
xpmem_proc1: give control back to xpmem_proc2
|
||||||
|
|
||||||
|
xpmem_proc2: adding 1 to all elems
|
||||||
|
|
||||||
|
xpmem_proc1: verifying data...done
|
||||||
|
==== test_fork PASSED ====
|
||||||
|
|
||||||
|
*** XTP_001 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get
|
||||||
|
[OK] xpmem_attach
|
||||||
|
[OK] xpmem_detach
|
||||||
|
[OK] xpmem_remove
|
||||||
|
*** XTP_001 PASSED
|
||||||
|
|
||||||
|
*** XTP_002 start ***
|
||||||
|
[OK] xpmem_make in child
|
||||||
|
[OK] xpmem_get in child
|
||||||
|
[OK] xpmem_attach in child
|
||||||
|
[OK] xpmem_detach in child
|
||||||
|
[OK] xpmem_remove in child
|
||||||
|
*** XTP_002 PASSED
|
||||||
|
|
||||||
|
*** XTP_003 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get in child
|
||||||
|
[OK] xpmem_attach in child
|
||||||
|
[OK] xpmem_detach in child
|
||||||
|
[OK] validate TEST_VAL
|
||||||
|
[OK] xpmem_remove
|
||||||
|
*** XTP_003 PASSED
|
||||||
|
|
||||||
|
*** XTP_004 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get in child
|
||||||
|
[OK] xpmem_attach in child
|
||||||
|
[OK] xpmem_detach in child
|
||||||
|
[OK] validate TEST_VAL
|
||||||
|
[OK] xpmem_remove
|
||||||
|
*** XTP_004 PASSED
|
||||||
|
|
||||||
|
*** XTP_005 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get in child
|
||||||
|
[OK] xpmem_attach in child
|
||||||
|
[OK] validate TEST_VAL
|
||||||
|
[OK] xpmem_remove
|
||||||
|
*** XTP_005 PASSED
|
||||||
|
|
||||||
|
*** XTP_006 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get in child failed (parent process exited already
|
||||||
|
*** XTP_006 PASSED
|
||||||
|
|
||||||
|
*** XTP_007 start ***
|
||||||
|
[OK] xpmem_make failed (invalid address)
|
||||||
|
[OK] xpmem_make succeed(do twice to same address)
|
||||||
|
*** XTP_007 PASSED
|
||||||
|
|
||||||
|
*** XTP_008 start ***
|
||||||
|
[OK] xpmem_get in child failed (invalid segid)
|
||||||
|
[OK] xpmem_get in child (do twice to same segid
|
||||||
|
*** XTP_008 PASSED
|
||||||
|
|
||||||
|
*** XTP_009 start ***
|
||||||
|
[OK] xpmem_attach in childi failed (invalid apid)
|
||||||
|
[OK] xpmem_attach in child succeed (do twice to same apid)
|
||||||
|
*** XTP_009 PASSED
|
||||||
|
|
||||||
|
*** XTP_010 start ***
|
||||||
|
[OK] xpmem_detach in child succeed (invalid address)
|
||||||
|
[OK] xpmem_detach in child succeed (do twice to same address)
|
||||||
|
*** XTP_010 PASSED
|
||||||
|
|
||||||
|
*** XTP_011 start ***
|
||||||
|
[OK] xpmem_remove failed (invalid segid)
|
||||||
|
[OK] xpmem_remove failed (do twice to same segid)
|
||||||
|
*** XTP_011 PASSED
|
||||||
|
|
||||||
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, pgsize * pgnum, 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;
|
||||||
|
}
|
||||||
99
test/issues/1259/large_page.patch
Normal file
99
test/issues/1259/large_page.patch
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
diff --git arch/arm64/kernel/memory.c arch/arm64/kernel/memory.c
|
||||||
|
index a84bc21..7368ada 100644
|
||||||
|
--- arch/arm64/kernel/memory.c
|
||||||
|
+++ arch/arm64/kernel/memory.c
|
||||||
|
@@ -2701,6 +2701,13 @@ 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);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// 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 +2817,17 @@ 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);
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ kprintf("%s: large_page_allocation, addr: %016lx, size: 0x%lx , phys: %lx\n",
|
||||||
|
+ __func__, base, tbl.pgsize, phys);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
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 df545e1..633e390 100644
|
||||||
|
--- arch/x86_64/kernel/memory.c
|
||||||
|
+++ arch/x86_64/kernel/memory.c
|
||||||
|
@@ -1931,6 +1931,10 @@ 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);
|
||||||
|
+
|
||||||
|
// 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);
|
||||||
|
@@ -2020,6 +2024,9 @@ 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);
|
||||||
|
+
|
||||||
|
// 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 809f5e0..cba9e5a 100644
|
||||||
|
--- kernel/process.c
|
||||||
|
+++ kernel/process.c
|
||||||
|
@@ -2059,6 +2059,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 e1d0231..c9da711 100644
|
||||||
|
--- kernel/xpmem.c
|
||||||
|
+++ kernel/xpmem.c
|
||||||
|
@@ -514,6 +514,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;
|
||||||
|
}
|
||||||
|
@@ -1994,6 +1995,8 @@ int xpmem_update_process_page_table(
|
||||||
|
flush_tlb_single(vaddr);
|
||||||
|
att->flags |= XPMEM_FLAG_VALIDPTEs;
|
||||||
|
|
||||||
|
+ kprintf("%s: xpmem_page_attach, addr: %016lx, size: 0x%lx\n",
|
||||||
|
+ __func__, vaddr, seg_pgsize);
|
||||||
|
seg_vaddr += seg_pgsize;
|
||||||
|
vaddr += seg_pgsize;
|
||||||
|
}
|
||||||
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
|
||||||
|
|
||||||
187
test/issues/1259/multi_vmr_xpmem.c
Normal file
187
test/issues/1259/multi_vmr_xpmem.c
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
#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;
|
||||||
|
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));
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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
|
||||||
178
test/issues/1259/x86_64_result.log
Normal file
178
test/issues/1259/x86_64_result.log
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
*** C1259T01 start *******************************
|
||||||
|
** xpem_attach to Huge mapped memory range
|
||||||
|
** end of range is aligned with Large page size
|
||||||
|
pageshift: 21
|
||||||
|
** [ OK ] seg_addr (2aaaab000000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (2aaaab000000) is allocated using large pages
|
||||||
|
pageshift: 30
|
||||||
|
** [ OK ] seg_addr (2aaac0000000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (2aaac0000000) is allocated using large pages
|
||||||
|
*** C1259T01: PASSED
|
||||||
|
|
||||||
|
*** C1259T02 start *******************************
|
||||||
|
** xpem_attach to Huge mapped memory range
|
||||||
|
** end of range is NOT aligned with Large page size
|
||||||
|
pageshift: 21
|
||||||
|
** [ OK ] seg_addr (2aaaab000000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (2aaaab000000) is allocated using large pages
|
||||||
|
pageshift: 30
|
||||||
|
** [ OK ] seg_addr (2aaac0000000) is allocated until xpmem_attach
|
||||||
|
** [ OK ] xpmem_addr (2aaac0000000) is allocated using large pages
|
||||||
|
*** C1259T02: PASSED
|
||||||
|
|
||||||
|
*** C1259T03 start *******************************
|
||||||
|
** xpem_attach to small mapped memory range
|
||||||
|
pageshift: small page
|
||||||
|
** [ OK ] xpmem_addr (2aaaaafee000) is allocated using small pages
|
||||||
|
*** C1259T03: PASSED
|
||||||
|
|
||||||
|
*** C1259T04 start *******************************
|
||||||
|
** xpem_attach to multi pagesize range
|
||||||
|
pageshift: 21
|
||||||
|
** [ OK ] xpmem_addr (2aaaab000000) is allocated using large pages
|
||||||
|
*** C1259T04: PASSED
|
||||||
|
|
||||||
|
*** C1259T05 start *******************************
|
||||||
|
** xpmem testsuite
|
||||||
|
XPMEM version = 26003
|
||||||
|
|
||||||
|
==== test_base STARTS ====
|
||||||
|
xpmem_proc1: mypid = 13702
|
||||||
|
xpmem_proc1: sharing 16384 bytes
|
||||||
|
xpmem_proc1: segid = 200003586 at 0x2aaaaafee000
|
||||||
|
|
||||||
|
xpmem_proc2: mypid = 14123
|
||||||
|
xpmem_proc2: segid = 200003586
|
||||||
|
xpmem_proc2: attached at 0x2aaaaafee000
|
||||||
|
xpmem_proc2: adding 1 to all elems
|
||||||
|
|
||||||
|
xpmem_proc1: verifying data...done
|
||||||
|
==== test_base PASSED ====
|
||||||
|
|
||||||
|
==== test_two_attach STARTS ====
|
||||||
|
xpmem_proc1: mypid = 14543
|
||||||
|
xpmem_proc1: sharing 16384 bytes
|
||||||
|
xpmem_proc1: segid = 2000038cf at 0x2aaaaafee000
|
||||||
|
|
||||||
|
xpmem_proc2: mypid = 14963
|
||||||
|
xpmem_proc2: segid = 2000038cf
|
||||||
|
xpmem_proc2: attached at 0x2aaaaafee000
|
||||||
|
xpmem_proc2: attached at 0x2aaaaaff2000
|
||||||
|
xpmem_proc2: adding 1 to all elems using 0x2aaaaafee000
|
||||||
|
xpmem_proc2: adding 1 to all elems using 0x2aaaaaff2000
|
||||||
|
|
||||||
|
xpmem_proc1: verifying data...done
|
||||||
|
==== test_two_attach PASSED ====
|
||||||
|
|
||||||
|
==== test_two_shares STARTS ====
|
||||||
|
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
|
||||||
|
xpmem_proc2: data[0] attached at 0x2aaaaafee000
|
||||||
|
xpmem_proc2: data[1] attached at 0x2aaaaaff2000
|
||||||
|
xpmem_proc2: adding 1 to all elems using 0x2aaaaafee000
|
||||||
|
xpmem_proc2: adding 1 to all elems using 0x2aaaaaff2000
|
||||||
|
|
||||||
|
xpmem_proc1: verifying data...done
|
||||||
|
==== test_two_shares PASSED ====
|
||||||
|
|
||||||
|
==== test_fork STARTS ====
|
||||||
|
xpmem_proc1: mypid = 16227
|
||||||
|
xpmem_proc1: sharing 16384 bytes
|
||||||
|
xpmem_proc1: segid = 200003f63 at 0x2aaaaafee000
|
||||||
|
|
||||||
|
xpmem_proc2: mypid = 16647
|
||||||
|
xpmem_proc2: segid = 200003f63
|
||||||
|
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
|
||||||
|
xpmem_proc1: give control back to xpmem_proc2
|
||||||
|
|
||||||
|
|
||||||
|
xpmem_child: hello from pid 17067
|
||||||
|
|
||||||
|
xpmem_proc2: adding 1 to all elems
|
||||||
|
|
||||||
|
xpmem_proc1: verifying data...done
|
||||||
|
==== test_fork PASSED ====
|
||||||
|
|
||||||
|
*** XTP_001 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get
|
||||||
|
[OK] xpmem_attach
|
||||||
|
[OK] xpmem_detach
|
||||||
|
[OK] xpmem_remove
|
||||||
|
*** XTP_001 PASSED
|
||||||
|
|
||||||
|
*** XTP_002 start ***
|
||||||
|
[OK] xpmem_make in child
|
||||||
|
[OK] xpmem_get in child
|
||||||
|
[OK] xpmem_attach in child
|
||||||
|
[OK] xpmem_detach in child
|
||||||
|
[OK] xpmem_remove in child
|
||||||
|
*** XTP_002 PASSED
|
||||||
|
|
||||||
|
*** XTP_003 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get in child
|
||||||
|
[OK] xpmem_attach in child
|
||||||
|
[OK] xpmem_detach in child
|
||||||
|
[OK] validate TEST_VAL
|
||||||
|
[OK] xpmem_remove
|
||||||
|
*** XTP_003 PASSED
|
||||||
|
|
||||||
|
*** XTP_004 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get in child
|
||||||
|
[OK] xpmem_attach in child
|
||||||
|
[OK] xpmem_detach in child
|
||||||
|
[OK] validate TEST_VAL
|
||||||
|
[OK] xpmem_remove
|
||||||
|
*** XTP_004 PASSED
|
||||||
|
|
||||||
|
*** XTP_005 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get in child
|
||||||
|
[OK] xpmem_attach in child
|
||||||
|
[OK] validate TEST_VAL
|
||||||
|
[OK] xpmem_remove
|
||||||
|
*** XTP_005 PASSED
|
||||||
|
|
||||||
|
*** XTP_006 start ***
|
||||||
|
[OK] xpmem_make
|
||||||
|
[OK] xpmem_get in child failed (parent process exited already
|
||||||
|
*** XTP_006 PASSED
|
||||||
|
|
||||||
|
*** XTP_007 start ***
|
||||||
|
[OK] xpmem_make failed (invalid address)
|
||||||
|
[OK] xpmem_make succeed(do twice to same address)
|
||||||
|
*** XTP_007 PASSED
|
||||||
|
|
||||||
|
*** XTP_008 start ***
|
||||||
|
[OK] xpmem_get in child failed (invalid segid)
|
||||||
|
[OK] xpmem_get in child (do twice to same segid
|
||||||
|
*** XTP_008 PASSED
|
||||||
|
|
||||||
|
*** XTP_009 start ***
|
||||||
|
[OK] xpmem_attach in childi failed (invalid apid)
|
||||||
|
[OK] xpmem_attach in child succeed (do twice to same apid)
|
||||||
|
*** XTP_009 PASSED
|
||||||
|
|
||||||
|
*** XTP_010 start ***
|
||||||
|
[OK] xpmem_detach in child succeed (invalid address)
|
||||||
|
[OK] xpmem_detach in child succeed (do twice to same address)
|
||||||
|
*** XTP_010 PASSED
|
||||||
|
|
||||||
|
*** XTP_011 start ***
|
||||||
|
[OK] xpmem_remove failed (invalid segid)
|
||||||
|
[OK] xpmem_remove failed (do twice to same segid)
|
||||||
|
*** XTP_011 PASSED
|
||||||
|
|
||||||
Reference in New Issue
Block a user