Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e787b731e | |||
| 612f364e6a | |||
| ceee4c379f | |||
| 36c981bc34 | |||
| fd941dad44 | |||
| 5f5b9f94d1 | |||
| 3f3c4acd71 | |||
| 00007dafaa | |||
| cbe2b2149d | |||
| 4cecde3fba | |||
| 8022a2a8c0 | |||
| 3328ce03d9 | |||
| 97b107f61c | |||
| 6f3be17c19 | |||
| dea7d00545 | |||
| 4512778569 | |||
| a7adb266ff | |||
| 2566f4f213 | |||
| ac0081eddd | |||
| d4056acfc3 | |||
| 1910543380 | |||
| 6332903f0d | |||
| 29d27b7c8d | |||
| 7136384384 | |||
| 2fe5c8de2e | |||
| e774e1b984 | |||
| 33b7414615 | |||
| 3c646e2485 | |||
| a5fcc91656 | |||
| d370e9241f | |||
| 3e254c06bf | |||
| 07537cd2e7 | |||
| a37f72da0e | |||
| ab11b168f0 | |||
| eac414d6d8 | |||
| bb725f5f50 | |||
| 5224551782 | |||
| 91146acfe5 | |||
| f64731ab34 | |||
| cd46cbd4b3 | |||
| 39780917af | |||
| 0f8f6d298e | |||
| f8e8b21f04 | |||
| 5c2f9b8239 | |||
| 1afc3d9b70 | |||
| 17a8f68d60 | |||
| 2b9a053504 | |||
| 6441aa1abb | |||
| 9b55b68934 | |||
| 83ef96a739 | |||
| b5337358cf | |||
| 2db3717e57 | |||
| 5395891966 | |||
| c32a5e261b | |||
| c0c80b71ca | |||
| d15a396d5a | |||
| e35ec09da1 | |||
| 5e44c9c9f9 | |||
| 0f6c36870c | |||
| 2ec2112cc5 | |||
| c86a38e18f | |||
| 6aa7b50e26 | |||
| c3c57940ba | |||
| 7aa2d64294 | |||
| 51fe77cdae | |||
| d5aafca1ae | |||
| 54b529c82d |
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "ihk"]
|
||||
path = ihk
|
||||
url = https://github.com/RIKEN-SysSoft/ihk.git
|
||||
[submodule "executer/user/lib/libdwarf/libdwarf"]
|
||||
path = executer/user/lib/libdwarf/libdwarf
|
||||
url = https://github.com/bgerofi/libdwarf.git
|
||||
|
||||
@ -10,7 +10,7 @@ project(mckernel C ASM)
|
||||
set(MCKERNEL_VERSION "1.7.0")
|
||||
|
||||
# See "Fedora Packaging Guidlines -- Versioning"
|
||||
set(MCKERNEL_RELEASE "0.2")
|
||||
set(MCKERNEL_RELEASE "0.3")
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
|
||||
# for rpmbuild
|
||||
@ -34,6 +34,7 @@ include(GNUInstallDirs)
|
||||
include(CMakeParseArguments)
|
||||
include(Kbuild)
|
||||
include(CheckCCompilerFlag)
|
||||
include(AutoconfHelper)
|
||||
|
||||
CHECK_C_COMPILER_FLAG(-Wno-implicit-fallthrough IMPLICIT_FALLTHROUGH)
|
||||
if(IMPLICIT_FALLTHROUGH)
|
||||
@ -119,9 +120,34 @@ find_package(PkgConfig REQUIRED)
|
||||
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON)
|
||||
|
||||
find_library(LIBRT rt)
|
||||
if (NOT LIBRT)
|
||||
message(FATAL_ERROR "error: couldn't find librt")
|
||||
endif()
|
||||
find_library(LIBNUMA numa)
|
||||
if (NOT LIBNUMA)
|
||||
message(FATAL_ERROR "error: couldn't find libnuma")
|
||||
endif()
|
||||
find_library(LIBBFD bfd)
|
||||
if (NOT LIBBFD)
|
||||
message(FATAL_ERROR "error: couldn't find libbfd")
|
||||
endif()
|
||||
find_library(LIBIBERTY iberty)
|
||||
if (NOT LIBIBERTY)
|
||||
message(FATAL_ERROR "error: couldn't find libiberty")
|
||||
endif()
|
||||
|
||||
# libdwarf-devel provides /usr/lib64/libdwarf.so
|
||||
find_library(LIBDWARF dwarf)
|
||||
|
||||
# elfutils-devel provides /usr/include/dwarf.h
|
||||
find_library(LIBEBL ebl)
|
||||
|
||||
if ((NOT LIBDWARF) OR (NOT LIBEBL))
|
||||
message("WARNING: libdwarf will be compiled locally")
|
||||
set(LIBDWARF LIBDWARF-NOTFOUND)
|
||||
set(LIBEBL LIBEBL-NOTFOUND)
|
||||
enable_language(CXX)
|
||||
endif()
|
||||
|
||||
if (ENABLE_QLMPI)
|
||||
find_package(MPI REQUIRED)
|
||||
@ -186,10 +212,14 @@ add_subdirectory(tools/crash)
|
||||
configure_file(scripts/mcreboot-smp.sh.in mcreboot.sh @ONLY)
|
||||
configure_file(scripts/mcstop+release-smp.sh.in mcstop+release.sh @ONLY)
|
||||
configure_file(scripts/mcreboot.1in mcreboot.1 @ONLY)
|
||||
configure_file(scripts/eclair-dump-backtrace.exp.in eclair-dump-backtrace.exp @ONLY)
|
||||
install(PROGRAMS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/mcreboot.sh"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/mcstop+release.sh"
|
||||
DESTINATION "${CMAKE_INSTALL_SBINDIR}")
|
||||
install(PROGRAMS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/eclair-dump-backtrace.exp"
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(FILES "scripts/irqbalance_mck.in"
|
||||
DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mcreboot.1"
|
||||
|
||||
3
NEWS.md
3
NEWS.md
@ -532,3 +532,6 @@ Restrictions on McKernel
|
||||
|
||||
24. ihk_os_getperfevent() could time-out when invoked from Fujitsu TCS
|
||||
(job-scheduler).
|
||||
|
||||
25. The behaviors of madvise and mbind are changed to do nothing and
|
||||
report success as a workaround for Fugaku.
|
||||
|
||||
@ -1279,7 +1279,7 @@ long ihk_mc_show_cpuinfo(char *buf, size_t buf_size, unsigned long read_off, int
|
||||
|
||||
/* generate strings */
|
||||
loff += scnprintf(lbuf + loff, lbuf_size - loff,
|
||||
"processor\t: %d\n", i);
|
||||
"processor\t: %d\n", cpuinfo->hwid);
|
||||
loff += scnprintf(lbuf + loff, lbuf_size - loff, "Features\t:");
|
||||
|
||||
for (j = 0; hwcap_str[j]; j++) {
|
||||
@ -1497,6 +1497,19 @@ struct thread *arch_switch_context(struct thread *prev, struct thread *next)
|
||||
}
|
||||
}
|
||||
#endif /*ENABLE_PERF*/
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
if (prev && prev->profile && prev->profile_start_ts != 0) {
|
||||
prev->profile_elapsed_ts +=
|
||||
(rdtsc() - prev->profile_start_ts);
|
||||
prev->profile_start_ts = 0;
|
||||
}
|
||||
|
||||
if (next->profile && next->profile_start_ts == 0) {
|
||||
next->profile_start_ts = rdtsc();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (likely(prev)) {
|
||||
tls_thread_switch(prev, next);
|
||||
|
||||
@ -1867,6 +1880,11 @@ int arch_cpu_read_write_register(
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
dkprintf("%s: MCCTRL_OS_CPU_%s_REGISTER: reg: 0x%lx, val: 0x%lx\n",
|
||||
__FUNCTION__,
|
||||
(op == MCCTRL_OS_CPU_READ_REGISTER ? "READ" : "WRITE"),
|
||||
desc->addr, desc->val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,6 @@ SYSCALL_HANDLED(175, geteuid)
|
||||
SYSCALL_HANDLED(176, getgid)
|
||||
SYSCALL_HANDLED(177, getegid)
|
||||
SYSCALL_HANDLED(178, gettid)
|
||||
SYSCALL_HANDLED(179, sysinfo)
|
||||
SYSCALL_DELEGATED(188, msgrcv)
|
||||
SYSCALL_DELEGATED(189, msgsnd)
|
||||
SYSCALL_DELEGATED(192, semtimedop)
|
||||
@ -143,3 +142,4 @@ SYSCALL_HANDLED(1045, signalfd)
|
||||
SYSCALL_DELEGATED(1049, stat)
|
||||
SYSCALL_DELEGATED(1060, getpgrp)
|
||||
SYSCALL_HANDLED(1062, time)
|
||||
SYSCALL_DELEGATED(1069, epoll_wait)
|
||||
|
||||
@ -310,6 +310,9 @@ void handle_interrupt_gicv3(struct pt_regs *regs)
|
||||
{
|
||||
uint64_t irqnr;
|
||||
const int from_user = interrupt_from_user(regs);
|
||||
struct cpu_local_var *v = get_this_cpu_local_var();
|
||||
//unsigned long irqflags;
|
||||
int do_check = 0;
|
||||
|
||||
irqnr = gic_read_iar();
|
||||
cpu_enable_nmi();
|
||||
@ -323,10 +326,18 @@ void handle_interrupt_gicv3(struct pt_regs *regs)
|
||||
}
|
||||
set_cputime(from_user ? CPUTIME_MODE_K2U : CPUTIME_MODE_K2K_OUT);
|
||||
|
||||
/* for migration by IPI */
|
||||
if (get_this_cpu_local_var()->flags & CPU_FLAG_NEED_MIGRATE) {
|
||||
schedule();
|
||||
//irqflags = ihk_mc_spinlock_lock(&v->runq_lock);
|
||||
/* For migration by IPI or by timesharing */
|
||||
if (v->flags &
|
||||
(CPU_FLAG_NEED_MIGRATE | CPU_FLAG_NEED_RESCHED)) {
|
||||
v->flags &= ~CPU_FLAG_NEED_RESCHED;
|
||||
do_check = 1;
|
||||
}
|
||||
//ihk_mc_spinlock_unlock(&v->runq_lock, irqflags);
|
||||
|
||||
if (do_check) {
|
||||
check_signal(0, regs, 0);
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ int ihk_mc_ikc_init_first_local(struct ihk_ikc_channel_desc *channel,
|
||||
|
||||
memset(channel, 0, sizeof(struct ihk_ikc_channel_desc));
|
||||
|
||||
mikc_queue_pages = ((4 * num_processors * MASTER_IKCQ_PKTSIZE)
|
||||
mikc_queue_pages = ((8 * num_processors * MASTER_IKCQ_PKTSIZE)
|
||||
+ (PAGE_SIZE - 1)) / PAGE_SIZE;
|
||||
|
||||
/* Place both sides in this side */
|
||||
|
||||
@ -590,7 +590,7 @@ static inline void armv8pmu_write_counter(int idx, uint32_t value)
|
||||
* count using the lower 32bits and we want an interrupt when
|
||||
* it overflows.
|
||||
*/
|
||||
uint64_t value64 = 0xffffffff00000000ULL | value;
|
||||
uint64_t value64 = (int32_t)value;
|
||||
|
||||
write_sysreg(value64, pmccntr_el0);
|
||||
}
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
#include <limits.h>
|
||||
#include <uio.h>
|
||||
#include <syscall.h>
|
||||
#include <bitops.h>
|
||||
#include <rusage_private.h>
|
||||
#include <ihk/debug.h>
|
||||
|
||||
@ -58,13 +57,34 @@ extern int num_processors;
|
||||
int obtain_clone_cpuid(cpu_set_t *cpu_set, int use_last)
|
||||
{
|
||||
int min_queue_len = -1;
|
||||
int cpu, min_cpu = -1, uti_cpu = -1;
|
||||
unsigned long irqstate;
|
||||
int cpu, min_cpu = -1;
|
||||
#if 0
|
||||
int uti_cpu = -1;
|
||||
#endif
|
||||
unsigned long irqstate = 0;
|
||||
|
||||
int start, end, step;
|
||||
|
||||
if (use_last) {
|
||||
start = num_processors - 1;
|
||||
end = -1;
|
||||
step = -1;
|
||||
}
|
||||
else {
|
||||
start = 0;
|
||||
end = num_processors;
|
||||
step = 1;
|
||||
}
|
||||
|
||||
if (!cpu_local_var(current)->proc->nr_processes) {
|
||||
irqstate = ihk_mc_spinlock_lock(&runq_reservation_lock);
|
||||
}
|
||||
else {
|
||||
irqstate = cpu_disable_interrupt_save();
|
||||
}
|
||||
|
||||
/* Find the first allowed core with the shortest run queue */
|
||||
for (cpu = 0; cpu < num_processors; ++cpu) {
|
||||
for (cpu = start; cpu != end; cpu += step) {
|
||||
struct cpu_local_var *v;
|
||||
|
||||
if (!CPU_ISSET(cpu, cpu_set))
|
||||
@ -75,11 +95,14 @@ int obtain_clone_cpuid(cpu_set_t *cpu_set, int use_last)
|
||||
dkprintf("%s: cpu=%d,runq_len=%d,runq_reserved=%d\n",
|
||||
__func__, cpu, v->runq_len, v->runq_reserved);
|
||||
if (min_queue_len == -1 ||
|
||||
v->runq_len + v->runq_reserved < min_queue_len) {
|
||||
min_queue_len = v->runq_len + v->runq_reserved;
|
||||
//v->runq_len + v->runq_reserved < min_queue_len) {
|
||||
v->runq_len < min_queue_len) {
|
||||
//min_queue_len = v->runq_len + v->runq_reserved;
|
||||
min_queue_len = v->runq_len;
|
||||
min_cpu = cpu;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Record the last tie CPU */
|
||||
if (min_cpu != cpu &&
|
||||
v->runq_len + v->runq_reserved == min_queue_len) {
|
||||
@ -88,14 +111,15 @@ int obtain_clone_cpuid(cpu_set_t *cpu_set, int use_last)
|
||||
dkprintf("%s: cpu=%d,runq_len=%d,runq_reserved=%d,min_cpu=%d,uti_cpu=%d\n",
|
||||
__func__, cpu, v->runq_len, v->runq_reserved,
|
||||
min_cpu, uti_cpu);
|
||||
#else
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&v->runq_lock);
|
||||
#if 0
|
||||
if (min_queue_len == 0)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
min_cpu = use_last ? uti_cpu : min_cpu;
|
||||
if (min_cpu != -1) {
|
||||
if (get_cpu_local_var(min_cpu)->status != CPU_STATUS_RESERVED)
|
||||
@ -104,7 +128,16 @@ int obtain_clone_cpuid(cpu_set_t *cpu_set, int use_last)
|
||||
__sync_fetch_and_add(&get_cpu_local_var(min_cpu)->runq_reserved,
|
||||
1);
|
||||
}
|
||||
#else
|
||||
__sync_fetch_and_add(&get_cpu_local_var(min_cpu)->runq_reserved, 1);
|
||||
#endif
|
||||
|
||||
if (!cpu_local_var(current)->proc->nr_processes) {
|
||||
ihk_mc_spinlock_unlock(&runq_reservation_lock, irqstate);
|
||||
}
|
||||
else {
|
||||
cpu_restore_interrupt(irqstate);
|
||||
}
|
||||
|
||||
return min_cpu;
|
||||
}
|
||||
@ -2043,7 +2076,7 @@ SYSCALL_DECLARE(mmap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
addr = do_mmap(addr, len, prot, flags, fd, off0, 0, NULL);
|
||||
addr = do_mmap(addr, len, prot, flags, fd, off0);
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
@ -2137,7 +2170,9 @@ int do_process_vm_read_writev(int pid,
|
||||
unsigned long lpage_left, rpage_left;
|
||||
unsigned long lpsize, rpsize;
|
||||
void *rva, *lva;
|
||||
#if 0
|
||||
struct vm_range *range;
|
||||
#endif
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
struct mcs_rwlock_node update_lock;
|
||||
|
||||
@ -2150,8 +2185,9 @@ int do_process_vm_read_writev(int pid,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Check if parameters are okay */
|
||||
ihk_mc_spinlock_lock_noirq(<hread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(<hread->vm->memory_range_lock);
|
||||
|
||||
range = lookup_process_memory_range(lthread->vm,
|
||||
(uintptr_t)local_iov,
|
||||
@ -2173,11 +2209,12 @@ int do_process_vm_read_writev(int pid,
|
||||
|
||||
ret = 0;
|
||||
arg_out:
|
||||
ihk_mc_spinlock_unlock_noirq(<hread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(<hread->vm->memory_range_lock);
|
||||
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (li = 0; li < liovcnt; ++li) {
|
||||
llen += local_iov[li].iov_len;
|
||||
@ -2242,7 +2279,7 @@ arg_out:
|
||||
if (pli != li) {
|
||||
struct vm_range *range;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(<hread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(<hread->vm->memory_range_lock);
|
||||
|
||||
/* Is base valid? */
|
||||
range = lookup_process_memory_range(lthread->vm,
|
||||
@ -2272,7 +2309,7 @@ arg_out:
|
||||
|
||||
ret = 0;
|
||||
pli_out:
|
||||
ihk_mc_spinlock_unlock_noirq(<hread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(<hread->vm->memory_range_lock);
|
||||
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
@ -2285,7 +2322,7 @@ pli_out:
|
||||
if (pri != ri) {
|
||||
struct vm_range *range;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&rvm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&rvm->memory_range_lock);
|
||||
|
||||
/* Is base valid? */
|
||||
range = lookup_process_memory_range(rvm,
|
||||
@ -2315,7 +2352,7 @@ pli_out:
|
||||
|
||||
ret = 0;
|
||||
pri_out:
|
||||
ihk_mc_spinlock_unlock_noirq(&rvm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&rvm->memory_range_lock);
|
||||
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
|
||||
@ -155,7 +155,7 @@ int arch_map_vdso(struct process_vm *vm)
|
||||
flag = VR_REMOTE | VR_PROT_READ;
|
||||
flag |= VRFLAG_PROT_TO_MAXPROT(flag);
|
||||
ret = add_process_memory_range(vm, start, end, vdso.vvar_phys, flag,
|
||||
NULL, 0, PAGE_SHIFT, NULL, &range);
|
||||
NULL, 0, PAGE_SHIFT, &range);
|
||||
if (ret != 0){
|
||||
dkprintf("ERROR: adding memory range for tod_data\n");
|
||||
goto exit;
|
||||
@ -167,7 +167,7 @@ int arch_map_vdso(struct process_vm *vm)
|
||||
flag = VR_REMOTE | VR_PROT_READ | VR_PROT_EXEC;
|
||||
flag |= VRFLAG_PROT_TO_MAXPROT(flag);
|
||||
ret = add_process_memory_range(vm, start, end, vdso.vdso_physlist[0], flag,
|
||||
NULL, 0, PAGE_SHIFT, NULL, &range);
|
||||
NULL, 0, PAGE_SHIFT, &range);
|
||||
if (ret != 0) {
|
||||
dkprintf("ERROR: adding memory range for vdso_text\n");
|
||||
|
||||
|
||||
@ -74,7 +74,6 @@ SYSCALL_DELEGATED(89, readlink)
|
||||
SYSCALL_HANDLED(96, gettimeofday)
|
||||
SYSCALL_HANDLED(97, getrlimit)
|
||||
SYSCALL_HANDLED(98, getrusage)
|
||||
SYSCALL_HANDLED(99, sysinfo)
|
||||
SYSCALL_HANDLED(100, times)
|
||||
SYSCALL_HANDLED(101, ptrace)
|
||||
SYSCALL_HANDLED(102, getuid)
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include <page.h>
|
||||
#include <limits.h>
|
||||
#include <syscall.h>
|
||||
#include <bitops.h>
|
||||
#include <rusage_private.h>
|
||||
#include <ihk/debug.h>
|
||||
|
||||
@ -1786,7 +1785,7 @@ recheck:
|
||||
goto out;
|
||||
}
|
||||
|
||||
addr = do_mmap(addr, len, prot, flags, fd, off0, 0, NULL);
|
||||
addr = do_mmap(addr, len, prot, flags, fd, off0);
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
@ -2115,7 +2114,7 @@ int arch_map_vdso(struct process_vm *vm)
|
||||
vrflags |= VR_PROT_READ | VR_PROT_EXEC;
|
||||
vrflags |= VRFLAG_PROT_TO_MAXPROT(vrflags);
|
||||
error = add_process_memory_range(vm, (intptr_t)s, (intptr_t)e,
|
||||
NOPHYS, vrflags, NULL, 0, PAGE_SHIFT, NULL, &range);
|
||||
NOPHYS, vrflags, NULL, 0, PAGE_SHIFT, &range);
|
||||
if (error) {
|
||||
ekprintf("ERROR: adding memory range for vdso. %d\n", error);
|
||||
goto out;
|
||||
@ -2147,8 +2146,7 @@ int arch_map_vdso(struct process_vm *vm)
|
||||
vrflags |= VR_PROT_READ;
|
||||
vrflags |= VRFLAG_PROT_TO_MAXPROT(vrflags);
|
||||
error = add_process_memory_range(vm, (intptr_t)s, (intptr_t)e,
|
||||
NOPHYS, vrflags, NULL, 0,
|
||||
PAGE_SHIFT, NULL, &range);
|
||||
NOPHYS, vrflags, NULL, 0, PAGE_SHIFT, &range);
|
||||
if (error) {
|
||||
ekprintf("ERROR: adding memory range for vvar. %d\n", error);
|
||||
goto out;
|
||||
@ -2290,7 +2288,7 @@ int do_process_vm_read_writev(int pid,
|
||||
}
|
||||
|
||||
/* Check if parameters are okay */
|
||||
ihk_mc_spinlock_lock_noirq(<hread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(<hread->vm->memory_range_lock);
|
||||
|
||||
range = lookup_process_memory_range(lthread->vm,
|
||||
(uintptr_t)local_iov,
|
||||
@ -2312,7 +2310,7 @@ int do_process_vm_read_writev(int pid,
|
||||
|
||||
ret = 0;
|
||||
arg_out:
|
||||
ihk_mc_spinlock_unlock_noirq(<hread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(<hread->vm->memory_range_lock);
|
||||
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
@ -2381,7 +2379,7 @@ arg_out:
|
||||
if (pli != li) {
|
||||
struct vm_range *range;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(<hread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(<hread->vm->memory_range_lock);
|
||||
|
||||
/* Is base valid? */
|
||||
range = lookup_process_memory_range(lthread->vm,
|
||||
@ -2411,7 +2409,7 @@ arg_out:
|
||||
|
||||
ret = 0;
|
||||
pli_out:
|
||||
ihk_mc_spinlock_unlock_noirq(<hread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(<hread->vm->memory_range_lock);
|
||||
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
@ -2424,7 +2422,7 @@ pli_out:
|
||||
if (pri != ri) {
|
||||
struct vm_range *range;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&rvm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&rvm->memory_range_lock);
|
||||
|
||||
/* Is base valid? */
|
||||
range = lookup_process_memory_range(rvm,
|
||||
@ -2454,7 +2452,7 @@ pli_out:
|
||||
|
||||
ret = 0;
|
||||
pri_out:
|
||||
ihk_mc_spinlock_unlock_noirq(&rvm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&rvm->memory_range_lock);
|
||||
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
|
||||
383
cmake/modules/AutoconfHelper.cmake
Normal file
383
cmake/modules/AutoconfHelper.cmake
Normal file
@ -0,0 +1,383 @@
|
||||
# Helper functions for translating autoconf projects. Several functions
|
||||
# are lifted from the Mono sources
|
||||
|
||||
include (CheckCSourceCompiles)
|
||||
include (CheckIncludeFile)
|
||||
include (TestBigEndian)
|
||||
include (CheckFunctionExists)
|
||||
include (CheckTypeSize)
|
||||
include (CheckCSourceRuns)
|
||||
|
||||
|
||||
# Function to get the version information from the configure.ac file in the
|
||||
# current directory. Its argument is the name of the library as passed to
|
||||
# AC_INIT. It will set the variables ${LIBNAME}_VERSION and ${LIBNAME}_SOVERSION
|
||||
function (ac_get_version libname)
|
||||
string(TOUPPER "${libname}" libname_upper)
|
||||
|
||||
# Read the relevant content from configure.ac
|
||||
file (STRINGS configure.ac tmp_configure_ac
|
||||
REGEX "${libname_upper}_[_A-Z]+=[ \\t]*[0-9]+")
|
||||
|
||||
# Product version
|
||||
string (REGEX REPLACE ".+MAJOR[_A-Z]+=([0-9]+).+MINOR[_A-Z]+=([0-9]+).+MICRO[_A-Z]+=([0-9]+).*"
|
||||
"\\1.\\2.\\3" ${libname_upper}_VERSION "${tmp_configure_ac}")
|
||||
|
||||
# Library version for libtool
|
||||
string (REGEX REPLACE ".+CURRENT=([0-9]+).+REVISION=([0-9]+).+AGE=([0-9]+).*"
|
||||
"\\1.\\2.\\3" ${libname_upper}_SOVERSION "${tmp_configure_ac}")
|
||||
|
||||
# Checks if the string needs to be displayed
|
||||
set (${libname_upper}_DISPLAYSTR_AUX
|
||||
"Found ${libname} version ${${libname_upper}_VERSION}, soversion ${${libname_upper}_SOVERSION} from configure.ac"
|
||||
)
|
||||
if ((NOT ${libname_upper}_DISPLAYSTR) OR (NOT ${libname_upper}_DISPLAYSTR STREQUAL ${libname_upper}_DISPLAYSTR_AUX))
|
||||
set (${libname_upper}_DISPLAYSTR ${${libname_upper}_DISPLAYSTR_AUX}
|
||||
CACHE INTERNAL "Version string from ${libname}" FORCE)
|
||||
message (STATUS ${${libname_upper}_DISPLAYSTR})
|
||||
endif ()
|
||||
|
||||
# Export the result to the caller
|
||||
set(${libname_upper}_VERSION "${${libname_upper}_VERSION}" PARENT_SCOPE)
|
||||
set(${libname_upper}_SOVERSION "${${libname_upper}_SOVERSION}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Also from mono's source code
|
||||
# Implementation of AC_CHECK_HEADERS
|
||||
# In addition, it also records the list of variables in the variable
|
||||
# 'autoheader_vars', and for each variable, a documentation string in the
|
||||
# variable ${var}_doc
|
||||
function(ac_check_headers)
|
||||
foreach (header ${ARGV})
|
||||
string(TOUPPER ${header} header_var)
|
||||
string(REPLACE "." "_" header_var ${header_var})
|
||||
string(REPLACE "/" "_" header_var ${header_var})
|
||||
set(header_var "HAVE_${header_var}")
|
||||
check_include_file (${header} ${header_var})
|
||||
set("${header_var}_doc" "Define to 1 if you have the <${header}> header file." PARENT_SCOPE)
|
||||
if (${header_var})
|
||||
set("${header_var}_defined" "1" PARENT_SCOPE)
|
||||
endif()
|
||||
set("${header_var}_val" "1" PARENT_SCOPE)
|
||||
set (autoheader_vars ${autoheader_vars} ${header_var})
|
||||
endforeach()
|
||||
set (autoheader_vars ${autoheader_vars} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Function taken from mono's source code
|
||||
function (ac_check_funcs)
|
||||
foreach (func ${ARGV})
|
||||
string(TOUPPER ${func} var)
|
||||
set(var "HAVE_${var}")
|
||||
set(${var})
|
||||
check_function_exists (${func} ${var})
|
||||
set("${var}_doc" "Define to 1 if you have the '${func}' function." PARENT_SCOPE)
|
||||
if (${var})
|
||||
set("${var}_defined" "1" PARENT_SCOPE)
|
||||
set(${var} yes PARENT_SCOPE)
|
||||
endif()
|
||||
set("${var}_val" "1" PARENT_SCOPE)
|
||||
set (autoheader_vars ${autoheader_vars} ${var})
|
||||
endforeach()
|
||||
set (autoheader_vars ${autoheader_vars} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Specifically, this macro checks for stdlib.h', stdarg.h',
|
||||
# string.h', and float.h'; if the system has those, it probably
|
||||
# has the rest of the ANSI C header files. This macro also checks
|
||||
# whether string.h' declares memchr' (and thus presumably the
|
||||
# other mem' functions), whether stdlib.h' declare free' (and
|
||||
# thus presumably malloc' and other related functions), and whether
|
||||
# the ctype.h' macros work on characters with the high bit set, as
|
||||
# ANSI C requires.
|
||||
function (ac_header_stdc)
|
||||
if (STDC_HEADERS)
|
||||
return()
|
||||
endif()
|
||||
message(STATUS "Looking for ANSI-C headers")
|
||||
set(code "
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *ptr;
|
||||
free((void*)1);
|
||||
ptr = memchr((void*)1, 0, 0);
|
||||
|
||||
return (int)ptr;
|
||||
}
|
||||
")
|
||||
# FIXME Check the ctype.h high bit
|
||||
CHECK_C_SOURCE_COMPILES("${code}" STDC_HEADERS)
|
||||
if (STDC_HEADERS)
|
||||
set(STDC_HEADERS 1 PARENT_SCOPE)
|
||||
message(STATUS "Looking for ANSI-C headers - found")
|
||||
else()
|
||||
message(STATUS "Looking for ANSI-C headers - not found")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
# Also from the mono sources, kind of implements AC_SYS_LARGEFILE
|
||||
function (ac_sys_largefile)
|
||||
CHECK_C_SOURCE_RUNS("
|
||||
#include <sys/types.h>
|
||||
#define BIG_OFF_T (((off_t)1<<62)-1+((off_t)1<<62))
|
||||
int main (int argc, char **argv) {
|
||||
int big_off_t=((BIG_OFF_T%2147483629==721) &&
|
||||
(BIG_OFF_T%2147483647==1));
|
||||
return big_off ? 0 : 1;
|
||||
}
|
||||
" HAVE_LARGE_FILE_SUPPORT)
|
||||
|
||||
# Check if it makes sense to define _LARGE_FILES or _FILE_OFFSET_BITS
|
||||
if (HAVE_LARGE_FILE_SUPPORT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set (_LARGE_FILE_EXTRA_SRC "
|
||||
#include <sys/types.h>
|
||||
int main (int argc, char **argv) {
|
||||
return sizeof(off_t) == 8 ? 0 : 1;
|
||||
}
|
||||
")
|
||||
CHECK_C_SOURCE_RUNS ("#define _LARGE_FILES\n${_LARGE_FILE_EXTRA_SRC}"
|
||||
HAVE_USEFUL_D_LARGE_FILES)
|
||||
if (NOT HAVE_USEFUL_D_LARGE_FILES)
|
||||
if (NOT DEFINED HAVE_USEFUL_D_FILE_OFFSET_BITS)
|
||||
set (SHOW_LARGE_FILE_WARNING TRUE)
|
||||
endif ()
|
||||
CHECK_C_SOURCE_RUNS ("#define _FILE_OFFSET_BITS 64\n${_LARGE_FILE_EXTRA_SRC}"
|
||||
HAVE_USEFUL_D_FILE_OFFSET_BITS)
|
||||
if (HAVE_USEFUL_D_FILE_OFFSET_BITS)
|
||||
set (_FILE_OFFSET_BITS 64 PARENT_SCOPE)
|
||||
elseif (SHOW_LARGE_FILE_WARNING)
|
||||
message (WARNING "No 64 bit file support through off_t available.")
|
||||
endif ()
|
||||
else ()
|
||||
set (_LARGE_FILES 1 PARENT_SCOPE)
|
||||
endif ()
|
||||
endfunction ()
|
||||
|
||||
|
||||
# Quick way to set some basic variables
|
||||
# FIXME add support for variable number of arguments: only package and version are mandatory
|
||||
# arguments are package version bug_report tarname url
|
||||
function (ac_init)
|
||||
set(package ${ARGV0})
|
||||
set(version ${ARGV1})
|
||||
set(bug_report ${ARGV2})
|
||||
set(tarname ${ARGV3})
|
||||
set(url ${ARGV4})
|
||||
set(PACKAGE_NAME "\"${package}\"" PARENT_SCOPE)
|
||||
set(PACKAGE_VERSION "\"${version}\"" PARENT_SCOPE)
|
||||
set(VERSION "\"${version}\"" PARENT_SCOPE)
|
||||
if(version)
|
||||
set(PACKAGE_STRING "\"${package} ${version}\"" PARENT_SCOPE)
|
||||
else()
|
||||
set(PACKAGE_STRING "\"${package}\"" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
set(PACKAGE_BUGREPORT "\"${bug_report}\"" PARENT_SCOPE)
|
||||
|
||||
if(NOT tarname)
|
||||
string(REGEX REPLACE "[^a-zA-Z0-9_]" "-" tarname "${package}")
|
||||
endif()
|
||||
set(PACKAGE_TARNAME "\"${tarname}\"" PARENT_SCOPE)
|
||||
|
||||
set(PACKAGE_URL "\"${url}\"" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Checks for the const keyword, defining "HAS_CONST_SUPPORT"
|
||||
# If it does not have support, defines "const" to 0 in the parent scope
|
||||
function (ac_c_const)
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"int main(int argc, char **argv){const int r = 0;return r;}"
|
||||
HAS_CONST_SUPPORT)
|
||||
if (NOT HAS_CONST_SUPPORT)
|
||||
set(const 0 PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
# Inline keyword support. Defines "inline" in the parent scope to the
|
||||
# compiler internal keyword for inline in C
|
||||
# TODO write a better test!
|
||||
function (ac_c_inline)
|
||||
if (MSVC)
|
||||
set (inline __inline)
|
||||
elseif(CMAKE_COMPILER_IS_GNUC)
|
||||
set (inline __inline__)
|
||||
endif()
|
||||
set(inline "${inline}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Test if you can safely include both <sys/time.h> and <time.h>
|
||||
function (ac_header_time)
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"#include <sys/time.h>\n#include <time.h>\nint main(int argc, char **argv) { return 0; }"
|
||||
TIME_WITH_SYS_TIME)
|
||||
set(TIME_WITH_SYS_TIME ${TIME_WITH_SYS_TIME} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
|
||||
# (Intel), setting "WORDS_BIGENDIAN" to 1 if big endian
|
||||
function (ac_c_bigendian)
|
||||
TEST_BIG_ENDIAN(HOST_BIGENDIAN)
|
||||
if (HOST_BIGENDIAN)
|
||||
set(WORDS_BIGENDIAN 1 PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
# Check for off_t, setting "off_t" in the parent scope
|
||||
function(ac_type_off_t)
|
||||
CHECK_TYPE_SIZE("off_t" SIZEOF_OFF_T)
|
||||
if (NOT SIZEOF_OFF_T)
|
||||
set(off_t "long int")
|
||||
endif()
|
||||
set(off_t ${off_t} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Check for size_t, setting "size_t" in the parent scope
|
||||
function(ac_type_size_t)
|
||||
CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T)
|
||||
if (NOT SIZEOF_SIZE_T)
|
||||
set(size_t "unsigned int")
|
||||
endif()
|
||||
set(size_t ${size_t} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Define "TM_IN_SYS_TIME" to 1 if <sys/time.h> declares "struct tm"
|
||||
function(ac_struct_tm)
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"#include <sys/time.h>\nint main(int argc, char **argv) { struct tm x; return 0; }"
|
||||
TM_IN_SYS_TIME
|
||||
)
|
||||
if (TM_IN_SYS_TIME)
|
||||
set (TM_IN_SYS_TIME 1 PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
# Obtain size of an 'type' and define as SIZEOF_TYPE
|
||||
function (ac_check_sizeof typename)
|
||||
string(TOUPPER "SIZEOF_${typename}" varname)
|
||||
string(REPLACE " " "_" varname "${varname}")
|
||||
string(REPLACE "*" "p" varname "${varname}")
|
||||
CHECK_TYPE_SIZE("${typename}" ${varname} BUILTIN_TYPES_ONLY)
|
||||
if(NOT ${varname})
|
||||
set(${varname} 0 PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
# Check if the type exists, defines HAVE_<type>
|
||||
function (ac_check_type typename)
|
||||
string(TOUPPER "${typename}" varname)
|
||||
string(REPLACE " " "_" varname "${varname}")
|
||||
string(REPLACE "*" "p" varname "${varname}")
|
||||
CHECK_TYPE_SIZE("${typename}" ${varname})
|
||||
if (NOT "${varname}" STREQUAL "")
|
||||
set("HAVE_${varname}" 1 PARENT_SCOPE)
|
||||
set("${varname}" "${typename}" PARENT_SCOPE)
|
||||
else()
|
||||
set("${varname}" "unknown" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
# Verifies if each type on the list exists, using the given prelude
|
||||
function (ac_check_types type_list prelude)
|
||||
foreach(typename ${type_list})
|
||||
string(TOUPPER "HAVE_${typename}" varname)
|
||||
string(REPLACE " " "_" varname "${varname}")
|
||||
string(REPLACE "*" "p" varname "${varname}")
|
||||
CHECK_C_SOURCE_COMPILES("${prelude}\n ${typename} foo;" ${varname})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(ac_path_prog variable prog_to_check_for value_if_not_found env_var)
|
||||
find_program(${variable} NAMES ${prog_to_check_for} PATHS ENV ${env_var} NO_DEFAULT_PATH)
|
||||
if(NOT ${variable})
|
||||
message(STATUS "Looking for ${prog_to_check_for} - not found")
|
||||
set(${variable} ${value_if_not_fount} PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Looking for ${prog_to_check_for} - ${variable}")
|
||||
set(${variable} ${${variable}} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# check if function func exists in library lib
|
||||
function(ac_check_lib lib func)
|
||||
string(TOUPPER "HAVE_${func}" varname)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${lib})
|
||||
check_function_exists(${func} ${varname})
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endfunction()
|
||||
|
||||
# check if source compiles without linking
|
||||
function(ac_try_compile SOURCE VAR)
|
||||
set(CMAKE_TMP_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp)
|
||||
if(NOT DEFINED "${VAR}")
|
||||
file(WRITE
|
||||
"${CMAKE_TMP_DIR}/src.c"
|
||||
"${SOURCE}\n"
|
||||
)
|
||||
|
||||
if(NOT CMAKE_REQUIRED_QUIET)
|
||||
message(STATUS "Performing Test ${VAR}")
|
||||
endif()
|
||||
# Set up CMakeLists.txt for static library:
|
||||
file(WRITE
|
||||
${CMAKE_TMP_DIR}/CMakeLists.txt
|
||||
"add_library(compile STATIC src.c)"
|
||||
)
|
||||
|
||||
# Configure:
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||
WORKING_DIRECTORY ${CMAKE_TMP_DIR}
|
||||
)
|
||||
|
||||
# Build:
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_TMP_DIR}
|
||||
RESULT_VARIABLE RESVAR
|
||||
OUTPUT_VARIABLE OUTPUT
|
||||
ERROR_VARIABLE OUTPUT
|
||||
)
|
||||
|
||||
# Set up result:
|
||||
if(RESVAR EQUAL 0)
|
||||
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
|
||||
if(NOT CMAKE_REQUIRED_QUIET)
|
||||
message(STATUS "Performing Test ${VAR} - Success")
|
||||
endif()
|
||||
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Source file was:\n${SOURCE}\n")
|
||||
else()
|
||||
if(NOT CMAKE_REQUIRED_QUIET)
|
||||
message(STATUS "Performing Test ${VAR} - Failed")
|
||||
endif()
|
||||
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Source file was:\n${SOURCE}\n")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
64
cmake/modules/FindLibElf.cmake
Normal file
64
cmake/modules/FindLibElf.cmake
Normal file
@ -0,0 +1,64 @@
|
||||
# - Try to find libelf
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBELF_FOUND - system has libelf
|
||||
# LIBELF_INCLUDE_DIRS - the libelf include directory
|
||||
# LIBELF_LIBRARIES - Link these to use libelf
|
||||
# LIBELF_DEFINITIONS - Compiler switches required for using libelf
|
||||
#
|
||||
# This module reads hints about search locations from variables:
|
||||
#
|
||||
# LIBELF_ROOT - Preferred installation prefix
|
||||
#
|
||||
# Copyright (c) 2008 Bernhard Walle <bernhard.walle@gmx.de>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (LIBELF_LIBRARIES AND LIBELF_INCLUDE_DIRS)
|
||||
set (LibElf_FIND_QUIETLY TRUE)
|
||||
endif (LIBELF_LIBRARIES AND LIBELF_INCLUDE_DIRS)
|
||||
|
||||
find_path (LIBELF_INCLUDE_DIRS
|
||||
NAMES
|
||||
libelf/libelf.h libelf.h
|
||||
HINTS
|
||||
${LIBELF_ROOT}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
libelf/include
|
||||
)
|
||||
|
||||
find_library (LIBELF_LIBRARIES
|
||||
NAMES
|
||||
elf libelf
|
||||
HINTS
|
||||
${LIBELF_ROOT}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
libelf/lib
|
||||
)
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set LIBELF_FOUND to TRUE if all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibElf DEFAULT_MSG
|
||||
LIBELF_LIBRARIES
|
||||
LIBELF_INCLUDE_DIRS)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES elf)
|
||||
include(CheckCXXSourceCompiles)
|
||||
check_cxx_source_compiles("#include <libelf.h>
|
||||
int main() {
|
||||
Elf *e = (Elf*)0;
|
||||
size_t sz;
|
||||
elf_getshdrstrndx(e, &sz);
|
||||
return 0;
|
||||
}" ELF_GETSHDRSTRNDX)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBELF_INCLUDE_DIRS LIBELF_LIBRARIES ELF_GETSHDRSTRNDX)
|
||||
@ -92,7 +92,6 @@ struct program_image_section {
|
||||
struct get_cpu_set_arg {
|
||||
int nr_processes;
|
||||
int *process_rank;
|
||||
pid_t ppid;
|
||||
void *cpu_set;
|
||||
size_t cpu_set_size; // Size in bytes
|
||||
int *target_core;
|
||||
|
||||
@ -587,14 +587,13 @@ extern int mckernel_cpu_2_linux_cpu(struct mcctrl_usrdata *udp, int cpu_id);
|
||||
static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
|
||||
{
|
||||
struct mcctrl_usrdata *udp = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_part_exec *pe = NULL, *pe_itr;
|
||||
struct mcctrl_part_exec *pe;
|
||||
struct get_cpu_set_arg req;
|
||||
struct mcctrl_cpu_topology *cpu_top, *cpu_top_i;
|
||||
struct cache_topology *cache_top;
|
||||
int cpu, cpus_assigned, cpus_to_assign, cpu_prev;
|
||||
int ret = 0;
|
||||
int mcexec_linux_numa;
|
||||
int pe_list_len = 0;
|
||||
cpumask_t *mcexec_cpu_set = NULL;
|
||||
cpumask_t *cpus_used = NULL;
|
||||
cpumask_t *cpus_to_use = NULL;
|
||||
@ -614,55 +613,25 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(&req, (void *)arg, sizeof(req))) {
|
||||
pr_err("%s: error copying user request\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto put_out;
|
||||
}
|
||||
|
||||
mutex_lock(&udp->part_exec_lock);
|
||||
/* Find part_exec having same node_proxy */
|
||||
list_for_each_entry_reverse(pe_itr, &udp->part_exec_list, chain) {
|
||||
pe_list_len++;
|
||||
if (pe_itr->node_proxy_pid == req.ppid) {
|
||||
pe = pe_itr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pe) {
|
||||
/* First process to enter CPU partitioning */
|
||||
pr_debug("%s: pe_list_len:%d\n", __func__, pe_list_len);
|
||||
if (pe_list_len >= PE_LIST_MAXLEN) {
|
||||
/* delete head entry of pe_list */
|
||||
pe_itr = list_first_entry(&udp->part_exec_list,
|
||||
struct mcctrl_part_exec, chain);
|
||||
list_del(&pe_itr->chain);
|
||||
kfree(pe_itr);
|
||||
}
|
||||
|
||||
pe = kzalloc(sizeof(struct mcctrl_part_exec), GFP_KERNEL);
|
||||
if (!pe) {
|
||||
mutex_unlock(&udp->part_exec_lock);
|
||||
ret = -ENOMEM;
|
||||
goto put_out;
|
||||
}
|
||||
/* Init part_exec */
|
||||
mutex_init(&pe->lock);
|
||||
INIT_LIST_HEAD(&pe->pli_list);
|
||||
pe->nr_processes = req.nr_processes;
|
||||
pe->nr_processes_left = req.nr_processes;
|
||||
pe->nr_processes_joined = 0;
|
||||
pe->node_proxy_pid = req.ppid;
|
||||
|
||||
list_add_tail(&pe->chain, &udp->part_exec_list);
|
||||
dprintk("%s: nr_processes: %d (partitioned exec starts)\n",
|
||||
__func__, pe->nr_processes);
|
||||
}
|
||||
mutex_unlock(&udp->part_exec_lock);
|
||||
pe = &udp->part_exec;
|
||||
|
||||
mutex_lock(&pe->lock);
|
||||
|
||||
if (copy_from_user(&req, (void *)arg, sizeof(req))) {
|
||||
printk("%s: error copying user request\n", __FUNCTION__);
|
||||
ret = -EINVAL;
|
||||
goto put_and_unlock_out;
|
||||
}
|
||||
|
||||
/* First process to enter CPU partitioning */
|
||||
if (pe->nr_processes == -1) {
|
||||
pe->nr_processes = req.nr_processes;
|
||||
pe->nr_processes_left = req.nr_processes;
|
||||
dprintk("%s: nr_processes: %d (partitioned exec starts)\n",
|
||||
__FUNCTION__,
|
||||
pe->nr_processes);
|
||||
}
|
||||
|
||||
if (pe->nr_processes != req.nr_processes) {
|
||||
printk("%s: error: requested number of processes"
|
||||
" doesn't match current partitioned execution\n",
|
||||
@ -671,15 +640,7 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
|
||||
goto put_and_unlock_out;
|
||||
}
|
||||
|
||||
if (pe->nr_processes_joined >= pe->nr_processes) {
|
||||
printk("%s: too many processes have joined to the group of %d\n",
|
||||
__func__, req.ppid);
|
||||
ret = -EINVAL;
|
||||
goto put_and_unlock_out;
|
||||
}
|
||||
|
||||
--pe->nr_processes_left;
|
||||
++pe->nr_processes_joined;
|
||||
dprintk("%s: nr_processes: %d, nr_processes_left: %d\n",
|
||||
__FUNCTION__,
|
||||
pe->nr_processes,
|
||||
@ -765,6 +726,8 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
|
||||
wake_up_interruptible(&pli_next->pli_wq);
|
||||
}
|
||||
|
||||
/* Reset process counter to start state */
|
||||
pe->nr_processes = -1;
|
||||
ret = -ETIMEDOUT;
|
||||
goto put_and_unlock_out;
|
||||
}
|
||||
@ -1012,8 +975,16 @@ next_cpu:
|
||||
/* Commit used cores to OS structure */
|
||||
memcpy(&pe->cpus_used, cpus_used, sizeof(*cpus_used));
|
||||
|
||||
/* If not last process, wake up next process in list */
|
||||
if (pe->nr_processes_left != 0) {
|
||||
/* Reset if last process */
|
||||
if (pe->nr_processes_left == 0) {
|
||||
dprintk("%s: nr_processes: %d (partitioned exec ends)\n",
|
||||
__FUNCTION__,
|
||||
pe->nr_processes);
|
||||
pe->nr_processes = -1;
|
||||
memset(&pe->cpus_used, 0, sizeof(pe->cpus_used));
|
||||
}
|
||||
/* Otherwise wake up next process in list */
|
||||
else {
|
||||
++pe->process_rank;
|
||||
pli_next = list_first_entry(&pe->pli_list,
|
||||
struct process_list_item, list);
|
||||
@ -1026,14 +997,11 @@ next_cpu:
|
||||
ret = 0;
|
||||
|
||||
put_and_unlock_out:
|
||||
mutex_unlock(&pe->lock);
|
||||
|
||||
put_out:
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
|
||||
kfree(cpus_to_use);
|
||||
kfree(cpus_used);
|
||||
kfree(mcexec_cpu_set);
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
mutex_unlock(&pe->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1237,7 +1205,7 @@ int mcexec_syscall(struct mcctrl_usrdata *ud, struct ikc_scd_packet *packet)
|
||||
ppd = mcctrl_get_per_proc_data(ud, pid);
|
||||
|
||||
if (unlikely(!ppd)) {
|
||||
kprintf("%s: ERROR: no per-process structure for PID %d, "
|
||||
dprintk("%s: ERROR: no per-process structure for PID %d, "
|
||||
"syscall nr: %lu\n",
|
||||
__FUNCTION__, pid, packet->req.number);
|
||||
|
||||
@ -1452,7 +1420,7 @@ retry_alloc:
|
||||
__FUNCTION__, task_pid_vnr(current), packet->ref);
|
||||
|
||||
mb();
|
||||
if (!packet->req.valid) {
|
||||
if (!smp_load_acquire(&packet->req.valid)) {
|
||||
printk("%s: ERROR: stray wakeup pid: %d, tid: %d: SC %lu\n",
|
||||
__FUNCTION__,
|
||||
task_tgid_vnr(current),
|
||||
@ -1462,7 +1430,7 @@ retry_alloc:
|
||||
goto retry;
|
||||
}
|
||||
|
||||
packet->req.valid = 0; /* ack */
|
||||
smp_store_release(&packet->req.valid, 0); /* ack */
|
||||
dprintk("%s: system call: %d, args[0]: %lu, args[1]: %lu, args[2]: %lu, "
|
||||
"args[3]: %lu, args[4]: %lu, args[5]: %lu\n",
|
||||
__FUNCTION__,
|
||||
@ -3399,14 +3367,6 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Per-CPU register manipulation functions */
|
||||
struct mcctrl_os_cpu_response {
|
||||
int done;
|
||||
unsigned long val;
|
||||
int err;
|
||||
wait_queue_head_t wq;
|
||||
};
|
||||
|
||||
int mcctrl_get_request_os_cpu(ihk_os_t os, int *ret_cpu)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata;
|
||||
@ -3470,31 +3430,14 @@ out_put_ppd:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mcctrl_os_read_write_cpu_response(ihk_os_t os,
|
||||
struct ikc_scd_packet *pisp)
|
||||
{
|
||||
struct mcctrl_os_cpu_response *resp;
|
||||
|
||||
/* XXX: What if caller thread is unblocked by a signal
|
||||
* before this message arrives? */
|
||||
resp = pisp->resp;
|
||||
if (!resp) {
|
||||
return;
|
||||
}
|
||||
|
||||
resp->val = pisp->desc.val;
|
||||
resp->done = 1;
|
||||
resp->err = pisp->err;
|
||||
wake_up_interruptible(&resp->wq);
|
||||
}
|
||||
|
||||
int __mcctrl_os_read_write_cpu_register(ihk_os_t os, int cpu,
|
||||
struct ihk_os_cpu_register *desc,
|
||||
enum mcctrl_os_cpu_operation op)
|
||||
{
|
||||
struct mcctrl_usrdata *udp = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct mcctrl_os_cpu_response resp;
|
||||
struct ihk_os_cpu_register *ldesc = NULL;
|
||||
int do_free = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!udp) {
|
||||
@ -3511,50 +3454,43 @@ int __mcctrl_os_read_write_cpu_register(ihk_os_t os, int cpu,
|
||||
|
||||
}
|
||||
|
||||
/* Keep a dynamic structure around that can
|
||||
* survive an early return due to a signal */
|
||||
ldesc = kmalloc(sizeof(*ldesc), GFP_KERNEL);
|
||||
if (!ldesc) {
|
||||
printk("%s: ERROR: allocating cpu register desc\n", __FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
*ldesc = *desc;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_CPU_RW_REG;
|
||||
isp.op = op;
|
||||
isp.desc = *desc;
|
||||
isp.resp = &resp;
|
||||
isp.pdesc = virt_to_phys(ldesc);
|
||||
|
||||
resp.done = 0;
|
||||
resp.err = 0;
|
||||
init_waitqueue_head(&resp.wq);
|
||||
|
||||
mb();
|
||||
ret = mcctrl_ikc_send(os, cpu, &isp);
|
||||
if (ret < 0) {
|
||||
ret = mcctrl_ikc_send_wait(os, cpu, &isp, 0, NULL, &do_free, 1, ldesc);
|
||||
if (ret != 0) {
|
||||
printk("%s: ERROR sending IKC msg: %d\n", __FUNCTION__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wait for response */
|
||||
ret = wait_event_interruptible(resp.wq, resp.done);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = resp.err;
|
||||
if (ret != 0) {
|
||||
printk("%s: ERROR receive: %d\n", __FUNCTION__, resp.err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Update if read */
|
||||
if (ret == 0 && op == MCCTRL_OS_CPU_READ_REGISTER) {
|
||||
desc->val = resp.val;
|
||||
if (op == MCCTRL_OS_CPU_READ_REGISTER) {
|
||||
desc->val = ldesc->val;
|
||||
}
|
||||
|
||||
/* Notify caller (for future async implementation) */
|
||||
atomic_set(&desc->sync, 1);
|
||||
|
||||
dprintk("%s: MCCTRL_OS_CPU_%s_REGISTER: reg: 0x%lx, val: 0x%lx\n",
|
||||
dprintk("%s: MCCTRL_OS_CPU_%s_REGISTER: CPU: %d, addr_ext: 0x%lx, val: 0x%lx\n",
|
||||
__FUNCTION__,
|
||||
(op == MCCTRL_OS_CPU_READ_REGISTER ? "READ" : "WRITE"),
|
||||
desc->addr, desc->val);
|
||||
(op == MCCTRL_OS_CPU_READ_REGISTER ? "READ" : "WRITE"), cpu,
|
||||
desc->addr_ext, desc->val);
|
||||
|
||||
out:
|
||||
if (do_free) {
|
||||
kfree(ldesc);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -209,6 +209,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
case SCD_MSG_SEND_SIGNAL_ACK:
|
||||
case SCD_MSG_PROCFS_ANSWER:
|
||||
case SCD_MSG_REMOTE_PAGE_FAULT_ANSWER:
|
||||
case SCD_MSG_CPU_RW_REG_RESP:
|
||||
mcctrl_wakeup_cb(__os, pisp);
|
||||
break;
|
||||
|
||||
@ -239,10 +240,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
get_vdso_info(__os, pisp->arg);
|
||||
break;
|
||||
|
||||
case SCD_MSG_CPU_RW_REG_RESP:
|
||||
mcctrl_os_read_write_cpu_response(__os, pisp);
|
||||
break;
|
||||
|
||||
case SCD_MSG_EVENTFD:
|
||||
dkprintf("%s: SCD_MSG_EVENTFD,pisp->eventfd_type=%d\n", __FUNCTION__, pisp->eventfd_type);
|
||||
mcctrl_eventfd(__os, pisp);
|
||||
@ -465,7 +462,7 @@ int prepare_ikc_channels(ihk_os_t os)
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
usrdata = kzalloc(sizeof(struct mcctrl_usrdata), GFP_KERNEL);
|
||||
usrdata = kzalloc(sizeof(struct mcctrl_usrdata), GFP_ATOMIC);
|
||||
if (!usrdata) {
|
||||
printk("%s: error: allocating mcctrl_usrdata\n", __FUNCTION__);
|
||||
ret = -ENOMEM;
|
||||
@ -491,7 +488,7 @@ int prepare_ikc_channels(ihk_os_t os)
|
||||
usrdata->num_channels = usrdata->cpu_info->n_cpus;
|
||||
usrdata->channels = kzalloc(sizeof(struct mcctrl_channel) *
|
||||
usrdata->num_channels,
|
||||
GFP_KERNEL);
|
||||
GFP_ATOMIC);
|
||||
|
||||
if (!usrdata->channels) {
|
||||
printk("Error: cannot allocate channels.\n");
|
||||
@ -500,7 +497,7 @@ int prepare_ikc_channels(ihk_os_t os)
|
||||
}
|
||||
|
||||
usrdata->ikc2linux = kzalloc(sizeof(struct ihk_ikc_channel_desc *) *
|
||||
nr_cpu_ids, GFP_KERNEL);
|
||||
nr_cpu_ids, GFP_ATOMIC);
|
||||
|
||||
if (!usrdata->ikc2linux) {
|
||||
printk("Error: cannot allocate ikc2linux channels.\n");
|
||||
@ -516,7 +513,6 @@ int prepare_ikc_channels(ihk_os_t os)
|
||||
|
||||
init_waitqueue_head(&usrdata->wq_procfs);
|
||||
mutex_init(&usrdata->reserve_lock);
|
||||
mutex_init(&usrdata->part_exec_lock);
|
||||
|
||||
for (i = 0; i < MCCTRL_PER_PROC_DATA_HASH_SIZE; ++i) {
|
||||
INIT_LIST_HEAD(&usrdata->per_proc_data_hash[i]);
|
||||
@ -525,8 +521,10 @@ int prepare_ikc_channels(ihk_os_t os)
|
||||
|
||||
INIT_LIST_HEAD(&usrdata->cpu_topology_list);
|
||||
INIT_LIST_HEAD(&usrdata->node_topology_list);
|
||||
INIT_LIST_HEAD(&usrdata->part_exec_list);
|
||||
|
||||
mutex_init(&usrdata->part_exec.lock);
|
||||
INIT_LIST_HEAD(&usrdata->part_exec.pli_list);
|
||||
usrdata->part_exec.nr_processes = -1;
|
||||
INIT_LIST_HEAD(&usrdata->wakeup_descs_list);
|
||||
spin_lock_init(&usrdata->wakeup_descs_lock);
|
||||
|
||||
@ -582,18 +580,6 @@ void destroy_ikc_channels(ihk_os_t os)
|
||||
|
||||
kfree(usrdata->channels);
|
||||
kfree(usrdata->ikc2linux);
|
||||
|
||||
mutex_lock(&usrdata->part_exec_lock);
|
||||
while (!list_empty(&usrdata->part_exec_list)) {
|
||||
struct mcctrl_part_exec *pe;
|
||||
|
||||
pe = list_first_entry(&usrdata->part_exec_list,
|
||||
struct mcctrl_part_exec, chain);
|
||||
list_del(&pe->chain);
|
||||
kfree(pe);
|
||||
}
|
||||
mutex_unlock(&usrdata->part_exec_lock);
|
||||
|
||||
kfree(usrdata);
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +154,7 @@ struct ikc_scd_packet {
|
||||
|
||||
/* SCD_MSG_CPU_RW_REG */
|
||||
struct {
|
||||
struct ihk_os_cpu_register desc;
|
||||
unsigned long pdesc; /* Physical addr of the descriptor */
|
||||
enum mcctrl_os_cpu_operation op;
|
||||
void *resp;
|
||||
};
|
||||
@ -298,7 +298,6 @@ struct mcctrl_cpu_topology {
|
||||
//struct mcctrl_usrdata *udp;
|
||||
struct ihk_cpu_topology *saved;
|
||||
int mckernel_cpu_id;
|
||||
int mckernel_core_id;
|
||||
cpumask_t core_siblings;
|
||||
cpumask_t thread_siblings;
|
||||
|
||||
@ -325,20 +324,13 @@ struct process_list_item {
|
||||
wait_queue_head_t pli_wq;
|
||||
};
|
||||
|
||||
#define PE_LIST_MAXLEN 5
|
||||
|
||||
struct mcctrl_part_exec {
|
||||
struct mutex lock;
|
||||
int nr_processes;
|
||||
/* number of processes to let in / out the synchronization point */
|
||||
int nr_processes_left;
|
||||
/* number of processes which have joined the partition */
|
||||
int nr_processes_joined;
|
||||
int process_rank;
|
||||
pid_t node_proxy_pid;
|
||||
cpumask_t cpus_used;
|
||||
struct list_head pli_list;
|
||||
struct list_head chain;
|
||||
};
|
||||
|
||||
#define CPU_LONGS (((NR_CPUS) + (BITS_PER_LONG) - 1) / (BITS_PER_LONG))
|
||||
@ -361,7 +353,6 @@ struct mcctrl_usrdata {
|
||||
int job_pos;
|
||||
int mcctrl_dma_abort;
|
||||
struct mutex reserve_lock;
|
||||
struct mutex part_exec_lock;
|
||||
unsigned long last_thread_exec;
|
||||
wait_queue_head_t wq_procfs;
|
||||
struct list_head per_proc_data_hash[MCCTRL_PER_PROC_DATA_HASH_SIZE];
|
||||
@ -377,7 +368,7 @@ struct mcctrl_usrdata {
|
||||
nodemask_t numa_online;
|
||||
struct list_head cpu_topology_list;
|
||||
struct list_head node_topology_list;
|
||||
struct list_head part_exec_list;
|
||||
struct mcctrl_part_exec part_exec;
|
||||
int perf_event_num;
|
||||
};
|
||||
|
||||
|
||||
@ -1130,7 +1130,6 @@ static const struct procfs_entry base_entry_stuff[] = {
|
||||
// PROC_REG("cpuinfo", S_IRUGO, NULL),
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_42 */
|
||||
// PROC_REG("meminfo", S_IRUGO, NULL),
|
||||
PROC_REG("meminfo", S_IRUGO, &mckernel_buff_io),
|
||||
// PROC_REG("pagetypeinfo",S_IRUGO, NULL),
|
||||
// PROC_REG("softirq", S_IRUGO, NULL),
|
||||
PROC_REG("stat", 0444, &mckernel_buff_io),
|
||||
|
||||
@ -228,9 +228,10 @@ static int __notify_syscall_requester(ihk_os_t os, struct ikc_scd_packet *packet
|
||||
c = (usrdata->channels + packet->ref)->c;
|
||||
|
||||
/* If spinning, no need for IKC message */
|
||||
if (__sync_bool_compare_and_swap(&res->req_thread_status,
|
||||
if (cmpxchg(&res->req_thread_status,
|
||||
IHK_SCD_REQ_THREAD_SPINNING,
|
||||
IHK_SCD_REQ_THREAD_TO_BE_WOKEN)) {
|
||||
IHK_SCD_REQ_THREAD_TO_BE_WOKEN) ==
|
||||
IHK_SCD_REQ_THREAD_SPINNING) {
|
||||
dprintk("%s: no need to send IKC message for PID %d\n",
|
||||
__FUNCTION__, packet->pid);
|
||||
return ret;
|
||||
@ -239,7 +240,7 @@ static int __notify_syscall_requester(ihk_os_t os, struct ikc_scd_packet *packet
|
||||
/* Wait until the status goes back to IHK_SCD_REQ_THREAD_SPINNING or
|
||||
IHK_SCD_REQ_THREAD_DESCHEDULED because two wake-up attempts are competing.
|
||||
Note that mcexec_terminate_thread() and returning EINTR would compete. */
|
||||
if (res->req_thread_status == IHK_SCD_REQ_THREAD_TO_BE_WOKEN) {
|
||||
if (smp_load_acquire(&res->req_thread_status) == IHK_SCD_REQ_THREAD_TO_BE_WOKEN) {
|
||||
printk("%s: INFO: someone else is waking up the McKernel thread, "
|
||||
"pid: %d, req status: %lu, syscall nr: %lu\n",
|
||||
__FUNCTION__, packet->pid,
|
||||
@ -247,9 +248,10 @@ static int __notify_syscall_requester(ihk_os_t os, struct ikc_scd_packet *packet
|
||||
}
|
||||
|
||||
/* The thread is not spinning any more, make sure it's descheduled */
|
||||
if (!__sync_bool_compare_and_swap(&res->req_thread_status,
|
||||
if (cmpxchg(&res->req_thread_status,
|
||||
IHK_SCD_REQ_THREAD_DESCHEDULED,
|
||||
IHK_SCD_REQ_THREAD_TO_BE_WOKEN)) {
|
||||
IHK_SCD_REQ_THREAD_TO_BE_WOKEN) !=
|
||||
IHK_SCD_REQ_THREAD_DESCHEDULED) {
|
||||
printk("%s: WARNING: inconsistent requester status, "
|
||||
"pid: %d, req status: %lu, syscall nr: %lu\n",
|
||||
__FUNCTION__, packet->pid,
|
||||
@ -970,6 +972,30 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Shared memory hack */
|
||||
{
|
||||
char *pathbuf, *fullpath;
|
||||
pathbuf = kmalloc(PATH_MAX, GFP_ATOMIC);
|
||||
if (pathbuf) {
|
||||
fullpath = d_path(&file->f_path, pathbuf, PATH_MAX);
|
||||
if (!IS_ERR(fullpath)) {
|
||||
if (!strncmp("/tmp/ompi.", fullpath, 10) ||
|
||||
!strncmp("/dev/shm/", fullpath, 9) ||
|
||||
(!strncmp("/var/opt/FJSVtcs/ple/daemonif/",
|
||||
fullpath, 30) && !strstr(fullpath, "dstore_sm.lock"))) {
|
||||
printk("%s: treating %s as a device file..\n",
|
||||
__func__, fullpath);
|
||||
kfree(pathbuf);
|
||||
|
||||
error = -ESRCH;
|
||||
goto out;
|
||||
}
|
||||
|
||||
kfree(pathbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inode = file->f_path.dentry->d_inode;
|
||||
if (!inode) {
|
||||
error = -EBADF;
|
||||
@ -1029,7 +1055,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa)
|
||||
pager = newpager;
|
||||
newpager = NULL;
|
||||
|
||||
/* Intel MPI library and shared memory "prefetch" */
|
||||
/* Shared libraries prefetch */
|
||||
{
|
||||
char *pathbuf, *fullpath;
|
||||
|
||||
@ -1037,15 +1063,7 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa)
|
||||
if (pathbuf) {
|
||||
fullpath = d_path(&file->f_path, pathbuf, PATH_MAX);
|
||||
if (!IS_ERR(fullpath)) {
|
||||
if (!strncmp("/dev/shm/Intel_MPI", fullpath, 18)) {
|
||||
mf_flags = (MF_PREMAP | MF_ZEROFILL);
|
||||
dprintk("%s: filename: %s, premap & zerofill\n",
|
||||
__FUNCTION__, fullpath);
|
||||
}
|
||||
else if (strstr(fullpath, "libmpi") ||
|
||||
strstr(fullpath, "libiomp") ||
|
||||
strstr(fullpath, "libpthread") ||
|
||||
strstr(fullpath, "libc.so")) {
|
||||
if (strstr(fullpath, ".so")) {
|
||||
mf_flags = MF_PREFETCH;
|
||||
dprintk("%s: filename: %s, prefetch\n",
|
||||
__FUNCTION__, fullpath);
|
||||
@ -1417,6 +1435,26 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off,
|
||||
#define ANY_WHERE 0
|
||||
if (prot_and_flags & MAP_LOCKED) prot_and_flags |= MAP_POPULATE;
|
||||
|
||||
/* Shared memory hack */
|
||||
{
|
||||
char *pathbuf, *fullpath;
|
||||
pathbuf = kmalloc(PATH_MAX, GFP_ATOMIC);
|
||||
if (pathbuf) {
|
||||
fullpath = d_path(&file->f_path, pathbuf, PATH_MAX);
|
||||
if (!IS_ERR(fullpath)) {
|
||||
if (!strncmp("/tmp/ompi.", fullpath, 10) ||
|
||||
!strncmp("/dev/shm/", fullpath, 9) ||
|
||||
!strncmp("/var/opt/FJSVtcs/ple/daemonif/",
|
||||
fullpath, 30)) {
|
||||
dprintk("%s: pre-populating %s..\n",
|
||||
__func__, fullpath);
|
||||
prot_and_flags |= MAP_POPULATE;
|
||||
}
|
||||
kfree(pathbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
|
||||
@ -1430,7 +1468,12 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off,
|
||||
#endif
|
||||
|
||||
if (IS_ERR_VALUE(va)) {
|
||||
printk("pager_req_map(%p,%d,%lx,%lx,%lx):do_mmap_pgoff failed. %d\n", os, fd, len, off, result_rpa, (int)va);
|
||||
if ((int)va != -ENOTSUPP) {
|
||||
pr_err("%s(%p,%d,%lx,%lx,%lx): "
|
||||
"do_mmap_pgoff failed. %d\n",
|
||||
__func__, os, fd, len, off, result_rpa,
|
||||
(int)va);
|
||||
}
|
||||
error = va;
|
||||
goto out;
|
||||
}
|
||||
@ -1579,11 +1622,28 @@ retry:
|
||||
#else
|
||||
fault = handle_mm_fault(current->mm, vma, va, flags);
|
||||
#endif
|
||||
#ifdef SC_DEBUG
|
||||
if (fault != 0) {
|
||||
printk("%s: error: faulting %lx at off: %lu\n",
|
||||
__FUNCTION__, va, off);
|
||||
char *pathbuf = NULL;
|
||||
char *fullpath;
|
||||
|
||||
if (vma->vm_file) {
|
||||
pathbuf = kmalloc(PATH_MAX, GFP_ATOMIC);
|
||||
if (pathbuf) {
|
||||
fullpath = d_path(&vma->vm_file->f_path,
|
||||
pathbuf, PATH_MAX);
|
||||
if (!IS_ERR(fullpath)) {
|
||||
printk("%s: WARNING: couldn't fault 0x%lx"
|
||||
" at off: %lu in %s\n",
|
||||
__FUNCTION__, va, off, fullpath);
|
||||
}
|
||||
|
||||
kfree(pathbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
page_fault_attempted = 1;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/hashtable.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/version.h>
|
||||
@ -24,14 +23,6 @@
|
||||
#define wprintk(...) do { if (1) printk(KERN_WARNING __VA_ARGS__); } while (0)
|
||||
#define eprintk(...) do { if (1) printk(KERN_ERR __VA_ARGS__); } while (0)
|
||||
|
||||
struct physical_core_id {
|
||||
int linux_core_id;
|
||||
int mckernel_core_id;
|
||||
struct hlist_node next;
|
||||
};
|
||||
|
||||
DEFINE_HASHTABLE(physical_core_id_map, 10);
|
||||
|
||||
static ssize_t
|
||||
show_int(struct sysfsm_ops *ops, void *instance, void *buf, size_t size)
|
||||
{
|
||||
@ -197,9 +188,6 @@ static void free_cpu_topology(struct mcctrl_usrdata *udp)
|
||||
void free_topology_info(ihk_os_t os)
|
||||
{
|
||||
struct mcctrl_usrdata *udp = ihk_host_os_get_usrdata(os);
|
||||
int bkt;
|
||||
struct hlist_node *tmp;
|
||||
struct physical_core_id *cur;
|
||||
|
||||
if (!udp) {
|
||||
pr_warn("%s: warning: mcctrl_usrdata not found\n", __func__);
|
||||
@ -209,11 +197,6 @@ void free_topology_info(ihk_os_t os)
|
||||
free_node_topology(udp);
|
||||
free_cpu_topology(udp);
|
||||
|
||||
hash_for_each_safe(physical_core_id_map, bkt, tmp, cur, next) {
|
||||
hash_del(&cur->next);
|
||||
kfree(cur);
|
||||
}
|
||||
|
||||
return;
|
||||
} /* free_topology_info() */
|
||||
|
||||
@ -365,11 +348,6 @@ static struct mcctrl_cpu_topology *get_one_cpu_topology(struct mcctrl_usrdata *u
|
||||
struct mcctrl_cpu_topology *topology = NULL;
|
||||
struct cache_topology *cache;
|
||||
struct ihk_cache_topology *saved_cache;
|
||||
int linux_core_id;
|
||||
int mckernel_core_id;
|
||||
struct physical_core_id *entry;
|
||||
struct physical_core_id *cur;
|
||||
static int nr_mckernel_core;
|
||||
|
||||
dprintk("get_one_cpu_topology(%p,%d)\n", udp, index);
|
||||
topology = kmalloc(sizeof(*topology), GFP_KERNEL);
|
||||
@ -413,22 +391,6 @@ static struct mcctrl_cpu_topology *get_one_cpu_topology(struct mcctrl_usrdata *u
|
||||
goto out;
|
||||
}
|
||||
|
||||
linux_core_id = topology->saved->core_id;
|
||||
mckernel_core_id = -1;
|
||||
hash_for_each_possible(physical_core_id_map, cur, next, linux_core_id) {
|
||||
mckernel_core_id = cur->mckernel_core_id;
|
||||
break;
|
||||
}
|
||||
if (mckernel_core_id < 0) {
|
||||
mckernel_core_id = nr_mckernel_core++;
|
||||
entry = kmalloc(sizeof(struct physical_core_id), GFP_KERNEL);
|
||||
entry->linux_core_id = linux_core_id;
|
||||
entry->mckernel_core_id = mckernel_core_id;
|
||||
hash_add(physical_core_id_map,
|
||||
&entry->next, entry->linux_core_id);
|
||||
}
|
||||
topology->mckernel_core_id = mckernel_core_id;
|
||||
|
||||
list_for_each_entry(saved_cache,
|
||||
&topology->saved->cache_topology_list, chain) {
|
||||
cache = get_cache_topology(udp, topology, saved_cache);
|
||||
@ -550,7 +512,7 @@ static void setup_cpu_sysfs_files(struct mcctrl_usrdata *udp,
|
||||
"%s/cpu%d/topology/physical_package_id",
|
||||
prefix, cpu_number);
|
||||
sysfsm_createf(udp->os, SYSFS_SNOOPING_OPS_d32,
|
||||
&cpu->mckernel_core_id, 0444,
|
||||
&cpu->saved->core_id, 0444,
|
||||
"%s/cpu%d/topology/core_id",
|
||||
prefix, cpu_number);
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ include_directories(
|
||||
"${PROJECT_BINARY_DIR}/ihk/linux/include"
|
||||
)
|
||||
|
||||
|
||||
add_subdirectory(lib)
|
||||
add_library(libmcexec STATIC arch/${ARCH}/archdep.S)
|
||||
SET_TARGET_PROPERTIES(libmcexec PROPERTIES OUTPUT_NAME mcexec)
|
||||
set_property(TARGET libmcexec PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
@ -20,6 +20,17 @@ target_include_directories(mcexec PUBLIC "${KERNEL_DIR}")
|
||||
set_property(TARGET mcexec PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET mcexec PROPERTY LINK_FLAGS "-fPIE -pie")
|
||||
|
||||
add_executable(mcinspect mcinspect.c)
|
||||
if (NOT LIBDWARF)
|
||||
target_include_directories(mcinspect PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/lib/")
|
||||
target_include_directories(mcinspect PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/libdwarf/libdwarf/libdwarf/")
|
||||
target_link_libraries(mcinspect dwarf z elf)
|
||||
else()
|
||||
target_link_libraries(mcinspect ${LIBDWARF})
|
||||
endif()
|
||||
target_link_libraries(mcinspect ${LIBBFD})
|
||||
|
||||
add_executable(eclair eclair.c arch/${ARCH}/arch-eclair.c)
|
||||
target_link_libraries(eclair ${LIBBFD})
|
||||
|
||||
@ -74,10 +85,13 @@ add_library(ldump2mcdump SHARED ldump2mcdump.c)
|
||||
configure_file(vmcore2mckdump.in vmcore2mckdump @ONLY)
|
||||
|
||||
configure_file(mcexec.1in mcexec.1 @ONLY)
|
||||
configure_file(mcps.in mcps @ONLY)
|
||||
|
||||
install(TARGETS mcexec eclair
|
||||
install(TARGETS mcexec eclair mcinspect
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/vmcore2mckdump"
|
||||
install(PROGRAMS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/vmcore2mckdump"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/mcps"
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
install(TARGETS sched_yield ldump2mcdump
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
3
executer/user/lib/CMakeLists.txt
Normal file
3
executer/user/lib/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
if (NOT LIBDWARF)
|
||||
add_subdirectory(libdwarf)
|
||||
endif()
|
||||
144
executer/user/lib/libdwarf/CMakeLists.txt
Normal file
144
executer/user/lib/libdwarf/CMakeLists.txt
Normal file
@ -0,0 +1,144 @@
|
||||
if (NOT LIBDWARF)
|
||||
# view folders on supported IDEs
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# used when finding libelf
|
||||
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
|
||||
|
||||
find_package(LibElf REQUIRED)
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBELF_INCLUDE_DIRS})
|
||||
include(AutoconfHelper)
|
||||
|
||||
ac_init()
|
||||
ac_c_bigendian()
|
||||
ac_check_headers(sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h inttypes.h stdint.h unistd.h)
|
||||
ac_check_headers(alloca.h elf.h elfaccess.h libelf.h libelf/libelf.h sys/types.h sys/elf_386.h sys/elf_amd64.h sys/elf_sparc.h sys/ia64/elf.h)
|
||||
|
||||
# The default libdwarf is the one with struct Elf
|
||||
message(STATUS "Assuming struct Elf for the default libdwarf.h")
|
||||
|
||||
# Find out where the elf header is.
|
||||
if(HAVE_ELF_H)
|
||||
set(HAVE_LOCATION_OF_LIBELFHEADER "<elf.h>")
|
||||
elseif(HAVE_LIBELF_H)
|
||||
set(HAVE_LOCATION_OF_LIBELFHEADER "<libelf.h>")
|
||||
elseif(HAVE_LIBELF_LIBELF_H)
|
||||
set(HAVE_LOCATION_OF_LIBELFHEADER "<libelf/libelf.h>")
|
||||
endif()
|
||||
|
||||
ac_check_lib(${LIBELF_LIBRARIES} elf64_getehdr)
|
||||
ac_check_lib(${LIBELF_LIBRARIES} elf64_getshdr)
|
||||
|
||||
ac_try_compile("
|
||||
int main()
|
||||
{
|
||||
__uint32_t p;
|
||||
p = 3;
|
||||
return 0;
|
||||
}"
|
||||
HAVE___UINT32_T)
|
||||
|
||||
ac_try_compile("
|
||||
int main()
|
||||
{
|
||||
__uint64_t p;
|
||||
p = 3;
|
||||
return 0;
|
||||
}"
|
||||
HAVE___UINT64_T)
|
||||
|
||||
ac_try_compile("
|
||||
#include <sys/types.h>
|
||||
int main()
|
||||
{
|
||||
__uint32_t p;
|
||||
p = 3;
|
||||
return 0;
|
||||
}"
|
||||
HAVE___UINT32_T_IN_SYS_TYPES_H)
|
||||
|
||||
ac_try_compile("
|
||||
#include <sys/types.h>
|
||||
int main()
|
||||
{
|
||||
__uint64_t p;
|
||||
p = 3;
|
||||
return 0;
|
||||
}"
|
||||
HAVE___UINT64_T_IN_SYS_TYPES_H)
|
||||
|
||||
check_c_source_runs("
|
||||
static unsigned foo( unsigned x, __attribute__ ((unused)) int y)
|
||||
{
|
||||
unsigned x2 = x + 1;
|
||||
return x2;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
unsigned y = 0;
|
||||
y = foo(12,y);
|
||||
return 0;
|
||||
}"
|
||||
HAVE_UNUSED_ATTRIBUTE)
|
||||
|
||||
message(STATUS "Checking compiler supports __attribute__ unused... ${HAVE_UNUSED_ATTRIBUTE}")
|
||||
|
||||
ac_try_compile("
|
||||
#include <zlib.h>
|
||||
int main()
|
||||
{
|
||||
Bytef dest[100];
|
||||
uLongf destlen = 100;
|
||||
Bytef *src = 0;
|
||||
uLong srclen = 3;
|
||||
int res = uncompress(dest,&destlen,src,srclen);
|
||||
if (res == Z_OK) {
|
||||
/* ALL IS WELL */
|
||||
}
|
||||
return 0;
|
||||
}"
|
||||
HAVE_ZLIB)
|
||||
message(STATUS "Checking zlib.h usability... ${HAVE_ZLIB}")
|
||||
set(dwfzlib $<$<BOOL:${HAVE_ZIB}>:"z")
|
||||
|
||||
configure_file(libdwarf/libdwarf/libdwarf.h.in libdwarf.h COPYONLY)
|
||||
configure_file(libdwarf/libdwarf/config.h.in.cmake config.h)
|
||||
set(DWARF_CONFIGURATION_FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
set(DWARF_SOURCES dwarf_abbrev.c dwarf_alloc.c dwarf_arange.c dwarf_die_deliv.c dwarf_dnames.c dwarf_dsc.c dwarf_elf_access.c dwarf_error.c
|
||||
dwarf_form.c dwarf_frame.c dwarf_frame2.c dwarf_funcs.c dwarf_gdbindex.c dwarf_global.c dwarf_groups.c dwarf_harmless.c dwarf_init_finish.c dwarf_leb.c
|
||||
dwarf_line.c dwarf_loc.c dwarf_macro.c dwarf_macro5.c dwarf_original_elf_init.c dwarf_pubtypes.c dwarf_query.c dwarf_ranges.c dwarf_string.c dwarf_tied.c
|
||||
dwarf_str_offsets.c
|
||||
dwarf_tsearchhash.c dwarf_types.c dwarf_util.c dwarf_vars.c dwarf_weaks.c dwarf_xu_index.c dwarf_print_lines.c malloc_check.c pro_alloc.c pro_arange.c
|
||||
pro_die.c pro_encode_nm.c pro_error.c pro_expr.c pro_finish.c pro_forms.c pro_funcs.c pro_frame.c pro_init.c pro_line.c pro_reloc.c pro_reloc_stream.c
|
||||
pro_reloc_symbolic.c pro_pubnames.c pro_section.c pro_types.c pro_vars.c pro_macinfo.c pro_weaks.c)
|
||||
|
||||
set(DWARF_HEADERS dwarf.h dwarf_abbrev.h dwarf_alloc.h dwarf_arange.h dwarf_base_types.h dwarf_die_deliv.h dwarf_dnames.h dwarf_dsc.h
|
||||
dwarf_elf_access.h dwarf_error.h dwarf_frame.h dwarf_funcs.h dwarf_gdbindex.h dwarf_global.h dwarf_harmless.h dwarf_incl.h dwarf_line.h dwarf_loc.h
|
||||
dwarf_macro.h dwarf_macro5.h dwarf_opaque.h dwarf_reloc_arm.h dwarf_reloc_mips.h dwarf_reloc_ppc.h dwarf_reloc_ppc64.h dwarf_reloc_x86_64.h dwarf_tsearch.h
|
||||
dwarf_str_offsets.h
|
||||
dwarf_types.h dwarf_util.h dwarf_vars.h dwarf_weaks.h dwarf_xu_index.h dwgetopt.h libdwarfdefs.h malloc_check.h pro_alloc.h pro_arange.h pro_die.h
|
||||
pro_encode_nm.h pro_error.h pro_expr.h pro_frame.h pro_incl.h pro_line.h pro_macinfo.h pro_opaque.h pro_reloc.h pro_reloc_stream.h pro_reloc_symbolic.h
|
||||
pro_section.h pro_types.h pro_util.h)
|
||||
|
||||
SET(__SRCS "")
|
||||
FOREACH(f ${DWARF_SOURCES})
|
||||
LIST(APPEND __SRCS "libdwarf/libdwarf/${f}")
|
||||
ENDFOREACH(f)
|
||||
SET(DWARF_SOURCES ${__SRCS})
|
||||
|
||||
set(GENNAMES_SOURCES
|
||||
libdwarf/libdwarf/gennames.c
|
||||
libdwarf/libdwarf/dwgetopt.c
|
||||
libdwarf/libdwarf/dwarf.h)
|
||||
add_executable(gennames ${GENNAMES_SOURCES})
|
||||
set(GENNAMES_OUTPUT dwarf_names.c dwarf_names.h dwarf_names_enum.h dwarf_names_new.h)
|
||||
|
||||
add_custom_command(OUTPUT ${GENNAMES_OUTPUT}
|
||||
COMMAND gennames -s -i ${CMAKE_CURRENT_SOURCE_DIR}/libdwarf/libdwarf/ -o .
|
||||
DEPENDS gennames libdwarf/libdwarf/libdwarf.h.in)
|
||||
|
||||
add_library(dwarf STATIC ${DWARF_SOURCES} ${GENNAMES_OUTPUT} ${DWARF_CONFIGURATION_FILES})
|
||||
target_include_directories(dwarf PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/libdwarf/libdwarf/")
|
||||
target_include_directories(dwarf BEFORE PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
1
executer/user/lib/libdwarf/libdwarf
Submodule
1
executer/user/lib/libdwarf/libdwarf
Submodule
Submodule executer/user/lib/libdwarf/libdwarf added at ab9230b2b8
@ -1,6 +1,7 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
@ -27,3 +28,110 @@ int sched_yield(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef pthread_create
|
||||
|
||||
typedef int (*__pthread_create_fn)(pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *),
|
||||
void *arg);
|
||||
|
||||
static __pthread_create_fn orig_pthread_create = 0;
|
||||
|
||||
|
||||
int pthread_create(pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *),
|
||||
void *arg)
|
||||
{
|
||||
if (!orig_pthread_create) {
|
||||
orig_pthread_create =
|
||||
(__pthread_create_fn)dlsym(RTLD_NEXT, "pthread_create");
|
||||
}
|
||||
|
||||
/* CLONE_VM and newsp == parent_tidptr impiles pthread start routine addr */
|
||||
syscall(__NR_clone, CLONE_VM, start_routine, start_routine, 0, 0, 0);
|
||||
|
||||
return orig_pthread_create(thread, attr, start_routine, arg);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define PROCMAPS_MAX_LEN 131072
|
||||
|
||||
char *addr_to_lib(void *addr, unsigned long *offset_in_lib)
|
||||
{
|
||||
char maps_path[PATH_MAX];
|
||||
char buf[PROCMAPS_MAX_LEN];
|
||||
int fd;
|
||||
void *start, *end;
|
||||
char perms[4];
|
||||
unsigned long offset;
|
||||
unsigned long dev[2];
|
||||
int inode;
|
||||
char path[PATH_MAX];
|
||||
char *line;
|
||||
|
||||
sprintf(maps_path,"/proc/self/maps");
|
||||
fd = open(maps_path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr,"error: cannot open the memory maps, %s\n",
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(buf, 0, PROCMAPS_MAX_LEN);
|
||||
read(fd, buf, PROCMAPS_MAX_LEN);
|
||||
line = strtok(buf, "\n");
|
||||
while (line) {
|
||||
memset(path, 0, sizeof(path));
|
||||
sscanf(line, "%012lx-%012lx %4s %lx %lx:%lx %d\t\t\t%[^\n]",
|
||||
&start, &end, perms, &offset, &dev[0], &dev[1], &inode, path);
|
||||
|
||||
if (start <= addr && end > addr) {
|
||||
close(fd);
|
||||
if (offset_in_lib)
|
||||
*offset_in_lib = (unsigned long)(addr - start);
|
||||
return strlen(path) > 0 ? strdup(path) : NULL;
|
||||
}
|
||||
|
||||
line = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *),
|
||||
void *arg)
|
||||
{
|
||||
char *lib = NULL;
|
||||
int util_thread = 1;
|
||||
unsigned long offset;
|
||||
|
||||
if (!orig_pthread_create) {
|
||||
orig_pthread_create =
|
||||
(__pthread_create_fn)dlsym(RTLD_NEXT, "pthread_create");
|
||||
}
|
||||
|
||||
lib = addr_to_lib(start_routine, &offset);
|
||||
if (lib)
|
||||
printf("%s: 0x%lx is in %s @ 0x%lx\n",
|
||||
__func__, start_routine, lib, offset);
|
||||
|
||||
if (lib && (strstr(lib, "iomp") || strstr(lib, "psm"))) {
|
||||
util_thread = 0;
|
||||
}
|
||||
|
||||
if (util_thread) {
|
||||
/* McKernel util_indicate_clone() */
|
||||
syscall(731);
|
||||
}
|
||||
|
||||
if (lib)
|
||||
free(lib);
|
||||
|
||||
return orig_pthread_create(thread, attr, start_routine, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2486,7 +2486,6 @@ int main(int argc, char **argv)
|
||||
cpu_set_arg.cpu_set = (void *)&desc->cpu_set;
|
||||
cpu_set_arg.cpu_set_size = sizeof(desc->cpu_set);
|
||||
cpu_set_arg.nr_processes = nr_processes;
|
||||
cpu_set_arg.ppid = getppid();
|
||||
cpu_set_arg.target_core = &target_core;
|
||||
cpu_set_arg.process_rank = &process_rank;
|
||||
cpu_set_arg.mcexec_linux_numa = &mcexec_linux_numa;
|
||||
|
||||
1348
executer/user/mcinspect.c
Normal file
1348
executer/user/mcinspect.c
Normal file
File diff suppressed because it is too large
Load Diff
10
executer/user/mcps.in
Normal file
10
executer/user/mcps.in
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
# IHK/McKernel mcps script.
|
||||
# author: Balazs Gerofi <bgerofi@riken.jp>
|
||||
# Copyright (C) 2019 RIKEN
|
||||
#
|
||||
prefix="@prefix@"
|
||||
BINDIR="${prefix}/bin"
|
||||
KERNDIR="@MCKERNELDIR@"
|
||||
|
||||
${BINDIR}/mcinspect --kernel=${KERNDIR}/mckernel.img --ps
|
||||
2
ihk
2
ihk
Submodule ihk updated: b680d18588...1a6150c5bb
@ -170,7 +170,7 @@ static void devobj_free(struct memobj *memobj)
|
||||
|
||||
error = syscall_generic_forwarding(__NR_mmap, &ctx);
|
||||
if (error) {
|
||||
kprintf("%s(%p %lx): release failed. %d\n",
|
||||
dkprintf("%s(%p %lx): release failed. %d\n",
|
||||
__func__, obj, handle, error);
|
||||
/* through */
|
||||
}
|
||||
|
||||
@ -398,8 +398,9 @@ static void fileobj_free(struct memobj *memobj)
|
||||
}
|
||||
}
|
||||
|
||||
/* Pre-mapped? */
|
||||
if (to_memobj(obj)->flags & MF_PREMAP) {
|
||||
/* Pre-mapped zerofilled? */
|
||||
if (to_memobj(obj)->flags & MF_PREMAP &&
|
||||
to_memobj(obj)->flags & MF_ZEROFILL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < to_memobj(obj)->nr_pages; ++i) {
|
||||
@ -440,7 +441,7 @@ static void fileobj_free(struct memobj *memobj)
|
||||
|
||||
error = syscall_generic_forwarding(__NR_mmap, &ctx);
|
||||
if (error) {
|
||||
kprintf("%s(%p %lx): free failed. %d\n", __func__,
|
||||
dkprintf("%s(%p %lx): free failed. %d\n", __func__,
|
||||
obj, obj->handle, error);
|
||||
/* through */
|
||||
}
|
||||
@ -473,20 +474,24 @@ static void fileobj_do_pageio(void *args0)
|
||||
ssize_t ss;
|
||||
struct mcs_lock_node mcs_node;
|
||||
int hash = (off >> PAGE_SHIFT) & FILEOBJ_PAGE_HASH_MASK;
|
||||
int attempts = 0;
|
||||
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_lock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
page = __fileobj_page_hash_lookup(obj, hash, off);
|
||||
if (!page) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (page->mode == PM_PAGEIO) {
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_unlock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
++attempts;
|
||||
if (attempts > 49) {
|
||||
dkprintf("%s: %s:%lu PM_PAGEIO loop %d -> schedule()\n",
|
||||
__func__, to_memobj(obj)->path, off, attempts);
|
||||
schedule();
|
||||
}
|
||||
cpu_pause();
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_lock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
}
|
||||
|
||||
if (page->mode == PM_WILL_PAGEIO) {
|
||||
@ -499,8 +504,7 @@ static void fileobj_do_pageio(void *args0)
|
||||
}
|
||||
else {
|
||||
page->mode = PM_PAGEIO;
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_unlock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
|
||||
ihk_mc_syscall_arg0(&ctx) = PAGER_REQ_READ;
|
||||
ihk_mc_syscall_arg1(&ctx) = obj->handle;
|
||||
@ -512,8 +516,7 @@ static void fileobj_do_pageio(void *args0)
|
||||
__FUNCTION__, obj->handle);
|
||||
ss = syscall_generic_forwarding(__NR_mmap, &ctx);
|
||||
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_lock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
if (page->mode != PM_PAGEIO) {
|
||||
kprintf("fileobj_do_pageio(%p,%lx,%lx):"
|
||||
"invalid mode %x\n",
|
||||
@ -539,8 +542,7 @@ static void fileobj_do_pageio(void *args0)
|
||||
page->mode = PM_DONE_PAGEIO;
|
||||
}
|
||||
out:
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_unlock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
memobj_unref(&obj->memobj); /* got fileobj_get_page() */
|
||||
kfree(args0);
|
||||
dkprintf("fileobj_do_pageio(%p,%lx,%lx):\n", obj, off, pgsize);
|
||||
@ -570,7 +572,8 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
profile_event_add(PROFILE_page_fault_file, PAGE_SIZE);
|
||||
#endif // PROFILE_ENABLE
|
||||
|
||||
if (memobj->flags & MF_PREMAP) {
|
||||
if (memobj->flags & MF_PREMAP &&
|
||||
memobj->flags & MF_ZEROFILL) {
|
||||
int page_ind = off >> PAGE_SHIFT;
|
||||
|
||||
if (!memobj->pages[page_ind]) {
|
||||
@ -587,8 +590,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
|
||||
/* Update the array but see if someone did it already and use
|
||||
* that if so */
|
||||
if (!__sync_bool_compare_and_swap(&memobj->pages[page_ind],
|
||||
NULL, virt)) {
|
||||
if (cmpxchg(&memobj->pages[page_ind], NULL, virt) != NULL) {
|
||||
ihk_mc_free_pages_user(virt, 1);
|
||||
}
|
||||
else {
|
||||
@ -609,8 +611,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
goto out_nolock;
|
||||
}
|
||||
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_lock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
page = __fileobj_page_hash_lookup(obj, hash, off);
|
||||
if (!page || (page->mode == PM_WILL_PAGEIO)
|
||||
|| (page->mode == PM_PAGEIO)) {
|
||||
@ -688,8 +689,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
*physp = page_to_phys(page);
|
||||
virt = NULL;
|
||||
out:
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_unlock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
out_nolock:
|
||||
if (virt) {
|
||||
ihk_mc_free_pages_user(virt, npages);
|
||||
@ -767,8 +767,7 @@ static int fileobj_lookup_page(struct memobj *memobj, off_t off,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_lock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
|
||||
page = __fileobj_page_hash_lookup(obj, hash, off);
|
||||
if (!page) {
|
||||
@ -779,8 +778,7 @@ static int fileobj_lookup_page(struct memobj *memobj, off_t off,
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
mcs_lock_unlock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
|
||||
dkprintf("fileobj_lookup_page(%p,%lx,%x,%p): %d \n",
|
||||
obj, off, p2align, physp, error);
|
||||
|
||||
@ -311,6 +311,7 @@ static int futex_wake(uint32_t *uaddr, int fshared, int nr_wake, uint32_t bitset
|
||||
struct plist_head *head;
|
||||
union futex_key key = FUTEX_KEY_INIT;
|
||||
int ret;
|
||||
unsigned long irqstate;
|
||||
|
||||
if (!bitset)
|
||||
return -EINVAL;
|
||||
@ -320,7 +321,7 @@ static int futex_wake(uint32_t *uaddr, int fshared, int nr_wake, uint32_t bitset
|
||||
goto out;
|
||||
|
||||
hb = hash_futex(&key);
|
||||
ihk_mc_spinlock_lock_noirq(&hb->lock);
|
||||
irqstate = ihk_mc_spinlock_lock(&hb->lock);
|
||||
head = &hb->chain;
|
||||
|
||||
plist_for_each_entry_safe(this, next, head, list) {
|
||||
@ -337,7 +338,7 @@ static int futex_wake(uint32_t *uaddr, int fshared, int nr_wake, uint32_t bitset
|
||||
}
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&hb->lock);
|
||||
ihk_mc_spinlock_unlock(&hb->lock, irqstate);
|
||||
put_futex_key(fshared, &key);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
@ -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,
|
||||
pn->sections[i].len > LARGE_PAGE_SIZE ?
|
||||
LARGE_PAGE_SHIFT : PAGE_SHIFT,
|
||||
NULL, &range) != 0) {
|
||||
&range) != 0) {
|
||||
kprintf("ERROR: adding memory range for ELF section %i\n", i);
|
||||
goto err;
|
||||
}
|
||||
@ -284,7 +284,7 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
dkprintf("%s: args_envs: %d pages\n",
|
||||
__func__, argenv_page_count);
|
||||
if(add_process_memory_range(vm, addr, e, args_envs_p,
|
||||
flags, NULL, 0, PAGE_SHIFT, NULL, NULL) != 0){
|
||||
flags, NULL, 0, PAGE_SHIFT, NULL) != 0){
|
||||
ihk_mc_free_pages_user(args_envs, argenv_page_count);
|
||||
kprintf("ERROR: adding memory range for args/envs\n");
|
||||
goto err;
|
||||
@ -500,6 +500,7 @@ static int process_msg_prepare_process(unsigned long rphys)
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
return -ENOMEM;
|
||||
}
|
||||
sprintf(thread->pthread_routine, "%s", "[main]");
|
||||
proc = thread->proc;
|
||||
vm = thread->vm;
|
||||
|
||||
@ -619,6 +620,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
{
|
||||
struct ikc_scd_packet *packet = __packet;
|
||||
struct ikc_scd_packet pckt;
|
||||
struct ihk_os_cpu_register *cpu_desc;
|
||||
struct ihk_ikc_channel_desc *resp_channel = cpu_local_var(ikc2linux);
|
||||
int rc;
|
||||
struct thread *thread;
|
||||
@ -689,11 +691,11 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
thread_unlock(thread);
|
||||
|
||||
dkprintf("%s: SCD_MSG_WAKE_UP_SYSCALL_THREAD: waking up tid %d\n",
|
||||
__FUNCTION__, packet->ttid);
|
||||
waitq_wakeup(&thread->scd_wq);
|
||||
thread_unlock(thread);
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
@ -717,9 +719,11 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
dkprintf("remote page fault,pid=%d,va=%lx,reason=%x\n",
|
||||
thread->proc->pid, packet->fault_address,
|
||||
packet->fault_reason|PF_POPULATE);
|
||||
preempt_disable();
|
||||
pckt.err = page_fault_process_vm(thread->vm,
|
||||
(void *)packet->fault_address,
|
||||
packet->fault_reason|PF_POPULATE);
|
||||
preempt_enable();
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
if (thread->profile) {
|
||||
@ -839,12 +843,17 @@ out_remote_pf:
|
||||
break;
|
||||
|
||||
case SCD_MSG_CPU_RW_REG:
|
||||
pp = ihk_mc_map_memory(NULL, packet->pdesc,
|
||||
sizeof(struct ihk_os_cpu_register));
|
||||
cpu_desc = (struct ihk_os_cpu_register *)ihk_mc_map_virtual(
|
||||
pp, 1, PTATTR_WRITABLE | PTATTR_ACTIVE);
|
||||
|
||||
pckt.msg = SCD_MSG_CPU_RW_REG_RESP;
|
||||
memcpy(&pckt.desc, &packet->desc,
|
||||
sizeof(struct ihk_os_cpu_register));
|
||||
pckt.resp = packet->resp;
|
||||
pckt.err = arch_cpu_read_write_register(&pckt.desc, packet->op);
|
||||
pckt.reply = packet->reply;
|
||||
pckt.err = arch_cpu_read_write_register(cpu_desc, packet->op);
|
||||
|
||||
ihk_mc_unmap_virtual(cpu_desc, 1);
|
||||
ihk_mc_unmap_memory(NULL, pp, sizeof(struct ihk_os_cpu_register));
|
||||
|
||||
ihk_ikc_send(resp_channel, &pckt, 0);
|
||||
break;
|
||||
@ -895,7 +904,7 @@ void init_host_ikc2linux(int linux_cpu)
|
||||
param.port = 503;
|
||||
param.intr_cpu = linux_cpu;
|
||||
param.pkt_size = sizeof(struct ikc_scd_packet);
|
||||
param.queue_size = 2 * num_processors * sizeof(struct ikc_scd_packet);
|
||||
param.queue_size = 4 * num_processors * sizeof(struct ikc_scd_packet);
|
||||
if (param.queue_size < PAGE_SIZE * 4) {
|
||||
param.queue_size = PAGE_SIZE * 4;
|
||||
}
|
||||
|
||||
@ -100,6 +100,7 @@ struct cpu_local_var {
|
||||
int in_interrupt;
|
||||
int no_preempt;
|
||||
int timer_enabled;
|
||||
unsigned long nr_ctx_switches;
|
||||
int kmalloc_initialized;
|
||||
struct ihk_os_cpu_monitor *monitor;
|
||||
struct rusage_percpu *rusage;
|
||||
|
||||
@ -55,7 +55,6 @@
|
||||
#define VR_MEMTYPE_MASK 0x0f000000
|
||||
#define VR_PAGEOUT 0x10000000
|
||||
#define VR_DONTDUMP 0x20000000
|
||||
#define VR_XPMEM 0x40000000
|
||||
#define VR_WIPEONFORK 0x80000000
|
||||
|
||||
#define PROT_TO_VR_FLAG(prot) (((unsigned long)(prot) << 16) & VR_PROT_MASK)
|
||||
@ -609,6 +608,7 @@ struct thread {
|
||||
// thread info
|
||||
int cpu_id;
|
||||
int tid;
|
||||
char pthread_routine[PATH_MAX + 64];
|
||||
int status; // PS_RUNNING -> PS_EXITED (-> ZOMBIE / ptrace)
|
||||
// | ^ ^
|
||||
// | | |
|
||||
@ -718,6 +718,7 @@ struct thread {
|
||||
/* Syscall offload wait queue head */
|
||||
struct waitq scd_wq;
|
||||
|
||||
unsigned long clone_pthread_start_routine;
|
||||
int uti_state;
|
||||
int mod_clone;
|
||||
struct uti_attr *mod_clone_arg;
|
||||
@ -749,7 +750,7 @@ struct process_vm {
|
||||
void *vvar_addr;
|
||||
|
||||
ihk_spinlock_t page_table_lock;
|
||||
ihk_spinlock_t memory_range_lock;
|
||||
ihk_rwspinlock_t memory_range_lock;
|
||||
// to protect the followings:
|
||||
// 1. addition of process "memory range" (extend_process_region, add_process_memory_range)
|
||||
// 2. addition of process page table (allocate_pages, update_process_page_table)
|
||||
@ -805,7 +806,7 @@ int add_process_memory_range(struct process_vm *vm,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long phys, unsigned long flag,
|
||||
struct memobj *memobj, off_t offset,
|
||||
int pgshift, void *private_data, struct vm_range **rp);
|
||||
int pgshift, struct vm_range **rp);
|
||||
int remove_process_memory_range(struct process_vm *vm, unsigned long start,
|
||||
unsigned long end, int *ro_freedp);
|
||||
int split_process_memory_range(struct process_vm *vm,
|
||||
|
||||
@ -5,10 +5,9 @@
|
||||
#define PROFILE_ENABLE
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
#define PROFILE_SYSCALL_MAX 300
|
||||
#define PROFILE_SYSCALL_MAX 2000
|
||||
#define PROFILE_OFFLOAD_MAX (PROFILE_SYSCALL_MAX << 1)
|
||||
#define PROFILE_EVENT_MIN PROFILE_OFFLOAD_MAX
|
||||
#define __NR_profile 701
|
||||
|
||||
#define PROF_JOB 0x40000000
|
||||
#define PROF_PROC 0x80000000
|
||||
@ -47,6 +46,8 @@ enum profile_event_type {
|
||||
PROFILE_EVENT_MAX /* Should be the last event type */
|
||||
};
|
||||
|
||||
#define __NR_profile PROFILE_EVENT_MAX
|
||||
|
||||
struct thread;
|
||||
struct process;
|
||||
|
||||
|
||||
@ -27,30 +27,17 @@ static inline int rusage_pgsize_to_pgtype(size_t pgsize)
|
||||
case 12:
|
||||
ret = IHK_OS_PGSIZE_4KB;
|
||||
break;
|
||||
case 16:
|
||||
ret = IHK_OS_PGSIZE_64KB;
|
||||
break;
|
||||
case 21:
|
||||
ret = IHK_OS_PGSIZE_2MB;
|
||||
break;
|
||||
case 25:
|
||||
ret = IHK_OS_PGSIZE_32MB;
|
||||
break;
|
||||
case 30:
|
||||
ret = IHK_OS_PGSIZE_1GB;
|
||||
break;
|
||||
case 34:
|
||||
ret = IHK_OS_PGSIZE_16GB;
|
||||
break;
|
||||
case 29:
|
||||
ret = IHK_OS_PGSIZE_512MB;
|
||||
break;
|
||||
case 42:
|
||||
ret = IHK_OS_PGSIZE_4TB;
|
||||
break;
|
||||
default:
|
||||
#if 0 /* 64KB page goes here when using mckernel_rusage-compatible ihk_os_rusage */
|
||||
kprintf("%s: Error: Unknown pgsize=%ld\n",
|
||||
__func__, pgsize);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -69,24 +56,6 @@ rusage_total_memory_add(unsigned long size)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
rusage_get_total_memory()
|
||||
{
|
||||
return rusage.total_memory;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
rusage_get_free_memory()
|
||||
{
|
||||
return rusage.total_memory - rusage.total_memory_usage;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
rusage_get_usage_memory()
|
||||
{
|
||||
return rusage.total_memory_usage;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rusage_rss_add(unsigned long size)
|
||||
{
|
||||
@ -430,24 +399,6 @@ rusage_rss_add(unsigned long size)
|
||||
{
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
rusage_get_total_memory()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
rusage_get_free_memory()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
rusage_get_usage_memory()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rusage_rss_sub(unsigned long size)
|
||||
{
|
||||
|
||||
@ -287,7 +287,7 @@ struct ikc_scd_packet {
|
||||
|
||||
/* SCD_MSG_CPU_RW_REG */
|
||||
struct {
|
||||
struct ihk_os_cpu_register desc;
|
||||
unsigned long pdesc; /* Physical addr of the descriptor */
|
||||
enum mcctrl_os_cpu_operation op;
|
||||
void *resp;
|
||||
};
|
||||
@ -443,22 +443,6 @@ struct rusage {
|
||||
long ru_nivcsw;
|
||||
};
|
||||
|
||||
struct sysinfo {
|
||||
long uptime; /* Seconds since boot */
|
||||
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
|
||||
unsigned long totalram; /* Total usable main memory size */
|
||||
unsigned long freeram; /* Available memory size */
|
||||
unsigned long sharedram; /* Amount of shared memory */
|
||||
unsigned long bufferram; /* Memory used by buffers */
|
||||
unsigned long totalswap; /* Total swap space size */
|
||||
unsigned long freeswap; /* swap space still available */
|
||||
unsigned short procs; /* Number of current processes */
|
||||
unsigned long totalhigh; /* Total high memory size */
|
||||
unsigned long freehigh; /* Available high memory size */
|
||||
unsigned int mem_unit; /* Memory unit size in bytes */
|
||||
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding for libc5 */
|
||||
};
|
||||
|
||||
extern void terminate(int, int);
|
||||
|
||||
struct tod_data_s {
|
||||
@ -508,7 +492,7 @@ enum set_cputime_mode {
|
||||
void set_cputime(enum set_cputime_mode mode);
|
||||
int do_munmap(void *addr, size_t len, int holding_memory_range_lock);
|
||||
intptr_t do_mmap(uintptr_t addr0, size_t len0, int prot, int flags, int fd,
|
||||
off_t off0, const int vrf0, void *private_data);
|
||||
off_t off0);
|
||||
void clear_host_pte(uintptr_t addr, size_t len, int holding_memory_range_lock);
|
||||
typedef int32_t key_t;
|
||||
int do_shmget(key_t key, size_t size, int shmflg);
|
||||
|
||||
@ -27,20 +27,6 @@ int xpmem_remove_process_memory_range(struct process_vm *vm,
|
||||
struct vm_range *vmr);
|
||||
int xpmem_fault_process_memory_range(struct process_vm *vm,
|
||||
struct vm_range *vmr, unsigned long vaddr, uint64_t reason);
|
||||
int xpmem_update_process_page_table(struct process_vm *vm,
|
||||
struct vm_range *vmr);
|
||||
|
||||
struct xpmem_attachment {
|
||||
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 */
|
||||
|
||||
|
||||
@ -177,6 +177,19 @@ struct xpmem_access_permit {
|
||||
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 {
|
||||
ihk_atomic_t n_opened; /* # of /dev/xpmem opened */
|
||||
struct xpmem_hashlist tg_hashtable[]; /* locks + tg hash lists */
|
||||
@ -318,7 +331,6 @@ static void xpmem_ap_deref(struct xpmem_access_permit *ap);
|
||||
static void xpmem_att_deref(struct xpmem_attachment *att);
|
||||
static int xpmem_validate_access(struct xpmem_access_permit *, off_t, size_t,
|
||||
int, unsigned long *);
|
||||
static int is_remote_vm(struct process_vm *vm);
|
||||
|
||||
/*
|
||||
* Inlines that mark an internal driver structure as being destroyable or not.
|
||||
|
||||
11
kernel/mem.c
11
kernel/mem.c
@ -1276,8 +1276,9 @@ static void unhandled_page_fault(struct thread *thread, void *fault_addr,
|
||||
|
||||
range = lookup_process_memory_range(vm, address, address+1);
|
||||
if (range) {
|
||||
__kprintf("address is in range, flag: 0x%lx\n",
|
||||
range->flag);
|
||||
__kprintf("address is in range, flag: 0x%lx (%s)\n",
|
||||
range->flag,
|
||||
range->memobj ? range->memobj->path : "");
|
||||
ihk_mc_pt_print_pte(vm->address_space->page_table,
|
||||
(void *)address);
|
||||
} else {
|
||||
@ -1600,9 +1601,11 @@ static void numa_distances_init()
|
||||
static ssize_t numa_sysfs_show_meminfo(struct sysfs_ops *ops,
|
||||
void *instance, void *buf, size_t size)
|
||||
{
|
||||
#ifdef IHK_RBTREE_ALLOCATOR
|
||||
struct ihk_mc_numa_node *node =
|
||||
(struct ihk_mc_numa_node *)instance;
|
||||
char *sbuf = (char *)buf;
|
||||
#endif
|
||||
int len = 0;
|
||||
|
||||
#ifdef IHK_RBTREE_ALLOCATOR
|
||||
@ -2559,7 +2562,7 @@ void ihk_mc_query_mem_user_page(void *dump_pase_info) {
|
||||
}
|
||||
|
||||
void ihk_mc_query_mem_free_page(void *dump_pase_info) {
|
||||
|
||||
#ifdef IHK_RBTREE_ALLOCATOR
|
||||
struct free_chunk *chunk;
|
||||
struct rb_node *node;
|
||||
struct rb_root *free_chunks;
|
||||
@ -2629,7 +2632,7 @@ void ihk_mc_query_mem_free_page(void *dump_pase_info) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ ihk_spinlock_t runq_reservation_lock;
|
||||
|
||||
int idle_halt = 0;
|
||||
int allow_oversubscribe = 0;
|
||||
int time_sharing = 0;
|
||||
int time_sharing = 1;
|
||||
|
||||
void
|
||||
init_process(struct process *proc, struct process *parent)
|
||||
@ -243,7 +243,7 @@ static int
|
||||
init_process_vm(struct process *owner, struct address_space *asp, struct process_vm *vm)
|
||||
{
|
||||
int i;
|
||||
ihk_mc_spinlock_init(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_init(&vm->memory_range_lock);
|
||||
ihk_mc_spinlock_init(&vm->page_table_lock);
|
||||
|
||||
ihk_atomic_set(&vm->refcount, 1);
|
||||
@ -792,7 +792,7 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
||||
struct vm_range *last_insert;
|
||||
struct copy_args args;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&orgvm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&orgvm->memory_range_lock);
|
||||
|
||||
/* Iterate original process' vm_range list and take a copy one-by-one */
|
||||
last_insert = NULL;
|
||||
@ -854,7 +854,7 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
||||
// memory_stat_rss_add() is called in child-node, i.e. copy_user_pte()
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&orgvm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&orgvm->memory_range_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -881,7 +881,7 @@ err_rollback:
|
||||
}
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&orgvm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&orgvm->memory_range_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1316,7 +1316,7 @@ int add_process_memory_range(struct process_vm *vm,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long phys, unsigned long flag,
|
||||
struct memobj *memobj, off_t offset,
|
||||
int pgshift, void *private_data, struct vm_range **rp)
|
||||
int pgshift, struct vm_range **rp)
|
||||
{
|
||||
dkprintf("%s: start=%lx,end=%lx,phys=%lx,flag=%lx\n", __FUNCTION__, start, end, phys, flag);
|
||||
struct vm_range *range;
|
||||
@ -1344,7 +1344,7 @@ int add_process_memory_range(struct process_vm *vm,
|
||||
range->memobj = memobj;
|
||||
range->objoff = offset;
|
||||
range->pgshift = pgshift;
|
||||
range->private_data = private_data;
|
||||
range->private_data = NULL;
|
||||
|
||||
rc = 0;
|
||||
if (phys == NOPHYS) {
|
||||
@ -1356,10 +1356,6 @@ int add_process_memory_range(struct process_vm *vm,
|
||||
else if (flag & VR_IO_NOCACHE) {
|
||||
rc = update_process_page_table(vm, range, phys, PTATTR_UNCACHABLE);
|
||||
}
|
||||
else if (flag & VR_XPMEM) {
|
||||
range->memobj->flags |= MF_XPMEM;
|
||||
rc = xpmem_update_process_page_table(vm, range);
|
||||
}
|
||||
else if (flag & VR_DEMAND_PAGING) {
|
||||
dkprintf("%s: range: 0x%lx - 0x%lx is demand paging\n",
|
||||
__FUNCTION__, range->start, range->end);
|
||||
@ -1387,8 +1383,7 @@ int add_process_memory_range(struct process_vm *vm,
|
||||
}
|
||||
|
||||
/* Clear content! */
|
||||
if (phys != NOPHYS
|
||||
&& !(flag & (VR_REMOTE | VR_DEMAND_PAGING | VR_XPMEM))
|
||||
if (phys != NOPHYS && !(flag & (VR_REMOTE | VR_DEMAND_PAGING))
|
||||
&& ((flag & VR_PROT_MASK) != VR_PROT_NONE)) {
|
||||
#if 1
|
||||
memset((void *)phys_to_virt(phys), 0, end - start);
|
||||
@ -2190,7 +2185,7 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
|
||||
|
||||
if (thread->vm->is_memory_range_lock_taken == -1 ||
|
||||
thread->vm->is_memory_range_lock_taken != ihk_mc_get_processor_id()) {
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||
locked = 1;
|
||||
} else {
|
||||
dkprintf("%s: INFO: skip locking of memory_range_lock,pid=%d,tid=%d\n",
|
||||
@ -2305,7 +2300,7 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
|
||||
error = 0;
|
||||
out:
|
||||
if (locked) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
}
|
||||
dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx): %d\n",
|
||||
ihk_mc_get_processor_id(), vm, fault_addr0,
|
||||
@ -2324,10 +2319,12 @@ int page_fault_process_vm(struct process_vm *fault_vm, void *fault_addr, uint64_
|
||||
break;
|
||||
}
|
||||
|
||||
preempt_enable();
|
||||
if (thread->pgio_fp) {
|
||||
(*thread->pgio_fp)(thread->pgio_arg);
|
||||
thread->pgio_fp = NULL;
|
||||
}
|
||||
preempt_disable();
|
||||
}
|
||||
|
||||
return error;
|
||||
@ -2404,8 +2401,7 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
vrflag |= VR_MAXPROT_READ | VR_MAXPROT_WRITE | VR_MAXPROT_EXEC;
|
||||
#define NOPHYS ((uintptr_t)-1)
|
||||
if ((rc = add_process_memory_range(thread->vm, start, end, NOPHYS,
|
||||
vrflag, NULL, 0, USER_STACK_PAGE_SHIFT,
|
||||
NULL, &range)) != 0) {
|
||||
vrflag, NULL, 0, USER_STACK_PAGE_SHIFT, &range)) != 0) {
|
||||
ihk_mc_free_pages_user(stack, minsz >> PAGE_SHIFT);
|
||||
kprintf("%s: error addding process memory range: %d\n", rc);
|
||||
return rc;
|
||||
@ -2569,7 +2565,7 @@ unsigned long extend_process_region(struct process_vm *vm,
|
||||
|
||||
if ((rc = add_process_memory_range(vm, end_allocated, new_end_allocated,
|
||||
(p == 0 ? 0 : virt_to_phys(p)), flag, NULL, 0,
|
||||
align_shift, NULL, NULL)) != 0) {
|
||||
align_shift, NULL)) != 0) {
|
||||
ihk_mc_free_pages_user(p, (new_end_allocated - end_allocated) >> PAGE_SHIFT);
|
||||
return end_allocated;
|
||||
}
|
||||
@ -2609,7 +2605,7 @@ void flush_process_memory(struct process_vm *vm)
|
||||
int error;
|
||||
|
||||
dkprintf("flush_process_memory(%p)\n", vm);
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
/* Let concurrent page faults know the VM will be gone */
|
||||
vm->exiting = 1;
|
||||
while ((node = next)) {
|
||||
@ -2627,7 +2623,7 @@ void flush_process_memory(struct process_vm *vm)
|
||||
}
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
dkprintf("flush_process_memory(%p):\n", vm);
|
||||
return;
|
||||
}
|
||||
@ -2642,7 +2638,7 @@ void free_process_memory_ranges(struct process_vm *vm)
|
||||
return;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
while ((node = next)) {
|
||||
range = rb_entry(node, struct vm_range, vm_rb_node);
|
||||
next = rb_next(node);
|
||||
@ -2655,7 +2651,7 @@ void free_process_memory_ranges(struct process_vm *vm)
|
||||
/* through */
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
}
|
||||
|
||||
static void free_thread_pages(struct thread *thread)
|
||||
@ -2745,7 +2741,7 @@ free_all_process_memory_range(struct process_vm *vm)
|
||||
struct rb_node *node, *next = rb_first(&vm->vm_range_tree);
|
||||
int error;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
while ((node = next)) {
|
||||
range = rb_entry(node, struct vm_range, vm_rb_node);
|
||||
next = rb_next(node);
|
||||
@ -2758,7 +2754,7 @@ free_all_process_memory_range(struct process_vm *vm)
|
||||
/* through */
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2814,6 +2810,7 @@ int populate_process_memory(struct process_vm *vm, void *start, size_t len)
|
||||
uintptr_t addr;
|
||||
|
||||
end = (uintptr_t)start + len;
|
||||
preempt_disable();
|
||||
for (addr = (uintptr_t)start; addr < end; addr += PAGE_SIZE) {
|
||||
error = page_fault_process_vm(vm, (void *)addr, reason);
|
||||
if (error) {
|
||||
@ -2827,6 +2824,7 @@ int populate_process_memory(struct process_vm *vm, void *start, size_t len)
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
preempt_enable();
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -3189,7 +3187,7 @@ void sched_init(void)
|
||||
&idle_thread->proc->children_list);
|
||||
|
||||
ihk_mc_init_context(&idle_thread->ctx, NULL, idle);
|
||||
ihk_mc_spinlock_init(&idle_thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_init(&idle_thread->vm->memory_range_lock);
|
||||
idle_thread->vm->vm_range_tree = RB_ROOT;
|
||||
idle_thread->vm->vm_range_numa_policy_tree = RB_ROOT;
|
||||
idle_thread->proc->pid = 0;
|
||||
@ -3301,6 +3299,9 @@ static void do_migrate(void)
|
||||
__FUNCTION__, req->thread->tid, old_cpu_id, cpu_id);
|
||||
|
||||
v->flags |= CPU_FLAG_NEED_RESCHED;
|
||||
/* Kick scheduler on target CPU */
|
||||
ihk_mc_interrupt_cpu(cpu_id, ihk_mc_get_vector(IHK_GV_IKC));
|
||||
|
||||
waitq_wakeup(&req->wq);
|
||||
double_rq_unlock(cur_v, v, irqstate);
|
||||
continue;
|
||||
@ -3326,7 +3327,7 @@ void set_timer(int runq_locked)
|
||||
}
|
||||
|
||||
list_for_each_entry(thread, &v->runq, sched_list) {
|
||||
if (thread->status != PS_RUNNING) {
|
||||
if (thread->status != PS_RUNNING && !thread->spin_sleep) {
|
||||
continue;
|
||||
}
|
||||
num_running++;
|
||||
@ -3336,7 +3337,7 @@ void set_timer(int runq_locked)
|
||||
if (num_running > 1 || v->current->itimer_enabled ||
|
||||
!list_empty(&v->backlog_list)) {
|
||||
if (!cpu_local_var(timer_enabled)) {
|
||||
lapic_timer_enable(/*10000000*/1000000);
|
||||
lapic_timer_enable(1000000);
|
||||
cpu_local_var(timer_enabled) = 1;
|
||||
}
|
||||
}
|
||||
@ -3516,8 +3517,11 @@ void schedule(void)
|
||||
set_timer(1);
|
||||
|
||||
if (switch_ctx) {
|
||||
dkprintf("schedule: %d => %d \n",
|
||||
prev ? prev->tid : 0, next ? next->tid : 0);
|
||||
++cpu_local_var(nr_ctx_switches);
|
||||
dkprintf("%s: %d => %d [ctx sws: %lu]\n",
|
||||
__func__,
|
||||
prev ? prev->tid : 0, next ? next->tid : 0,
|
||||
cpu_local_var(nr_ctx_switches));
|
||||
|
||||
if (prev && prev->ptrace_debugreg) {
|
||||
save_debugreg(prev->ptrace_debugreg);
|
||||
@ -3677,6 +3681,11 @@ int __sched_wakeup_thread(struct thread *thread,
|
||||
|
||||
/* Make interrupt_exit() call schedule() */
|
||||
v->flags |= CPU_FLAG_NEED_RESCHED;
|
||||
|
||||
/* Make sure to check if timer needs to be re-enabled */
|
||||
if (thread->cpu_id == ihk_mc_get_processor_id()) {
|
||||
set_timer(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
status = -EINVAL;
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
#include <mman.h>
|
||||
#include <bitmap.h>
|
||||
#include <init.h>
|
||||
#include <rusage_private.h>
|
||||
|
||||
//#define DEBUG_PRINT_PROCFS
|
||||
|
||||
@ -360,28 +359,6 @@ static int _process_procfs_request(struct ikc_scd_packet *rpacket, int *result)
|
||||
goto end;
|
||||
}
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_42 */
|
||||
else if (!strcmp(p, "meminfo")) {
|
||||
ans = snprintf(buf, count,
|
||||
"MemTotal: %10d kB\n"
|
||||
"MemFree: %10d kB\n"
|
||||
"SwapTotal: %10d kB\n"
|
||||
"SwapFree: %10d kB\n"
|
||||
"CommitLimit: %10d kB\n"
|
||||
"Committed_AS: %10d kB\n",
|
||||
rusage_get_total_memory() >> 10,
|
||||
rusage_get_free_memory() >> 10,
|
||||
0, 0,
|
||||
rusage_get_free_memory() >> 10,
|
||||
rusage_get_usage_memory() >> 10);
|
||||
|
||||
if (ans < 0 || ans > count ||
|
||||
buf_add(&buf_top, &buf_cur, buf, ans) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ans = 0;
|
||||
goto end;
|
||||
}
|
||||
else {
|
||||
kprintf("unsupported procfs entry: %s\n", p);
|
||||
goto end;
|
||||
@ -459,7 +436,7 @@ static int _process_procfs_request(struct ikc_scd_packet *rpacket, int *result)
|
||||
if (strcmp(p, "maps") == 0) {
|
||||
struct vm_range *range;
|
||||
|
||||
if (!ihk_mc_spinlock_trylock_noirq(&vm->memory_range_lock)) {
|
||||
if (!ihk_rwspinlock_read_trylock_noirq(&vm->memory_range_lock)) {
|
||||
if (!result) {
|
||||
if ((err = procfs_backlog(vm, rpacket))) {
|
||||
goto err;
|
||||
@ -505,14 +482,14 @@ static int _process_procfs_request(struct ikc_scd_packet *rpacket, int *result)
|
||||
|
||||
if (ans < 0 || ans > count ||
|
||||
buf_add(&buf_top, &buf_cur, buf, ans) < 0) {
|
||||
ihk_mc_spinlock_unlock_noirq(
|
||||
ihk_rwspinlock_read_unlock_noirq(
|
||||
&vm->memory_range_lock);
|
||||
goto err;
|
||||
}
|
||||
range = next_process_memory_range(vm, range);
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
ans = 0;
|
||||
goto end;
|
||||
@ -535,7 +512,7 @@ static int _process_procfs_request(struct ikc_scd_packet *rpacket, int *result)
|
||||
start = (offset / sizeof(uint64_t)) << PAGE_SHIFT;
|
||||
end = start + ((count / sizeof(uint64_t)) << PAGE_SHIFT);
|
||||
|
||||
if (!ihk_mc_spinlock_trylock_noirq(&vm->memory_range_lock)) {
|
||||
if (!ihk_rwspinlock_read_trylock_noirq(&vm->memory_range_lock)) {
|
||||
if (!result) {
|
||||
if ((err = procfs_backlog(vm, rpacket))) {
|
||||
goto err;
|
||||
@ -555,7 +532,7 @@ static int _process_procfs_request(struct ikc_scd_packet *rpacket, int *result)
|
||||
++_buf;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
dprintf("/proc/pagemap: 0x%lx - 0x%lx, count: %d\n",
|
||||
start, end, count);
|
||||
@ -587,7 +564,7 @@ static int _process_procfs_request(struct ikc_scd_packet *rpacket, int *result)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ihk_mc_spinlock_trylock_noirq(&vm->memory_range_lock)) {
|
||||
if (!ihk_rwspinlock_read_trylock_noirq(&vm->memory_range_lock)) {
|
||||
if (!result) {
|
||||
if ((err = procfs_backlog(vm, rpacket))) {
|
||||
goto err;
|
||||
@ -604,7 +581,7 @@ static int _process_procfs_request(struct ikc_scd_packet *rpacket, int *result)
|
||||
lockedsize += range->end - range->start;
|
||||
range = next_process_memory_range(vm, range);
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
cpu_bitmask = &bitmasks[bitmasks_offset];
|
||||
bitmasks_offset += bitmap_scnprintf(cpu_bitmask,
|
||||
|
||||
263
kernel/profile.c
263
kernel/profile.c
@ -106,153 +106,108 @@ void profile_event_add(enum profile_event_type type, uint64_t tsc)
|
||||
event->tsc += tsc;
|
||||
}
|
||||
|
||||
void profile_print_thread_stats(struct thread *thread)
|
||||
static void print_profile_events(struct profile_event *profile_events,
|
||||
char *full_hdr_fmt,
|
||||
char *hdr_prefix,
|
||||
int id,
|
||||
unsigned long elapsed_ts)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
flags = kprintf_lock();
|
||||
__kprintf(full_hdr_fmt, id, elapsed_ts / 1000);
|
||||
|
||||
__kprintf("%3s: %5s (%3s,%20s): %6s %7s offl: %6s %7s (%6s)\n",
|
||||
"ID", "<num>", "num", "(syscall/event) name", "cnt",
|
||||
"cycles", "cnt", "cycles", "perc");
|
||||
|
||||
for (i = 0; i < PROFILE_SYSCALL_MAX; ++i) {
|
||||
if (!profile_events[i].cnt &&
|
||||
!profile_events[i + PROFILE_SYSCALL_MAX].cnt)
|
||||
continue;
|
||||
|
||||
__kprintf("%s: %4d (%3d,%20s): %6u %6luk "
|
||||
"offl: %6u %6luk (%2d.%2d%%)\n",
|
||||
hdr_prefix,
|
||||
id,
|
||||
i,
|
||||
syscall_name[i],
|
||||
profile_events[i].cnt,
|
||||
profile_events[i].tsc / 1000,
|
||||
profile_events[i + PROFILE_SYSCALL_MAX].cnt,
|
||||
profile_events[i + PROFILE_SYSCALL_MAX].tsc /
|
||||
1000,
|
||||
(profile_events[i].tsc ?
|
||||
profile_events[i].tsc * 100
|
||||
/ elapsed_ts : 0),
|
||||
(profile_events[i].tsc ?
|
||||
(profile_events[i].tsc * 10000
|
||||
/ elapsed_ts) % 100 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
for (i = PROFILE_EVENT_MIN; i < PROFILE_EVENT_MAX; ++i) {
|
||||
if (!profile_events[i].cnt)
|
||||
continue;
|
||||
|
||||
__kprintf("%s: %4d (%24s): %6u %6lu\n",
|
||||
hdr_prefix,
|
||||
id,
|
||||
profile_event_names[i - PROFILE_EVENT_MIN],
|
||||
profile_events[i].cnt,
|
||||
(profile_events[i].tsc /
|
||||
(profile_events[i].cnt ?
|
||||
profile_events[i].cnt : 1))
|
||||
,
|
||||
(profile_events[i].tsc &&
|
||||
elapsed_ts ?
|
||||
profile_events[i].tsc * 100
|
||||
/ elapsed_ts : 0),
|
||||
(profile_events[i].tsc &&
|
||||
elapsed_ts ?
|
||||
(profile_events[i].tsc * 10000
|
||||
/ elapsed_ts) % 100 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
kprintf_unlock(flags);
|
||||
}
|
||||
|
||||
|
||||
void profile_print_thread_stats(struct thread *thread)
|
||||
{
|
||||
if (!thread->profile_events)
|
||||
return;
|
||||
|
||||
/* Not yet accumulated period? */
|
||||
if (thread->profile_start_ts) {
|
||||
thread->profile_elapsed_ts += (rdtsc() - thread->profile_start_ts);
|
||||
thread->profile_elapsed_ts += (rdtsc() -
|
||||
thread->profile_start_ts);
|
||||
}
|
||||
|
||||
flags = kprintf_lock();
|
||||
|
||||
__kprintf("TID: %4d elapsed cycles (excluding idle): %luk\n",
|
||||
print_profile_events(thread->profile_events,
|
||||
"TID: %4d elapsed cycles (excluding idle): %luk\n",
|
||||
"TID",
|
||||
thread->tid,
|
||||
thread->profile_elapsed_ts / 1000);
|
||||
|
||||
for (i = 0; i < PROFILE_SYSCALL_MAX; ++i) {
|
||||
if (!thread->profile_events[i].cnt &&
|
||||
!thread->profile_events[i + PROFILE_SYSCALL_MAX].cnt)
|
||||
continue;
|
||||
|
||||
__kprintf("TID: %4d (%3d,%20s): %6u %6luk offl: %6u %6luk (%2d.%2d%%)\n",
|
||||
thread->tid,
|
||||
i,
|
||||
syscall_name[i],
|
||||
thread->profile_events[i].cnt,
|
||||
(thread->profile_events[i].tsc /
|
||||
(thread->profile_events[i].cnt ?
|
||||
thread->profile_events[i].cnt : 1))
|
||||
/ 1000,
|
||||
thread->profile_events[i + PROFILE_SYSCALL_MAX].cnt,
|
||||
(thread->profile_events[i + PROFILE_SYSCALL_MAX].tsc /
|
||||
(thread->profile_events[i + PROFILE_SYSCALL_MAX].cnt ?
|
||||
thread->profile_events[i + PROFILE_SYSCALL_MAX].cnt : 1))
|
||||
/ 1000,
|
||||
(thread->profile_events[i].tsc ?
|
||||
thread->profile_events[i].tsc * 100
|
||||
/ thread->profile_elapsed_ts : 0),
|
||||
(thread->profile_events[i].tsc ?
|
||||
(thread->profile_events[i].tsc * 10000
|
||||
/ thread->profile_elapsed_ts) % 100 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
for (i = PROFILE_EVENT_MIN; i < PROFILE_EVENT_MAX; ++i) {
|
||||
|
||||
if (!thread->profile_events[i].cnt)
|
||||
continue;
|
||||
|
||||
__kprintf("TID: %4d (%24s): %6u %6luk \n",
|
||||
thread->tid,
|
||||
profile_event_names[i - PROFILE_EVENT_MIN],
|
||||
thread->profile_events[i].cnt,
|
||||
(thread->profile_events[i].tsc /
|
||||
(thread->profile_events[i].cnt ?
|
||||
thread->profile_events[i].cnt : 1))
|
||||
/ 1000,
|
||||
(thread->profile_events[i].tsc ?
|
||||
thread->profile_events[i].tsc * 100
|
||||
/ thread->profile_elapsed_ts : 0),
|
||||
(thread->profile_events[i].tsc ?
|
||||
(thread->profile_events[i].tsc * 10000
|
||||
/ thread->profile_elapsed_ts) % 100 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
kprintf_unlock(flags);
|
||||
thread->profile_elapsed_ts);
|
||||
}
|
||||
|
||||
void profile_print_proc_stats(struct process *proc)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
if (!proc->profile_events || !proc->profile_elapsed_ts)
|
||||
return;
|
||||
|
||||
flags = kprintf_lock();
|
||||
__kprintf("PID: %4d elapsed cycles for all threads (excluding idle): %luk\n",
|
||||
print_profile_events(proc->profile_events,
|
||||
"PID: %4d elapsed cycles for all threads (excluding idle): %luk\n",
|
||||
"PID",
|
||||
proc->pid,
|
||||
proc->profile_elapsed_ts / 1000);
|
||||
|
||||
for (i = 0; i < PROFILE_SYSCALL_MAX; ++i) {
|
||||
if (!proc->profile_events[i].cnt &&
|
||||
!proc->profile_events[i + PROFILE_SYSCALL_MAX].cnt)
|
||||
continue;
|
||||
|
||||
__kprintf("PID: %4d (%3d,%20s): %6u %6luk offl: %6u %6luk (%2d.%2d%%)\n",
|
||||
proc->pid,
|
||||
i,
|
||||
syscall_name[i],
|
||||
proc->profile_events[i].cnt,
|
||||
(proc->profile_events[i].tsc /
|
||||
(proc->profile_events[i].cnt ?
|
||||
proc->profile_events[i].cnt : 1))
|
||||
/ 1000,
|
||||
proc->profile_events[i + PROFILE_SYSCALL_MAX].cnt,
|
||||
(proc->profile_events[i + PROFILE_SYSCALL_MAX].tsc /
|
||||
(proc->profile_events[i + PROFILE_SYSCALL_MAX].cnt ?
|
||||
proc->profile_events[i + PROFILE_SYSCALL_MAX].cnt : 1))
|
||||
/ 1000,
|
||||
(proc->profile_events[i].tsc ?
|
||||
proc->profile_events[i].tsc * 100
|
||||
/ proc->profile_elapsed_ts : 0),
|
||||
(proc->profile_events[i].tsc ?
|
||||
(proc->profile_events[i].tsc * 10000
|
||||
/ proc->profile_elapsed_ts) % 100 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
for (i = PROFILE_EVENT_MIN; i < PROFILE_EVENT_MAX; ++i) {
|
||||
|
||||
if (!proc->profile_events[i].cnt)
|
||||
continue;
|
||||
|
||||
// __kprintf("PID: %4d (%24s): %6u %6luk \n",
|
||||
__kprintf("PID: %4d (%24s): %6u %6lu \n",
|
||||
proc->pid,
|
||||
profile_event_names[i - PROFILE_EVENT_MIN],
|
||||
proc->profile_events[i].cnt,
|
||||
(proc->profile_events[i].tsc /
|
||||
(proc->profile_events[i].cnt ?
|
||||
proc->profile_events[i].cnt : 1))
|
||||
// / 1000
|
||||
,
|
||||
(proc->profile_events[i].tsc &&
|
||||
proc->profile_elapsed_ts ?
|
||||
proc->profile_events[i].tsc * 100
|
||||
/ proc->profile_elapsed_ts : 0),
|
||||
(proc->profile_events[i].tsc &&
|
||||
proc->profile_elapsed_ts ?
|
||||
(proc->profile_events[i].tsc * 10000
|
||||
/ proc->profile_elapsed_ts) % 100 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
kprintf_unlock(flags);
|
||||
proc->profile_elapsed_ts);
|
||||
}
|
||||
|
||||
int profile_accumulate_and_print_job_events(struct process *proc)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
struct mcs_lock_node mcs_node;
|
||||
|
||||
mcs_lock_lock(&job_profile_lock, &mcs_node);
|
||||
@ -297,68 +252,20 @@ int profile_accumulate_and_print_job_events(struct process *proc)
|
||||
|
||||
/* Last process? */
|
||||
if (job_nr_processes_left == 0) {
|
||||
flags = kprintf_lock();
|
||||
__kprintf("JOB: (%2d) elapsed cycles for all threads (excluding idle): %luk\n",
|
||||
|
||||
print_profile_events(job_profile_events,
|
||||
"JOB: (%2d) elapsed cycles for all threads (excluding idle): %luk\n",
|
||||
"JOB",
|
||||
job_nr_processes,
|
||||
job_elapsed_ts / 1000);
|
||||
|
||||
for (i = 0; i < PROFILE_SYSCALL_MAX; ++i) {
|
||||
if (!job_profile_events[i].cnt &&
|
||||
!job_profile_events[i + PROFILE_SYSCALL_MAX].cnt)
|
||||
continue;
|
||||
|
||||
__kprintf("JOB: (%2d) (%3d,%20s): %6u %6luk offl: %6u %6luk (%2d.%2d%%)\n",
|
||||
job_nr_processes,
|
||||
i,
|
||||
syscall_name[i],
|
||||
job_profile_events[i].cnt,
|
||||
(job_profile_events[i].tsc /
|
||||
(job_profile_events[i].cnt ?
|
||||
job_profile_events[i].cnt : 1))
|
||||
/ 1000,
|
||||
job_profile_events[i + PROFILE_SYSCALL_MAX].cnt,
|
||||
(job_profile_events[i + PROFILE_SYSCALL_MAX].tsc /
|
||||
(job_profile_events[i + PROFILE_SYSCALL_MAX].cnt ?
|
||||
job_profile_events[i + PROFILE_SYSCALL_MAX].cnt : 1))
|
||||
/ 1000,
|
||||
(job_profile_events[i].tsc ?
|
||||
job_profile_events[i].tsc * 100
|
||||
/ job_elapsed_ts : 0),
|
||||
(job_profile_events[i].tsc ?
|
||||
(job_profile_events[i].tsc * 10000
|
||||
/ job_elapsed_ts) % 100 : 0)
|
||||
);
|
||||
|
||||
job_profile_events[i].tsc = 0;
|
||||
job_profile_events[i].cnt = 0;
|
||||
job_profile_events[i + PROFILE_SYSCALL_MAX].tsc = 0;
|
||||
job_profile_events[i + PROFILE_SYSCALL_MAX].cnt = 0;
|
||||
}
|
||||
|
||||
for (i = PROFILE_EVENT_MIN; i < PROFILE_EVENT_MAX; ++i) {
|
||||
|
||||
if (!job_profile_events[i].cnt)
|
||||
continue;
|
||||
|
||||
__kprintf("JOB: (%2d) (%24s): %6u %6luk \n",
|
||||
job_nr_processes,
|
||||
profile_event_names[i - PROFILE_EVENT_MIN],
|
||||
job_profile_events[i].cnt,
|
||||
(job_profile_events[i].tsc /
|
||||
(job_profile_events[i].cnt ?
|
||||
job_profile_events[i].cnt : 1))
|
||||
/ 1000);
|
||||
|
||||
job_profile_events[i].tsc = 0;
|
||||
job_profile_events[i].cnt = 0;
|
||||
}
|
||||
|
||||
kprintf_unlock(flags);
|
||||
job_elapsed_ts);
|
||||
|
||||
/* Reset job process indicators */
|
||||
job_nr_processes = -1;
|
||||
job_nr_processes_left = -1;
|
||||
job_elapsed_ts = 0;
|
||||
|
||||
memset(job_profile_events, 0, sizeof(*job_profile_events) *
|
||||
PROFILE_EVENT_MAX);
|
||||
}
|
||||
|
||||
mcs_lock_unlock(&job_profile_lock, &mcs_node);
|
||||
|
||||
299
kernel/syscall.c
299
kernel/syscall.c
@ -159,7 +159,7 @@ static void send_syscall(struct syscall_request *req, int cpu,
|
||||
memcpy(&packet.req, req, sizeof(*req));
|
||||
|
||||
barrier();
|
||||
packet.req.valid = 1;
|
||||
smp_store_release(&packet.req.valid, 1);
|
||||
|
||||
#ifdef SYSCALL_BY_IKC
|
||||
packet.msg = SCD_MSG_SYSCALL_ONESIDE;
|
||||
@ -234,14 +234,19 @@ long do_syscall(struct syscall_request *req, int cpu)
|
||||
#define STATUS_COMPLETED 1
|
||||
#define STATUS_PAGE_FAULT 3
|
||||
#define STATUS_SYSCALL 4
|
||||
while (res.status != STATUS_COMPLETED) {
|
||||
while (res.status == STATUS_IN_PROGRESS) {
|
||||
while (smp_load_acquire(&res.status) != STATUS_COMPLETED) {
|
||||
while (smp_load_acquire(&res.status) == STATUS_IN_PROGRESS) {
|
||||
struct cpu_local_var *v;
|
||||
int do_schedule = 0;
|
||||
long runq_irqstate;
|
||||
unsigned long flags;
|
||||
DECLARE_WAITQ_ENTRY(scd_wq_entry, cpu_local_var(current));
|
||||
|
||||
if (req->number == __NR_epoll_wait ||
|
||||
req->number == __NR_epoll_pwait ||
|
||||
req->number == __NR_ppoll)
|
||||
goto schedule;
|
||||
|
||||
cpu_pause();
|
||||
|
||||
/* Spin if not preemptable */
|
||||
@ -270,13 +275,16 @@ long do_syscall(struct syscall_request *req, int cpu)
|
||||
continue;
|
||||
}
|
||||
|
||||
schedule:
|
||||
flags = cpu_disable_interrupt_save();
|
||||
|
||||
/* Try to sleep until notified */
|
||||
if (res.req_thread_status == IHK_SCD_REQ_THREAD_DESCHEDULED ||
|
||||
__sync_bool_compare_and_swap(&res.req_thread_status,
|
||||
if (smp_load_acquire(&res.req_thread_status) ==
|
||||
IHK_SCD_REQ_THREAD_DESCHEDULED ||
|
||||
(cmpxchg(&res.req_thread_status,
|
||||
IHK_SCD_REQ_THREAD_SPINNING,
|
||||
IHK_SCD_REQ_THREAD_DESCHEDULED)) {
|
||||
IHK_SCD_REQ_THREAD_DESCHEDULED) ==
|
||||
IHK_SCD_REQ_THREAD_SPINNING)) {
|
||||
dkprintf("%s: tid %d waiting for syscall reply...\n",
|
||||
__FUNCTION__, thread->tid);
|
||||
waitq_init(&thread->scd_wq);
|
||||
@ -285,6 +293,7 @@ long do_syscall(struct syscall_request *req, int cpu)
|
||||
cpu_restore_interrupt(flags);
|
||||
schedule();
|
||||
waitq_finish_wait(&thread->scd_wq, &scd_wq_entry);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (do_schedule) {
|
||||
@ -300,7 +309,7 @@ long do_syscall(struct syscall_request *req, int cpu)
|
||||
cpu_restore_interrupt(flags);
|
||||
}
|
||||
|
||||
if (res.status == STATUS_SYSCALL) {
|
||||
if (smp_load_acquire(&res.status) == STATUS_SYSCALL) {
|
||||
struct syscall_request *requestp;
|
||||
struct syscall_request request;
|
||||
int num;
|
||||
@ -1125,8 +1134,8 @@ void terminate_mcexec(int rc, int sig)
|
||||
if ((old_exit_status = proc->group_exit_status) & 0x0000000100000000L)
|
||||
return;
|
||||
exit_status = 0x0000000100000000L | ((rc & 0x00ff) << 8) | (sig & 0xff);
|
||||
if (!__sync_bool_compare_and_swap(&proc->group_exit_status,
|
||||
old_exit_status, exit_status))
|
||||
if (cmpxchg(&proc->group_exit_status,
|
||||
old_exit_status, exit_status) != old_exit_status)
|
||||
return;
|
||||
if (!proc->nohost) {
|
||||
request.number = __NR_exit_group;
|
||||
@ -1590,12 +1599,6 @@ static int search_free_space(size_t len, int pgshift, uintptr_t *addrp)
|
||||
/* try given addr first */
|
||||
addr = *addrp;
|
||||
if (addr != 0) {
|
||||
if ((region->user_end <= addr)
|
||||
|| ((region->user_end - len) < addr)) {
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
range = lookup_process_memory_range(thread->vm, addr, addr+len);
|
||||
if (range == NULL)
|
||||
goto out;
|
||||
@ -1631,8 +1634,7 @@ out:
|
||||
|
||||
intptr_t
|
||||
do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
const int flags, const int fd, const off_t off0,
|
||||
const int vrf0, void *private_data)
|
||||
const int flags, const int fd, const off_t off0)
|
||||
{
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
struct vm_regions *region = &thread->vm->region;
|
||||
@ -1689,10 +1691,12 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
|
||||
if (flags & MAP_HUGETLB) {
|
||||
pgshift = (flags >> MAP_HUGE_SHIFT) & 0x3F;
|
||||
if (!pgshift) {
|
||||
pgshift = ihk_mc_get_linux_default_huge_page_shift();
|
||||
}
|
||||
p2align = pgshift - PAGE_SHIFT;
|
||||
}
|
||||
else if ((((flags & MAP_PRIVATE) && (flags & MAP_ANONYMOUS))
|
||||
|| (vrf0 & VR_XPMEM))
|
||||
else if ((flags & MAP_PRIVATE) && (flags & MAP_ANONYMOUS)
|
||||
&& !proc->thp_disable) {
|
||||
pgshift = 0; /* transparent huge page */
|
||||
p2align = PAGE_P2ALIGN;
|
||||
@ -1710,7 +1714,7 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
p2align = PAGE_P2ALIGN;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
if (flags & MAP_FIXED) {
|
||||
/* clear specified address range */
|
||||
@ -1723,29 +1727,7 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
}
|
||||
else if (flags & MAP_ANONYMOUS) {
|
||||
/* Obtain mapping address */
|
||||
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);
|
||||
}
|
||||
error = search_free_space(len, PAGE_SHIFT + p2align, &addr);
|
||||
if (error) {
|
||||
ekprintf("do_mmap:search_free_space(%lx,%lx,%d) failed. %d\n",
|
||||
len, region->map_end, p2align, error);
|
||||
@ -1755,13 +1737,12 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
|
||||
/* do the map */
|
||||
vrflags = VR_NONE;
|
||||
vrflags |= vrf0;
|
||||
vrflags |= PROT_TO_VR_FLAG(prot);
|
||||
vrflags |= (flags & MAP_PRIVATE)? VR_PRIVATE: 0;
|
||||
vrflags |= (flags & MAP_LOCKED)? VR_LOCKED: 0;
|
||||
vrflags |= VR_DEMAND_PAGING;
|
||||
if (flags & MAP_ANONYMOUS && !anon_on_demand) {
|
||||
if (flags & MAP_PRIVATE || vrflags & VR_XPMEM) {
|
||||
if (flags & MAP_ANONYMOUS) {
|
||||
if (!anon_on_demand && (flags & MAP_PRIVATE)) {
|
||||
vrflags &= ~VR_DEMAND_PAGING;
|
||||
}
|
||||
}
|
||||
@ -1770,6 +1751,7 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
populated_mapping = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX: Intel MPI 128MB mapping.. */
|
||||
if (len == 134217728) {
|
||||
dkprintf("%s: %ld bytes mapping -> no prefault\n",
|
||||
@ -1777,6 +1759,7 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
vrflags |= VR_DEMAND_PAGING;
|
||||
populated_mapping = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((flags & MAP_ANONYMOUS) && !(prot & PROT_WRITE)) {
|
||||
error = set_host_vma(addr, len, PROT_READ | PROT_EXEC, 1/* holding memory_range_lock */);
|
||||
@ -1795,6 +1778,14 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
off = off0;
|
||||
error = fileobj_create(fd, &memobj, &maxprot,
|
||||
flags, addr0);
|
||||
if (memobj && memobj->path && !strncmp(memobj->path, "/dev/shm/ucx_posix", 18)) {
|
||||
kprintf("%s: mmap flags: %lx, path: %s, memobj->flags: %lx, "
|
||||
"pgshift: %d, p2align: %d -> FIXING page size\n",
|
||||
__func__, flags, memobj->path, memobj->flags, pgshift, p2align);
|
||||
pgshift = PAGE_SHIFT;
|
||||
p2align = PAGE_P2ALIGN;
|
||||
populated_mapping = 1;
|
||||
}
|
||||
#ifdef ATTACHED_MIC
|
||||
/*
|
||||
* XXX: refuse device mapping in attached-mic now:
|
||||
@ -1831,6 +1822,13 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
#ifdef PROFILE_ENABLE
|
||||
profile_event_add(PROFILE_mmap_device_file, len);
|
||||
#endif // PROFILE_ENABLE
|
||||
if (memobj->path &&
|
||||
(!strncmp("/tmp/ompi.", memobj->path, 10) ||
|
||||
!strncmp("/dev/shm/", memobj->path, 9))) {
|
||||
pgshift = PAGE_SHIFT;
|
||||
p2align = PAGE_P2ALIGN;
|
||||
populated_mapping = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
@ -1884,7 +1882,6 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
}
|
||||
/* Prepopulated ANONYMOUS mapping */
|
||||
else if (!(vrflags & VR_DEMAND_PAGING)
|
||||
&& !(flags & MAP_SHARED)
|
||||
&& ((vrflags & VR_PROT_MASK) != VR_PROT_NONE)) {
|
||||
npages = len >> PAGE_SHIFT;
|
||||
/* Small allocations mostly benefit from closest RAM,
|
||||
@ -1963,7 +1960,7 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
vrflags |= VRFLAG_PROT_TO_MAXPROT(PROT_TO_VR_FLAG(maxprot));
|
||||
|
||||
error = add_process_memory_range(thread->vm, addr, addr+len, phys,
|
||||
vrflags, memobj, off, pgshift, private_data, &range);
|
||||
vrflags, memobj, off, pgshift, &range);
|
||||
if (error) {
|
||||
kprintf("%s: add_process_memory_range failed for 0x%lx:%lu"
|
||||
" flags: %lx, vrflags: %lx, pgshift: %d, error: %d\n",
|
||||
@ -1976,14 +1973,15 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
populate_len = memobj ? min(len, memobj->size) : len;
|
||||
|
||||
if (!(flags & MAP_ANONYMOUS)) {
|
||||
if (atomic_cmpxchg4(&memobj->status, MEMOBJ_TO_BE_PREFETCHED,
|
||||
MEMOBJ_READY)) {
|
||||
if (cmpxchg(&memobj->status, MEMOBJ_TO_BE_PREFETCHED,
|
||||
MEMOBJ_READY) == MEMOBJ_TO_BE_PREFETCHED) {
|
||||
populated_mapping = 1;
|
||||
}
|
||||
|
||||
/* Update PTEs for pre-mapped memory object */
|
||||
if ((memobj->flags & MF_PREMAP) &&
|
||||
(proc->mpol_flags & MPOL_SHM_PREMAP)) {
|
||||
if (memobj->flags & MF_ZEROFILL) {
|
||||
int i;
|
||||
enum ihk_mc_pt_attribute ptattr;
|
||||
ptattr = arch_vrflag_to_ptattr(range->flag, PF_POPULATE, NULL);
|
||||
@ -2007,6 +2005,10 @@ do_mmap(const uintptr_t addr0, const size_t len0, const int prot,
|
||||
dkprintf("%s: memobj 0x%lx pre-mapped\n", __FUNCTION__, memobj);
|
||||
// fileobj && MF_PREMAP && MPOL_SHM_PREMAP case: memory_stat_rss_add() is called in fileobj_create()
|
||||
}
|
||||
else {
|
||||
populated_mapping = 1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if (memobj->flags & MF_REG_FILE) {
|
||||
populated_mapping = 1;
|
||||
@ -2024,7 +2026,7 @@ out:
|
||||
if (ro_vma_mapped) {
|
||||
(void)set_host_vma(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC, 1/* holding memory_range_lock */);
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
if (!error && populated_mapping && !((vrflags & VR_PROT_MASK) == VR_PROT_NONE)) {
|
||||
error = populate_process_memory(thread->vm,
|
||||
@ -2092,9 +2094,9 @@ SYSCALL_DECLARE(munmap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&thread->vm->memory_range_lock);
|
||||
error = do_munmap((void *)addr, len, 1/* holding memory_range_lock */);
|
||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
out:
|
||||
dkprintf("[%d]sys_munmap(%lx,%lx): %d\n",
|
||||
@ -2148,7 +2150,7 @@ SYSCALL_DECLARE(mprotect)
|
||||
|
||||
flush_nfo_tlb();
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
first = lookup_process_memory_range(thread->vm, start, start+PAGE_SIZE);
|
||||
|
||||
@ -2238,7 +2240,7 @@ out:
|
||||
/* through */
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
dkprintf("[%d]sys_mprotect(%lx,%lx,%x): %d\n",
|
||||
ihk_mc_get_processor_id(), start, len0, prot, error);
|
||||
return error;
|
||||
@ -2281,11 +2283,11 @@ SYSCALL_DECLARE(brk)
|
||||
vrflag |= VR_PRIVATE;
|
||||
vrflag |= VRFLAG_PROT_TO_MAXPROT(vrflag);
|
||||
old_brk_end_allocated = region->brk_end_allocated;
|
||||
ihk_mc_spinlock_lock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||
region->brk_end_allocated =
|
||||
extend_process_region(cpu_local_var(current)->vm,
|
||||
region->brk_end_allocated, address, vrflag);
|
||||
ihk_mc_spinlock_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||
|
||||
if (old_brk_end_allocated == region->brk_end_allocated) {
|
||||
r = old_brk_end_allocated;
|
||||
@ -2510,7 +2512,7 @@ static void munmap_all(void)
|
||||
size_t size;
|
||||
int error;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
next = lookup_process_memory_range(vm, 0, -1);
|
||||
while ((range = next)) {
|
||||
next = next_process_memory_range(vm, range);
|
||||
@ -2524,7 +2526,7 @@ static void munmap_all(void)
|
||||
/* through */
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
/* free vm_ranges which do_munmap() failed to remove. */
|
||||
free_process_memory_ranges(thread->vm);
|
||||
@ -2554,18 +2556,18 @@ static int do_execveat(ihk_mc_user_context_t *ctx, int dirfd,
|
||||
struct process *proc = thread->proc;
|
||||
int i;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
range = lookup_process_memory_range(vm, (unsigned long)filename,
|
||||
(unsigned long)filename+1);
|
||||
|
||||
if (range == NULL || !(range->flag & VR_PROT_READ)) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
kprintf("execve(): ERROR: filename is bad address\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
desc = ihk_mc_alloc_pages(4, IHK_MC_AP_NOWAIT);
|
||||
if (!desc) {
|
||||
@ -2751,8 +2753,13 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
struct syscall_request request1 IHK_DMA_ALIGN;
|
||||
int ptrace_event = 0;
|
||||
int termsig = clone_flags & 0x000000ff;
|
||||
#if 0
|
||||
const struct ihk_mc_cpu_info *cpu_info = ihk_mc_get_cpu_info();
|
||||
#endif
|
||||
int err = 0;
|
||||
unsigned long clone_pthread_start_routine = 0;
|
||||
struct vm_range *range = NULL;
|
||||
int helper_thread = 0;
|
||||
|
||||
dkprintf("%s,flags=%08x,newsp=%lx,ptidptr=%lx,"
|
||||
"ctidptr=%lx,tls=%lx,curpc=%lx,cursp=%lx",
|
||||
@ -2762,6 +2769,18 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
dkprintf("do_fork(): stack_pointr passed in: 0x%lX, stack pointer of caller: 0x%lx\n",
|
||||
newsp, cursp);
|
||||
|
||||
/* CLONE_VM and newsp == parent_tidptr impiles pthread start routine addr */
|
||||
if ((clone_flags & CLONE_VM) && newsp == parent_tidptr) {
|
||||
old->clone_pthread_start_routine = parent_tidptr;
|
||||
dkprintf("%s: clone_pthread_start_routine: 0x%lx\n", __func__,
|
||||
old->clone_pthread_start_routine);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Clear pthread routine addr regardless if we succeed */
|
||||
clone_pthread_start_routine = old->clone_pthread_start_routine;
|
||||
old->clone_pthread_start_routine = 0;
|
||||
|
||||
parent_cpuid = old->cpu_id;
|
||||
if (((clone_flags & CLONE_VM) && !(clone_flags & CLONE_THREAD)) ||
|
||||
(!(clone_flags & CLONE_VM) && (clone_flags & CLONE_THREAD))) {
|
||||
@ -2794,10 +2813,12 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!allow_oversubscribe && rusage.num_threads >= cpu_info->ncpus) {
|
||||
kprintf("%s: ERROR: CPU oversubscription is not allowed. Specify -O option in mcreboot.sh to allow it.\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (oldproc->coredump_barrier_count) {
|
||||
return -EINVAL;
|
||||
@ -2815,11 +2836,36 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
}
|
||||
}
|
||||
|
||||
cpuid = obtain_clone_cpuid(&old->cpu_set, old->mod_clone == SPAWN_TO_REMOTE && oldproc->uti_use_last_cpu);
|
||||
if (clone_pthread_start_routine) {
|
||||
ihk_rwspinlock_read_lock_noirq(&old->vm->memory_range_lock);
|
||||
range = lookup_process_memory_range(old->vm,
|
||||
clone_pthread_start_routine,
|
||||
clone_pthread_start_routine + 1);
|
||||
ihk_rwspinlock_read_unlock_noirq(&old->vm->memory_range_lock);
|
||||
|
||||
if (range && range->memobj && range->memobj->path) {
|
||||
if (!strstr(range->memobj->path, "omp.so") &&
|
||||
!strstr(range->memobj->path, "libfj90")) {
|
||||
helper_thread = 1;
|
||||
}
|
||||
dkprintf("clone(): %s thread from %s\n",
|
||||
helper_thread ? "helper" : "compute",
|
||||
range->memobj->path);
|
||||
}
|
||||
}
|
||||
|
||||
if (helper_thread) {
|
||||
cpuid = ihk_mc_get_processor_id();
|
||||
//cpuid = obtain_clone_cpuid(&oldproc->cpu_set, 1);
|
||||
}
|
||||
else {
|
||||
cpuid = obtain_clone_cpuid(&oldproc->cpu_set,
|
||||
(old->mod_clone == SPAWN_TO_REMOTE && oldproc->uti_use_last_cpu));
|
||||
if (cpuid == -1) {
|
||||
kprintf("do_fork,core not available\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
new = clone_thread(old, curpc,
|
||||
newsp ? newsp : cursp, clone_flags);
|
||||
@ -2829,6 +2875,17 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
goto release_cpuid;
|
||||
}
|
||||
|
||||
if (clone_pthread_start_routine &&
|
||||
range && range->memobj && range->memobj->path) {
|
||||
|
||||
sprintf(new->pthread_routine, "0x%lx @ %s",
|
||||
clone_pthread_start_routine,
|
||||
range->memobj->path);
|
||||
}
|
||||
else {
|
||||
sprintf(new->pthread_routine, "%s", "[unknown]");
|
||||
}
|
||||
|
||||
newproc = new->proc;
|
||||
|
||||
cpu_set(cpuid, &new->vm->address_space->cpu_set,
|
||||
@ -2881,8 +2938,8 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
retry_tid:
|
||||
for (i = 0; i < newproc->nr_tids; ++i) {
|
||||
if (!newproc->tids[i].thread) {
|
||||
if (!__sync_bool_compare_and_swap(
|
||||
&newproc->tids[i].thread, NULL, new)) {
|
||||
if (cmpxchg(&newproc->tids[i].thread,
|
||||
NULL, new) != NULL) {
|
||||
goto retry_tid;
|
||||
}
|
||||
new->tid = newproc->tids[i].tid;
|
||||
@ -2985,7 +3042,8 @@ retry_tid:
|
||||
new->status = PS_RUNNING;
|
||||
|
||||
/* Only the first do_fork() call creates a thread on a Linux CPU */
|
||||
if (__sync_bool_compare_and_swap(&old->mod_clone, SPAWN_TO_REMOTE, SPAWN_TO_LOCAL)) {
|
||||
if (cmpxchg(&old->mod_clone, SPAWN_TO_REMOTE, SPAWN_TO_LOCAL) ==
|
||||
SPAWN_TO_REMOTE) {
|
||||
new->mod_clone = SPAWNING_TO_REMOTE;
|
||||
if (old->mod_clone_arg) {
|
||||
new->mod_clone_arg = kmalloc(sizeof(struct uti_attr),
|
||||
@ -4400,7 +4458,7 @@ perf_mmap(struct mckfd *sfd, ihk_mc_user_context_t *ctx)
|
||||
|
||||
flags |= MAP_ANONYMOUS;
|
||||
prot |= PROT_WRITE;
|
||||
rc = do_mmap(addr0, len0, prot, flags, fd, off0, 0, NULL);
|
||||
rc = do_mmap(addr0, len0, prot, flags, fd, off0);
|
||||
|
||||
// setup perf_event_mmap_page
|
||||
page = (struct perf_event_mmap_page *)rc;
|
||||
@ -5143,10 +5201,10 @@ SYSCALL_DECLARE(mincore)
|
||||
range = NULL;
|
||||
up = vec;
|
||||
for (addr = start; addr < end; addr += PAGE_SIZE) {
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||
range = lookup_process_memory_range(vm, addr, addr+1);
|
||||
if (!range) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
dkprintf("mincore(0x%lx,0x%lx,%p):lookup failed. ENOMEM\n",
|
||||
start, len, vec);
|
||||
return -ENOMEM;
|
||||
@ -5168,7 +5226,7 @@ SYSCALL_DECLARE(mincore)
|
||||
value = 0;
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
error = copy_to_user(up, &value, sizeof(value));
|
||||
if (error) {
|
||||
@ -5286,6 +5344,7 @@ SYSCALL_DECLARE(madvise)
|
||||
|
||||
dkprintf("[%d]sys_madvise(%lx,%lx,%x)\n",
|
||||
ihk_mc_get_processor_id(), start, len0, advice);
|
||||
return 0;
|
||||
|
||||
len = (len0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
end = start + len;
|
||||
@ -5344,7 +5403,7 @@ SYSCALL_DECLARE(madvise)
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&thread->vm->memory_range_lock);
|
||||
/* check contiguous map */
|
||||
first = NULL;
|
||||
range = NULL; /* for avoidance of warning */
|
||||
@ -5515,7 +5574,7 @@ SYSCALL_DECLARE(madvise)
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
out2:
|
||||
dkprintf("[%d]sys_madvise(%lx,%lx,%x): %d\n",
|
||||
@ -5709,6 +5768,9 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
|
||||
|
||||
if (shmflg & SHM_HUGETLB) {
|
||||
pgshift = (shmflg >> SHM_HUGE_SHIFT) & 0x3F;
|
||||
if (!pgshift) {
|
||||
pgshift = ihk_mc_get_linux_default_huge_page_shift();
|
||||
}
|
||||
} else if (proc->thp_disable) {
|
||||
pgshift = PAGE_SHIFT;
|
||||
} else {
|
||||
@ -5827,11 +5889,11 @@ SYSCALL_DECLARE(shmat)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
if (addr) {
|
||||
if (lookup_process_memory_range(vm, addr, addr+len)) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
shmobj_list_unlock();
|
||||
memobj_unref(&obj->memobj);
|
||||
dkprintf("shmat(%#x,%p,%#x):lookup_process_memory_range succeeded. -ENOMEM\n", shmid, shmaddr, shmflg);
|
||||
@ -5841,7 +5903,7 @@ SYSCALL_DECLARE(shmat)
|
||||
else {
|
||||
error = search_free_space(len, obj->pgshift, &addr);
|
||||
if (error) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
shmobj_list_unlock();
|
||||
memobj_unref(&obj->memobj);
|
||||
dkprintf("shmat(%#x,%p,%#x):search_free_space failed. %d\n", shmid, shmaddr, shmflg, error);
|
||||
@ -5857,7 +5919,7 @@ SYSCALL_DECLARE(shmat)
|
||||
if (!(prot & PROT_WRITE)) {
|
||||
error = set_host_vma(addr, len, PROT_READ | PROT_EXEC, 1/* holding memory_range_lock */);
|
||||
if (error) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
shmobj_list_unlock();
|
||||
memobj_unref(&obj->memobj);
|
||||
dkprintf("shmat(%#x,%p,%#x):set_host_vma failed. %d\n", shmid, shmaddr, shmflg, error);
|
||||
@ -5866,19 +5928,19 @@ SYSCALL_DECLARE(shmat)
|
||||
}
|
||||
|
||||
error = add_process_memory_range(vm, addr, addr+len, -1,
|
||||
vrflags, &obj->memobj, 0, obj->pgshift, NULL, NULL);
|
||||
vrflags, &obj->memobj, 0, obj->pgshift, NULL);
|
||||
if (error) {
|
||||
if (!(prot & PROT_WRITE)) {
|
||||
(void)set_host_vma(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC, 1/* holding memory_range_lock */);
|
||||
}
|
||||
memobj_unref(&obj->memobj);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
shmobj_list_unlock();
|
||||
dkprintf("shmat(%#x,%p,%#x):add_process_memory_range failed. %d\n", shmid, shmaddr, shmflg, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
shmobj_list_unlock();
|
||||
|
||||
dkprintf("shmat(%#x,%p,%#x): 0x%lx. %d\n", shmid, shmaddr, shmflg, addr);
|
||||
@ -6165,23 +6227,23 @@ SYSCALL_DECLARE(shmdt)
|
||||
int error;
|
||||
|
||||
dkprintf("shmdt(%p)\n", shmaddr);
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
range = lookup_process_memory_range(vm, (uintptr_t)shmaddr, (uintptr_t)shmaddr+1);
|
||||
if (!range || (range->start != (uintptr_t)shmaddr) || !range->memobj
|
||||
|| !(range->memobj->flags & MF_SHMDT_OK)) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
dkprintf("shmdt(%p): -EINVAL\n", shmaddr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
error = do_munmap((void *)range->start, (range->end - range->start), 1/* holding memory_range_lock */);
|
||||
if (error) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
dkprintf("shmdt(%p): %d\n", shmaddr, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
dkprintf("shmdt(%p): 0\n", shmaddr);
|
||||
return 0;
|
||||
} /* sys_shmdt() */
|
||||
@ -6624,27 +6686,6 @@ SYSCALL_DECLARE(getrusage)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(sysinfo)
|
||||
{
|
||||
struct sysinfo *sysinfo = (struct sysinfo *)ihk_mc_syscall_arg0(ctx);
|
||||
struct sysinfo __sysinfo;
|
||||
int ret = 0;
|
||||
|
||||
memset(&__sysinfo, '\0', sizeof(struct sysinfo));
|
||||
|
||||
__sysinfo.totalram = rusage_get_total_memory();
|
||||
__sysinfo.freeram = rusage_get_free_memory();
|
||||
__sysinfo.mem_unit = 1; // always one unit for McKernel
|
||||
|
||||
if (copy_to_user(sysinfo, &__sysinfo, sizeof(struct sysinfo))) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern int ptrace_traceme(void);
|
||||
extern void set_single_step(struct thread *thread);
|
||||
|
||||
@ -6992,6 +7033,16 @@ static int ptrace_setoptions(int pid, int flags)
|
||||
|
||||
child->ptrace &= ~PTRACE_O_MASK; /* PT_TRACE_EXEC remains */
|
||||
child->ptrace |= flags;
|
||||
dkprintf("%s: (PT_TRACED%s%s%s%s%s%s)\n",
|
||||
__func__,
|
||||
flags & PTRACE_O_TRACESYSGOOD ? "|PTRACE_O_TRACESYSGOOD" : "",
|
||||
flags & PTRACE_O_TRACEFORK ? "|PTRACE_O_TRACEFORK" : "",
|
||||
flags & PTRACE_O_TRACEVFORK ? "|PTRACE_O_TRACEVFORK" : "",
|
||||
flags & PTRACE_O_TRACECLONE ? "|PTRACE_O_TRACECLONE" : "",
|
||||
flags & PTRACE_O_TRACEEXEC ? "|PTRACE_O_TRACEEXEC" : "",
|
||||
flags & PTRACE_O_TRACEVFORKDONE ? "|PTRACE_O_TRACEVFORKDONE" : "",
|
||||
flags & PTRACE_O_TRACEEXIT ? "|PTRACE_O_TRACEEXIT" : "");
|
||||
|
||||
ret = 0;
|
||||
|
||||
unlockout:
|
||||
@ -8094,7 +8145,7 @@ SYSCALL_DECLARE(mlock)
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
/* check contiguous map */
|
||||
first = NULL;
|
||||
@ -8199,7 +8250,7 @@ SYSCALL_DECLARE(mlock)
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
if (!error) {
|
||||
error = populate_process_memory(thread->vm, (void *)start, len);
|
||||
@ -8269,7 +8320,7 @@ SYSCALL_DECLARE(munlock)
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
/* check contiguous map */
|
||||
first = NULL;
|
||||
@ -8374,7 +8425,7 @@ SYSCALL_DECLARE(munlock)
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
out2:
|
||||
dkprintf("[%d]sys_munlock(%lx,%lx): %d\n",
|
||||
ihk_mc_get_processor_id(), start0, len0, error);
|
||||
@ -8430,7 +8481,7 @@ SYSCALL_DECLARE(remap_file_pages)
|
||||
|
||||
dkprintf("sys_remap_file_pages(%#lx,%#lx,%#x,%#lx,%#x)\n",
|
||||
start0, size, prot, pgoff, flags);
|
||||
ihk_mc_spinlock_lock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&thread->vm->memory_range_lock);
|
||||
#define PGOFF_LIMIT ((off_t)1 << ((8*sizeof(off_t) - 1) - PAGE_SHIFT))
|
||||
if ((size <= 0) || (size & (PAGE_SIZE - 1)) || (prot != 0)
|
||||
|| (PGOFF_LIMIT <= pgoff)
|
||||
@ -8474,7 +8525,7 @@ SYSCALL_DECLARE(remap_file_pages)
|
||||
}
|
||||
error = 0;
|
||||
out:
|
||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
if (need_populate
|
||||
&& (er = populate_process_memory(
|
||||
@ -8515,7 +8566,7 @@ SYSCALL_DECLARE(mremap)
|
||||
|
||||
dkprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx)\n",
|
||||
oldaddr, oldsize0, newsize0, flags, newaddr);
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
/* check arguments */
|
||||
if ((oldaddr & ~PAGE_MASK)
|
||||
@ -8653,7 +8704,7 @@ SYSCALL_DECLARE(mremap)
|
||||
error = add_process_memory_range(thread->vm, newstart, newend, -1,
|
||||
range->flag, range->memobj,
|
||||
range->objoff + (oldstart - range->start),
|
||||
0, NULL, NULL);
|
||||
range->pgshift, NULL);
|
||||
if (error) {
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"add failed. %d\n",
|
||||
@ -8734,7 +8785,7 @@ SYSCALL_DECLARE(mremap)
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
if (!error && (lckstart < lckend)) {
|
||||
error = populate_process_memory(thread->vm, (void *)lckstart, (lckend - lckstart));
|
||||
if (error) {
|
||||
@ -8769,7 +8820,7 @@ SYSCALL_DECLARE(msync)
|
||||
uintptr_t e;
|
||||
|
||||
dkprintf("sys_msync(%#lx,%#lx,%#x)\n", start0, len0, flags);
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
if ((start0 & ~PAGE_MASK)
|
||||
|| (flags & ~(MS_ASYNC|MS_INVALIDATE|MS_SYNC))
|
||||
@ -8863,7 +8914,7 @@ SYSCALL_DECLARE(msync)
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
dkprintf("sys_msync(%#lx,%#lx,%#x):%d\n", start0, len0, flags, error);
|
||||
return error;
|
||||
} /* sys_msync() */
|
||||
@ -8928,6 +8979,8 @@ SYSCALL_DECLARE(mbind)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
memset(numa_mask, 0, sizeof(numa_mask));
|
||||
|
||||
if (maxnode) {
|
||||
@ -9044,7 +9097,7 @@ SYSCALL_DECLARE(mbind)
|
||||
}
|
||||
|
||||
/* Validate address range */
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
range = lookup_process_memory_range(vm, addr, addr + len);
|
||||
if (!range) {
|
||||
@ -9182,7 +9235,7 @@ mbind_update_only:
|
||||
error = 0;
|
||||
|
||||
unlock_out:
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
out:
|
||||
return error;
|
||||
} /* sys_mbind() */
|
||||
@ -9412,18 +9465,18 @@ SYSCALL_DECLARE(get_mempolicy)
|
||||
if (flags & MPOL_F_ADDR) {
|
||||
struct vm_range *range;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||
range = lookup_process_memory_range(vm, addr, addr + 1);
|
||||
if (!range) {
|
||||
dkprintf("%s: ERROR: range is invalid\n", __FUNCTION__);
|
||||
error = -EFAULT;
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
range_policy = vm_range_policy_search(vm, addr);
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
}
|
||||
|
||||
/* Return policy */
|
||||
@ -10267,7 +10320,11 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
}
|
||||
#endif // PROFILE_ENABLE
|
||||
|
||||
if (v->flags & CPU_FLAG_NEED_RESCHED) {
|
||||
/* Do not deschedule when returning from an event (e.g., MPI) */
|
||||
if (!(num == __NR_epoll_wait ||
|
||||
num == __NR_epoll_pwait ||
|
||||
num == __NR_ppoll) &&
|
||||
smp_load_acquire(&v->flags) & CPU_FLAG_NEED_RESCHED) {
|
||||
check_need_resched();
|
||||
}
|
||||
|
||||
|
||||
302
kernel/xpmem.c
302
kernel/xpmem.c
@ -423,11 +423,6 @@ static int xpmem_make(
|
||||
struct xpmem_thread_group *seg_tg;
|
||||
struct xpmem_segment *seg;
|
||||
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, "
|
||||
"permit_value=0%04lo",
|
||||
@ -459,27 +454,6 @@ static int xpmem_make(
|
||||
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);
|
||||
if (segid < 0) {
|
||||
xpmem_tg_deref(seg_tg);
|
||||
@ -1037,6 +1011,7 @@ static int xpmem_attach(
|
||||
struct xpmem_segment *seg;
|
||||
struct xpmem_attachment *att;
|
||||
struct mcs_rwlock_node_irqsave at_lock;
|
||||
struct vm_range *vmr;
|
||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||
|
||||
XPMEM_DEBUG("call: apid=0x%lx, offset=0x%lx, size=0x%lx, vaddr=0x%lx, "
|
||||
@ -1130,38 +1105,58 @@ static int xpmem_attach(
|
||||
if (flags & MAP_FIXED) {
|
||||
struct vm_range *existing_vmr;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
existing_vmr = lookup_process_memory_range(vm, vaddr,
|
||||
vaddr + size);
|
||||
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
for (; existing_vmr && existing_vmr->start < vaddr + size;
|
||||
existing_vmr = next_process_memory_range(vm,
|
||||
existing_vmr)) {
|
||||
if (xpmem_is_private_data(existing_vmr)) {
|
||||
ret = -EINVAL;
|
||||
ihk_mc_spinlock_unlock_noirq(
|
||||
&vm->memory_range_lock);
|
||||
goto out_2;
|
||||
}
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
}
|
||||
|
||||
flags |= MAP_ANONYMOUS;
|
||||
XPMEM_DEBUG("do_mmap(): vaddr=0x%lx, size=0x%lx, prot_flags=0x%lx, "
|
||||
"flags=0x%lx, fd=%d, offset=0x%lx",
|
||||
vaddr, size, prot_flags, flags, mckfd->fd, offset);
|
||||
/* The new range is associated with shmobj because of
|
||||
/* The new range uses on-demand paging and is associated with shmobj because of
|
||||
MAP_ANONYMOUS && !MAP_PRIVATE && MAP_SHARED */
|
||||
at_vaddr = do_mmap(vaddr, size, prot_flags, flags, mckfd->fd,
|
||||
offset, VR_XPMEM, att);
|
||||
at_vaddr = do_mmap(vaddr, size, prot_flags, flags, mckfd->fd, offset);
|
||||
if (IS_ERR((void *)(uintptr_t)at_vaddr)) {
|
||||
ret = at_vaddr;
|
||||
goto out_2;
|
||||
}
|
||||
XPMEM_DEBUG("at_vaddr=0x%lx", at_vaddr);
|
||||
att->at_vaddr = at_vaddr;
|
||||
|
||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
vmr = lookup_process_memory_range(vm, at_vaddr, at_vaddr + 1);
|
||||
|
||||
/* To identify pages of XPMEM attachment for rusage accounting */
|
||||
if(vmr->memobj) {
|
||||
vmr->memobj->flags |= MF_XPMEM;
|
||||
} else {
|
||||
ekprintf("%s: vmr->memobj equals to NULL\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
if (!vmr) {
|
||||
ret = -ENOENT;
|
||||
goto out_2;
|
||||
}
|
||||
vmr->private_data = att;
|
||||
|
||||
|
||||
att->at_vmr = vmr;
|
||||
|
||||
*at_vaddr_p = at_vaddr + offset_in_page(att->vaddr);
|
||||
|
||||
@ -1187,6 +1182,7 @@ out_1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int xpmem_detach(
|
||||
unsigned long at_vaddr)
|
||||
{
|
||||
@ -1199,18 +1195,18 @@ static int xpmem_detach(
|
||||
|
||||
XPMEM_DEBUG("call: at_vaddr=0x%lx", at_vaddr);
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
range = lookup_process_memory_range(vm, at_vaddr, at_vaddr + 1);
|
||||
|
||||
if (!range || range->start > at_vaddr) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
att = (struct xpmem_attachment *)range->private_data;
|
||||
if (att == NULL) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1220,7 +1216,7 @@ static int xpmem_detach(
|
||||
|
||||
if (att->flags & XPMEM_FLAG_DESTROYING) {
|
||||
mcs_rwlock_writer_unlock(&att->at_lock, &at_lock);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
xpmem_att_deref(att);
|
||||
return 0;
|
||||
}
|
||||
@ -1233,7 +1229,7 @@ static int xpmem_detach(
|
||||
att->flags &= ~XPMEM_FLAG_DESTROYING;
|
||||
xpmem_ap_deref(ap);
|
||||
mcs_rwlock_writer_unlock(&att->at_lock, &at_lock);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
xpmem_att_deref(att);
|
||||
return -EACCES;
|
||||
}
|
||||
@ -1253,7 +1249,7 @@ static int xpmem_detach(
|
||||
ekprintf("%s: ERROR: xpmem_vm_munmap() failed %d\n",
|
||||
__FUNCTION__, ret);
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
|
||||
DBUG_ON(ret != 0);
|
||||
|
||||
att->flags &= ~XPMEM_FLAG_VALIDPTEs;
|
||||
@ -1416,21 +1412,24 @@ static void xpmem_detach_att(
|
||||
|
||||
XPMEM_DEBUG("call: apid=0x%lx, att=0x%p", ap->apid, att);
|
||||
|
||||
XPMEM_DEBUG("detaching att->vm=0x%p", (void *)att->vm);
|
||||
XPMEM_DEBUG("detaching current->vm=0x%p, att->vm=0x%p",
|
||||
(void *)cpu_local_var(current)->vm, (void *)att->vm);
|
||||
|
||||
vm = cpu_local_var(current)->vm ? cpu_local_var(current)->vm : att->vm;
|
||||
|
||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
mcs_rwlock_writer_lock(&att->at_lock, &at_lock);
|
||||
|
||||
if (att->flags & XPMEM_FLAG_DESTROYING) {
|
||||
mcs_rwlock_writer_unlock(&att->at_lock, &at_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
XPMEM_DEBUG("return: XPMEM_FLAG_DESTROYING");
|
||||
return;
|
||||
}
|
||||
att->flags |= XPMEM_FLAG_DESTROYING;
|
||||
|
||||
vm = att->vm;
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
range = lookup_process_memory_range(vm,
|
||||
range = lookup_process_memory_range(cpu_local_var(current)->vm,
|
||||
att->at_vaddr, att->at_vaddr + 1);
|
||||
|
||||
if (!range || range->start > att->at_vaddr) {
|
||||
@ -1438,7 +1437,7 @@ static void xpmem_detach_att(
|
||||
list_del_init(&att->att_list);
|
||||
ihk_mc_spinlock_unlock_noirq(&ap->lock);
|
||||
mcs_rwlock_writer_unlock(&att->at_lock, &at_lock);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
xpmem_att_destroyable(att);
|
||||
XPMEM_DEBUG("return: range=%p");
|
||||
return;
|
||||
@ -1467,13 +1466,14 @@ static void xpmem_detach_att(
|
||||
|
||||
XPMEM_DEBUG("xpmem_vm_munmap(): start=0x%lx, len=0x%lx",
|
||||
range->start, att->at_size);
|
||||
ret = xpmem_vm_munmap(vm, (void *)range->start, att->at_size);
|
||||
ret = xpmem_vm_munmap(cpu_local_var(current)->vm, (void *)range->start,
|
||||
att->at_size);
|
||||
if (ret) {
|
||||
ekprintf("%s: ERROR: xpmem_vm_munmap() failed %d\n",
|
||||
__FUNCTION__, ret);
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||
|
||||
xpmem_att_destroyable(att);
|
||||
|
||||
@ -1576,7 +1576,7 @@ static void xpmem_clear_PTEs_of_att(
|
||||
XPMEM_DEBUG("call: att=0x%p, start=0x%lx, end=0x%lx",
|
||||
att, start, end);
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&att->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_lock_noirq(&att->vm->memory_range_lock);
|
||||
mcs_rwlock_writer_lock(&att->at_lock, &at_lock);
|
||||
|
||||
if (att->flags & XPMEM_FLAG_VALIDPTEs) {
|
||||
@ -1636,7 +1636,7 @@ static void xpmem_clear_PTEs_of_att(
|
||||
}
|
||||
out:
|
||||
mcs_rwlock_writer_unlock(&att->at_lock, &at_lock);
|
||||
ihk_mc_spinlock_unlock_noirq(&att->vm->memory_range_lock);
|
||||
ihk_rwspinlock_read_unlock_noirq(&att->vm->memory_range_lock);
|
||||
|
||||
XPMEM_DEBUG("return: ");
|
||||
}
|
||||
@ -1664,11 +1664,16 @@ int xpmem_remove_process_memory_range(
|
||||
|
||||
xpmem_att_ref(att);
|
||||
|
||||
ihk_rwspinlock_read_lock_noirq(
|
||||
&cpu_local_var(current)->vm->memory_range_lock);
|
||||
|
||||
mcs_rwlock_writer_lock(&att->at_lock, &at_lock);
|
||||
|
||||
if (att->flags & XPMEM_FLAG_DESTROYING) {
|
||||
mcs_rwlock_writer_unlock(&att->at_lock, &at_lock);
|
||||
xpmem_att_deref(att);
|
||||
XPMEM_DEBUG("already cleaned up");
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vmr->start == att->at_vaddr &&
|
||||
@ -1697,7 +1702,7 @@ int xpmem_remove_process_memory_range(
|
||||
else {
|
||||
remaining_vaddr = vmr->end;
|
||||
remaining_vmr = lookup_process_memory_range(
|
||||
vm, remaining_vaddr - 1,
|
||||
cpu_local_var(current)->vm, remaining_vaddr - 1,
|
||||
remaining_vaddr);
|
||||
if (!remaining_vmr) {
|
||||
ekprintf("%s: ERROR: vm_range is NULL\n", __FUNCTION__);
|
||||
@ -1718,7 +1723,7 @@ int xpmem_remove_process_memory_range(
|
||||
}
|
||||
|
||||
remaining_vmr = lookup_process_memory_range(
|
||||
vm, remaining_vaddr,
|
||||
cpu_local_var(current)->vm, remaining_vaddr,
|
||||
remaining_vaddr + 1);
|
||||
if (!remaining_vmr) {
|
||||
ekprintf("%s: ERROR: vm_range is NULL\n", __FUNCTION__);
|
||||
@ -1742,6 +1747,9 @@ int xpmem_remove_process_memory_range(
|
||||
out:
|
||||
mcs_rwlock_writer_unlock(&att->at_lock, &at_lock);
|
||||
|
||||
ihk_rwspinlock_read_unlock_noirq(
|
||||
&cpu_local_var(current)->vm->memory_range_lock);
|
||||
|
||||
xpmem_att_deref(att);
|
||||
|
||||
XPMEM_DEBUG("return: ret=%d", 0);
|
||||
@ -1870,117 +1878,6 @@ out_1:
|
||||
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(
|
||||
struct process_vm *vm,
|
||||
@ -2008,13 +1905,13 @@ static int xpmem_remap_pte(
|
||||
"seg_vaddr=0x%lx",
|
||||
vmr, vaddr, reason, seg->segid, seg_vaddr);
|
||||
|
||||
if (is_remote_vm(seg_tg->vm)) {
|
||||
ihk_mc_spinlock_lock_noirq(&seg_tg->vm->memory_range_lock);
|
||||
}
|
||||
ihk_rwspinlock_read_lock_noirq(&seg_tg->vm->memory_range_lock);
|
||||
|
||||
seg_vmr = lookup_process_memory_range(seg_tg->vm, seg_vaddr,
|
||||
seg_vaddr + 1);
|
||||
|
||||
ihk_rwspinlock_read_unlock_noirq(&seg_tg->vm->memory_range_lock);
|
||||
|
||||
if (!seg_vmr) {
|
||||
ret = -EFAULT;
|
||||
ekprintf("%s: ERROR: lookup_process_memory_range() failed\n",
|
||||
@ -2025,7 +1922,6 @@ static int xpmem_remap_pte(
|
||||
seg_pte = ihk_mc_pt_lookup_pte(seg_tg->vm->address_space->page_table,
|
||||
(void *)seg_vaddr, seg_vmr->pgshift, &seg_pgaddr, &seg_pgsize,
|
||||
&seg_p2align);
|
||||
|
||||
if (!seg_pte) {
|
||||
ret = -EFAULT;
|
||||
ekprintf("%s: ERROR: ihk_mc_pt_lookup_pte() failed\n",
|
||||
@ -2049,34 +1945,31 @@ static int xpmem_remap_pte(
|
||||
att_attr = arch_vrflag_to_ptattr(vmr->flag, reason, att_pte);
|
||||
XPMEM_DEBUG("att_attr=0x%lx", att_attr);
|
||||
|
||||
if (att_pte && !pgsize_is_contiguous(seg_pgsize)) {
|
||||
if (att_pte) {
|
||||
ret = ihk_mc_pt_set_pte(vm->address_space->page_table, att_pte,
|
||||
seg_pgsize, seg_phys, att_attr);
|
||||
att_pgsize, seg_phys, att_attr);
|
||||
if (ret) {
|
||||
ret = -EFAULT;
|
||||
ekprintf("%s: ERROR: ihk_mc_pt_set_pte() failed %d\n",
|
||||
__func__, ret);
|
||||
__FUNCTION__, ret);
|
||||
goto out;
|
||||
}
|
||||
// memory_stat_rss_add() is called by the process hosting the memory area
|
||||
}
|
||||
else {
|
||||
ret = ihk_mc_pt_set_range(vm->address_space->page_table, vm,
|
||||
att_pgaddr, att_pgaddr + seg_pgsize,
|
||||
seg_phys, att_attr,
|
||||
pgsize_to_pgshift(seg_pgsize), vmr, 1);
|
||||
att_pgaddr, att_pgaddr + att_pgsize, seg_phys, att_attr,
|
||||
vmr->pgshift, vmr, 0);
|
||||
if (ret) {
|
||||
ret = -EFAULT;
|
||||
ekprintf("%s: ERROR: ihk_mc_pt_set_range() failed %d\n",
|
||||
__func__, ret);
|
||||
__FUNCTION__, ret);
|
||||
goto out;
|
||||
}
|
||||
// memory_stat_rss_add() is called by the process hosting the memory area
|
||||
}
|
||||
|
||||
out:
|
||||
if (is_remote_vm(seg_tg->vm)) {
|
||||
ihk_mc_spinlock_unlock_noirq(&seg_tg->vm->memory_range_lock);
|
||||
}
|
||||
|
||||
XPMEM_DEBUG("return: ret=%d", ret);
|
||||
|
||||
return ret;
|
||||
@ -2133,6 +2026,7 @@ static pte_t * xpmem_vaddr_to_pte(
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
return pte;
|
||||
}
|
||||
|
||||
@ -2143,34 +2037,36 @@ static int xpmem_pin_page(
|
||||
struct process_vm *src_vm,
|
||||
unsigned long vaddr)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
struct vm_range *range;
|
||||
|
||||
XPMEM_DEBUG("call: tgid=%d, vaddr=0x%lx", tg->tgid, vaddr);
|
||||
|
||||
if (is_remote_vm(src_vm)) {
|
||||
ihk_mc_spinlock_lock_noirq(&src_vm->memory_range_lock);
|
||||
}
|
||||
ihk_rwspinlock_read_lock_noirq(&src_vm->memory_range_lock);
|
||||
|
||||
range = lookup_process_memory_range(src_vm, vaddr, vaddr + 1);
|
||||
|
||||
ihk_rwspinlock_read_unlock_noirq(&src_vm->memory_range_lock);
|
||||
|
||||
if (!range || range->start > vaddr) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (xpmem_is_private_data(range)) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = page_fault_process_vm(src_vm, (void *)vaddr,
|
||||
PF_POPULATE | PF_WRITE | PF_USER);
|
||||
if (!ret) {
|
||||
ihk_atomic_inc(&tg->n_pinned);
|
||||
out:
|
||||
if (is_remote_vm(src_vm)) {
|
||||
ihk_mc_spinlock_unlock_noirq(&src_vm->memory_range_lock);
|
||||
}
|
||||
else {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
XPMEM_DEBUG("return: ret=%d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2181,24 +2077,30 @@ static void xpmem_unpin_pages(
|
||||
unsigned long vaddr,
|
||||
size_t size)
|
||||
{
|
||||
int n_pgs = (((offset_in_page(vaddr) + (size)) + (PAGE_SIZE - 1)) >>
|
||||
PAGE_SHIFT);
|
||||
int n_pgs_unpinned = 0;
|
||||
size_t vsize = 0;
|
||||
unsigned long end = vaddr + size;
|
||||
pte_t *pte = NULL;
|
||||
|
||||
XPMEM_DEBUG("call: segid=0x%lx, vaddr=0x%lx, size=0x%lx",
|
||||
seg->segid, vaddr, size);
|
||||
|
||||
XPMEM_DEBUG("n_pgs=%d", n_pgs);
|
||||
|
||||
vaddr &= PAGE_MASK;
|
||||
|
||||
while (vaddr < end) {
|
||||
while (n_pgs > 0) {
|
||||
pte = xpmem_vaddr_to_pte(vm, vaddr, &vsize);
|
||||
if (pte && !pte_is_null(pte)) {
|
||||
n_pgs_unpinned++;
|
||||
vaddr += vsize;
|
||||
vaddr += PAGE_SIZE;
|
||||
n_pgs--;
|
||||
}
|
||||
else {
|
||||
vaddr = ((vaddr + vsize) & (~(vsize - 1)));
|
||||
vsize = ((vaddr + vsize) & (~(vsize - 1)));
|
||||
n_pgs -= (vsize - vaddr) / PAGE_SIZE;
|
||||
vaddr = vsize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2400,15 +2302,3 @@ static int xpmem_validate_access(
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,162 @@
|
||||
|
||||
#include <arch-lock.h>
|
||||
|
||||
|
||||
/* Simple read/write spinlock implementation */
|
||||
#define IHK_RWSPINLOCK_WRITELOCKED (0xffU << 24)
|
||||
typedef struct {
|
||||
ihk_atomic_t v;
|
||||
} __attribute__((aligned(4))) ihk_rwspinlock_t;
|
||||
|
||||
static void ihk_rwspinlock_init(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
ihk_atomic_set(&lock->v, 0);
|
||||
}
|
||||
|
||||
static inline void __ihk_rwspinlock_read_lock(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
int desired_old_val;
|
||||
int new_val;
|
||||
|
||||
/*
|
||||
* Atomically increase number of readers,
|
||||
* but make sure no writer is holding the lock.
|
||||
*/
|
||||
for (;;) {
|
||||
desired_old_val = ihk_atomic_read(&lock->v);
|
||||
desired_old_val &= ~(IHK_RWSPINLOCK_WRITELOCKED);
|
||||
new_val = desired_old_val + 1;
|
||||
|
||||
/* Only if we have not reached the max number of readers */
|
||||
if (likely((uint32_t)new_val < IHK_RWSPINLOCK_WRITELOCKED)) {
|
||||
if (likely(cmpxchg(&lock->v.counter, desired_old_val, new_val) ==
|
||||
desired_old_val))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int __ihk_rwspinlock_read_trylock(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
int desired_old_val;
|
||||
int new_val;
|
||||
|
||||
/*
|
||||
* Atomically try to increase number of readers,
|
||||
* but make sure no writer is holding the lock.
|
||||
*/
|
||||
desired_old_val = ihk_atomic_read(&lock->v);
|
||||
desired_old_val &= ~(IHK_RWSPINLOCK_WRITELOCKED);
|
||||
new_val = desired_old_val + 1;
|
||||
|
||||
/* Only if we have not reached the max number of readers */
|
||||
if (likely((uint32_t)new_val < IHK_RWSPINLOCK_WRITELOCKED)) {
|
||||
if (likely(cmpxchg(&lock->v.counter, desired_old_val, new_val) ==
|
||||
desired_old_val))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void __ihk_rwspinlock_read_unlock(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
ihk_atomic_dec((ihk_atomic_t *)&lock->v);
|
||||
}
|
||||
|
||||
static inline void __ihk_rwspinlock_write_lock(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
/*
|
||||
* Atomically switch to write-locked state,
|
||||
* but make sure no one else is holding the lock.
|
||||
*/
|
||||
for (;;) {
|
||||
if (likely(cmpxchg(&lock->v.counter,
|
||||
0, IHK_RWSPINLOCK_WRITELOCKED) == 0))
|
||||
return;
|
||||
cpu_pause();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __ihk_rwspinlock_write_unlock(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
smp_store_release(&(lock->v.counter), 0);
|
||||
}
|
||||
|
||||
/* User facing functions */
|
||||
static inline void ihk_rwspinlock_read_lock_noirq(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
preempt_disable();
|
||||
__ihk_rwspinlock_read_lock(lock);
|
||||
}
|
||||
|
||||
static inline int ihk_rwspinlock_read_trylock_noirq(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
int rc;
|
||||
|
||||
preempt_disable();
|
||||
rc = __ihk_rwspinlock_read_trylock(lock);
|
||||
if (!rc) {
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline void ihk_rwspinlock_write_lock_noirq(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
preempt_disable();
|
||||
__ihk_rwspinlock_write_lock(lock);
|
||||
}
|
||||
|
||||
static inline void ihk_rwspinlock_read_unlock_noirq(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
__ihk_rwspinlock_read_unlock(lock);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static inline void ihk_rwspinlock_write_unlock_noirq(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
__ihk_rwspinlock_write_unlock(lock);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
unsigned long ihk_rwspinlock_read_lock(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
unsigned long irqstate = cpu_disable_interrupt_save();
|
||||
|
||||
ihk_rwspinlock_read_lock_noirq(lock);
|
||||
return irqstate;
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned long ihk_rwspinlock_write_lock(ihk_rwspinlock_t *lock)
|
||||
{
|
||||
unsigned long irqstate = cpu_disable_interrupt_save();
|
||||
|
||||
ihk_rwspinlock_write_lock_noirq(lock);
|
||||
return irqstate;
|
||||
}
|
||||
|
||||
static inline void ihk_rwspinlock_read_unlock(ihk_rwspinlock_t *lock,
|
||||
unsigned long irqstate)
|
||||
{
|
||||
ihk_rwspinlock_read_unlock_noirq(lock);
|
||||
cpu_restore_interrupt(irqstate);
|
||||
}
|
||||
|
||||
static inline void ihk_rwspinlock_write_unlock(ihk_rwspinlock_t *lock,
|
||||
unsigned long irqstate)
|
||||
{
|
||||
ihk_rwspinlock_write_unlock_noirq(lock);
|
||||
cpu_restore_interrupt(irqstate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef ARCH_MCS_LOCK
|
||||
/* An architecture independent implementation of the
|
||||
* Mellor-Crummey Scott (MCS) lock */
|
||||
|
||||
96
scripts/eclair-dump-backtrace.exp.in
Executable file
96
scripts/eclair-dump-backtrace.exp.in
Executable file
@ -0,0 +1,96 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set INST_DIR "@prefix@"
|
||||
|
||||
spawn $INST_DIR/bin/eclair -k $INST_DIR/smp-@ARCH@/kernel/mckernel.img -i -l
|
||||
|
||||
set state "init"
|
||||
set thread_id 0
|
||||
set timeout -1
|
||||
|
||||
expect {
|
||||
"Quit anyway? (y or n) " {
|
||||
send "y\r"
|
||||
wait
|
||||
exit 0
|
||||
}
|
||||
"Unknown thread*" {
|
||||
send "quit\r"
|
||||
exp_continue
|
||||
}
|
||||
"in ?? ()" {
|
||||
switch -- $state {
|
||||
"thread_chosen" {
|
||||
set state "thread_skip"
|
||||
}
|
||||
"thread_bt" {
|
||||
set state "thread_skip"
|
||||
}
|
||||
}
|
||||
|
||||
exp_continue
|
||||
}
|
||||
"(eclair) " {
|
||||
switch -- $state {
|
||||
"init" {
|
||||
set state "threads_list"
|
||||
send "info threads\r"
|
||||
}
|
||||
"threads_list" {
|
||||
incr thread_id
|
||||
set state "thread_chosen"
|
||||
send "thread $thread_id\r"
|
||||
}
|
||||
"thread_bt" {
|
||||
incr thread_id
|
||||
set state "thread_chosen"
|
||||
send "thread $thread_id\r"
|
||||
}
|
||||
"thread_skip" {
|
||||
incr thread_id
|
||||
set state "thread_chosen"
|
||||
send "thread $thread_id\r"
|
||||
}
|
||||
"thread_chosen" {
|
||||
set state "thread_bt"
|
||||
send "bt\r"
|
||||
}
|
||||
}
|
||||
|
||||
exp_continue
|
||||
}
|
||||
"Type <RET> for more, q to quit, c to continue without paging--" {
|
||||
switch -- $state {
|
||||
"threads_list" {
|
||||
send "\r"
|
||||
}
|
||||
"thread_bt" {
|
||||
send "q\r"
|
||||
}
|
||||
"thread_skip" {
|
||||
send "q\r"
|
||||
}
|
||||
}
|
||||
exp_continue
|
||||
}
|
||||
"Type <return> to continue, or q <return> to quit" {
|
||||
switch -- $state {
|
||||
"threads_list" {
|
||||
send "\r"
|
||||
}
|
||||
"thread_bt" {
|
||||
send "\r"
|
||||
}
|
||||
"thread_skip" {
|
||||
send "q\r"
|
||||
}
|
||||
}
|
||||
exp_continue
|
||||
}
|
||||
" not known." {
|
||||
expect "(eclair) " { send "quit\r" }
|
||||
expect "Quit anyway? (y or n) " { send "y\r" }
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
%{!?kernel_version: %global kernel_version @UNAME_R@}
|
||||
%{!?kernel_dir: %global kernel_dir /usr/src/kernels/%{kernel_version}}
|
||||
%define krequires %(echo %{kernel_version} | sed "s/.%{_target_cpu}$//")
|
||||
%define ktag %(echo %{krequires} | tr '-' '_' | sed -e 's/\.el[0-9]*$//' | sed -e 's/\.\([a-zA-Z]\)/_\1/')
|
||||
%define ktag %(echo %{krequires} | tr '-' '_' | sed -e 's/\.el[0-9_]*$//' | sed -e 's/\.\([a-zA-Z]\)/_\1/')
|
||||
|
||||
Name: mckernel
|
||||
Version: @MCKERNEL_VERSION@
|
||||
@ -96,6 +96,10 @@ This package contains headers and libraries required for build apps using IHK/Mc
|
||||
%{_sbindir}/ihkmond
|
||||
%{_bindir}/mcexec
|
||||
%{_bindir}/eclair
|
||||
%{_bindir}/eclair-dump-backtrace.exp
|
||||
%{_bindir}/mcinspect
|
||||
%{_bindir}/mcps
|
||||
/usr/lib/debug/usr/bin/mcinspect-%{version}-%{release}.%{_arch}.debug
|
||||
%{_bindir}/vmcore2mckdump
|
||||
%{_bindir}/mcstat
|
||||
%{_libdir}/libihk.so
|
||||
|
||||
@ -1,187 +0,0 @@
|
||||
#!/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
|
||||
@ -1,12 +0,0 @@
|
||||
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
|
||||
|
||||
@ -1,104 +0,0 @@
|
||||
【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していることを確認。
|
||||
@ -1,60 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,79 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,112 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
PGSHIFT_LIST=(21 29 34)
|
||||
SMALL_PGSIZE=65536
|
||||
@ -1,184 +0,0 @@
|
||||
*** C1259T01 start *******************************
|
||||
** xpmem_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 *******************************
|
||||
** xpmem_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 *******************************
|
||||
** xpmem_attach to small mapped memory range
|
||||
pageshift: small page
|
||||
** [ OK ] xpmem_addr (100000210000) is allocated using small pages
|
||||
*** C1259T03: PASSED
|
||||
|
||||
*** C1259T04 start *******************************
|
||||
** xpmem_attach to multi pagesize range
|
||||
pageshift: 21
|
||||
** [ OK ] xpmem_addr (100000600000) is allocated using large pages
|
||||
*** C1259T04: PASSED
|
||||
|
||||
*** C1259T05 start *******************************
|
||||
** xpmem testsuite
|
||||
XPMEM version = 26003
|
||||
|
||||
==== test_base STARTS ====
|
||||
xpmem_proc1: mypid = 38514
|
||||
xpmem_proc1: sharing 262144 bytes
|
||||
xpmem_proc1: segid = 200009672 at 0x100000210000
|
||||
|
||||
xpmem_proc2: mypid = 38711
|
||||
xpmem_proc2: segid = 200009672
|
||||
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 = 39028
|
||||
xpmem_proc1: sharing 262144 bytes
|
||||
xpmem_proc1: segid = 200009874 at 0x100000210000
|
||||
|
||||
xpmem_proc2: mypid = 39233
|
||||
xpmem_proc2: segid = 200009874
|
||||
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 = 39429
|
||||
xpmem_proc1: sharing 2 segments, 262144 bytes each
|
||||
xpmem_proc1: segid[0] = 200009a05 at 0x100000210000
|
||||
xpmem_proc1: segid[1] = 400009a05 at 0x100000250000
|
||||
|
||||
xpmem_proc2: mypid = 39625
|
||||
xpmem_proc2: segid[0] = 200009a05
|
||||
xpmem_proc2: segid[1] = 400009a05
|
||||
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 = 39831
|
||||
xpmem_proc1: sharing 262144 bytes
|
||||
xpmem_proc1: segid = 200009b97 at 0x100000210000
|
||||
|
||||
xpmem_proc2: mypid = 40027
|
||||
xpmem_proc2: segid = 200009b97
|
||||
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 40224
|
||||
|
||||
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
|
||||
|
||||
@ -1,182 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,99 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
#!/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
|
||||
|
||||
@ -1,187 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
#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
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
#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
|
||||
@ -1,2 +0,0 @@
|
||||
PGSHIFT_LIST=(21 30)
|
||||
SMALL_PGSIZE=4096
|
||||
@ -1,178 +0,0 @@
|
||||
*** C1259T01 start *******************************
|
||||
** xpmem_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 *******************************
|
||||
** xpmem_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 *******************************
|
||||
** xpmem_attach to small mapped memory range
|
||||
pageshift: small page
|
||||
** [ OK ] xpmem_addr (2aaaaafee000) is allocated using small pages
|
||||
*** C1259T03: PASSED
|
||||
|
||||
*** C1259T04 start *******************************
|
||||
** xpmem_attach to multi pagesize range
|
||||
pageshift: 21
|
||||
** [ OK ] xpmem_addr (2aaaab200000) is allocated using large pages
|
||||
*** C1259T04: PASSED
|
||||
|
||||
*** C1259T05 start *******************************
|
||||
** xpmem testsuite
|
||||
XPMEM version = 26003
|
||||
|
||||
==== test_base STARTS ====
|
||||
xpmem_proc1: mypid = 20070
|
||||
xpmem_proc1: sharing 16384 bytes
|
||||
xpmem_proc1: segid = 200004e66 at 0x2aaaaafee000
|
||||
|
||||
xpmem_proc2: mypid = 20490
|
||||
xpmem_proc2: segid = 200004e66
|
||||
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 = 20913
|
||||
xpmem_proc1: sharing 16384 bytes
|
||||
xpmem_proc1: segid = 2000051b1 at 0x2aaaaafee000
|
||||
|
||||
xpmem_proc2: mypid = 21336
|
||||
xpmem_proc2: segid = 2000051b1
|
||||
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 = 21758
|
||||
xpmem_proc1: sharing 2 segments, 16384 bytes each
|
||||
xpmem_proc1: segid[0] = 2000054fe at 0x2aaaaafee000
|
||||
xpmem_proc1: segid[1] = 4000054fe at 0x2aaaaaff2000
|
||||
|
||||
xpmem_proc2: mypid = 22179
|
||||
xpmem_proc2: segid[0] = 2000054fe
|
||||
xpmem_proc2: segid[1] = 4000054fe
|
||||
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 = 22599
|
||||
xpmem_proc1: sharing 16384 bytes
|
||||
xpmem_proc1: segid = 200005847 at 0x2aaaaafee000
|
||||
|
||||
xpmem_proc2: mypid = 23022
|
||||
xpmem_proc2: segid = 200005847
|
||||
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 23443
|
||||
|
||||
|
||||
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
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
【Issue#1330 動作確認】
|
||||
□ テスト内容
|
||||
1. xpmemの基本操作の確認
|
||||
mckernel/test/xpmemのテストを実行し、xpmemの基本操作が
|
||||
正常に動作することを確認する
|
||||
テスト内容の詳細はmckernel/test/xpmem/README を参照
|
||||
|
||||
□ 実行手順
|
||||
1. mckernel/test/xpmem に移動する
|
||||
1. xpmemのインストールディレクトリをMakefileとgo_test.sh中のXPMEM_DIRに記載する
|
||||
2. xpmemのビルドディレクトリをgo_test.sh中のXPMEM_BUILD_DIRに記載する
|
||||
3. 下記の手順でテストを実行する
|
||||
$ 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していることを確認。
|
||||
@ -1,151 +0,0 @@
|
||||
*** XPMEM_TESTSUITE start *******************************
|
||||
XPMEM version = 26003
|
||||
|
||||
==== test_base STARTS ====
|
||||
xpmem_proc1: mypid = 3962
|
||||
xpmem_proc1: sharing 262144 bytes
|
||||
xpmem_proc1: segid = 200000f7a at 0x100000210000
|
||||
|
||||
xpmem_proc2: mypid = 4161
|
||||
xpmem_proc2: segid = 200000f7a
|
||||
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 = 4472
|
||||
xpmem_proc1: sharing 262144 bytes
|
||||
xpmem_proc1: segid = 200001178 at 0x100000210000
|
||||
|
||||
xpmem_proc2: mypid = 4670
|
||||
xpmem_proc2: segid = 200001178
|
||||
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 = 4871
|
||||
xpmem_proc1: sharing 2 segments, 262144 bytes each
|
||||
xpmem_proc1: segid[0] = 200001307 at 0x100000210000
|
||||
xpmem_proc1: segid[1] = 400001307 at 0x100000250000
|
||||
|
||||
xpmem_proc2: mypid = 5068
|
||||
xpmem_proc2: segid[0] = 200001307
|
||||
xpmem_proc2: segid[1] = 400001307
|
||||
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 = 5271
|
||||
xpmem_proc1: sharing 262144 bytes
|
||||
xpmem_proc1: segid = 200001497 at 0x100000210000
|
||||
|
||||
xpmem_proc2: mypid = 5468
|
||||
xpmem_proc2: segid = 200001497
|
||||
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 5789
|
||||
|
||||
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
|
||||
[OK] xpmem_get in child
|
||||
[OK] xpmem_attach in child
|
||||
[OK] validate TEST_VAL
|
||||
[OK] xpmem_remove
|
||||
*** XTP_007 PASSED
|
||||
|
||||
*** XTP_901 start ***
|
||||
[OK] xpmem_make failed (invalid address)
|
||||
[OK] xpmem_make succeed(do twice to same address)
|
||||
*** XTP_901 PASSED
|
||||
|
||||
*** XTP_902 start ***
|
||||
[OK] xpmem_get in child failed (invalid segid)
|
||||
[OK] xpmem_get in child (do twice to same segid
|
||||
*** XTP_902 PASSED
|
||||
|
||||
*** XTP_903 start ***
|
||||
[OK] xpmem_attach in childi failed (invalid apid)
|
||||
[OK] xpmem_attach in child succeed (do twice to same apid)
|
||||
*** XTP_903 PASSED
|
||||
|
||||
*** XTP_904 start ***
|
||||
[OK] xpmem_detach in child succeed (invalid address)
|
||||
[OK] xpmem_detach in child succeed (do twice to same address)
|
||||
*** XTP_904 PASSED
|
||||
|
||||
*** XTP_905 start ***
|
||||
[OK] xpmem_remove failed (invalid segid)
|
||||
[OK] xpmem_remove failed (do twice to same segid)
|
||||
*** XTP_905 PASSED
|
||||
|
||||
@ -1,151 +0,0 @@
|
||||
*** XPMEM_TESTSUITE start *******************************
|
||||
XPMEM version = 26003
|
||||
|
||||
==== test_base STARTS ====
|
||||
xpmem_proc1: mypid = 4598
|
||||
xpmem_proc1: sharing 16384 bytes
|
||||
xpmem_proc1: segid = 2000011f6 at 0x2aaaaafee000
|
||||
|
||||
xpmem_proc2: mypid = 5018
|
||||
xpmem_proc2: segid = 2000011f6
|
||||
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 = 5438
|
||||
xpmem_proc1: sharing 16384 bytes
|
||||
xpmem_proc1: segid = 20000153e at 0x2aaaaafee000
|
||||
|
||||
xpmem_proc2: mypid = 5858
|
||||
xpmem_proc2: segid = 20000153e
|
||||
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 = 6278
|
||||
xpmem_proc1: sharing 2 segments, 16384 bytes each
|
||||
xpmem_proc1: segid[0] = 200001886 at 0x2aaaaafee000
|
||||
xpmem_proc1: segid[1] = 400001886 at 0x2aaaaaff2000
|
||||
|
||||
xpmem_proc2: mypid = 6698
|
||||
xpmem_proc2: segid[0] = 200001886
|
||||
xpmem_proc2: segid[1] = 400001886
|
||||
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 = 7118
|
||||
xpmem_proc1: sharing 16384 bytes
|
||||
xpmem_proc1: segid = 200001bce at 0x2aaaaafee000
|
||||
|
||||
xpmem_proc2: mypid = 7538
|
||||
xpmem_proc2: segid = 200001bce
|
||||
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 7958
|
||||
|
||||
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
|
||||
[OK] xpmem_get in child
|
||||
[OK] xpmem_attach in child
|
||||
[OK] validate TEST_VAL
|
||||
[OK] xpmem_remove
|
||||
*** XTP_007 PASSED
|
||||
|
||||
*** XTP_901 start ***
|
||||
[OK] xpmem_make failed (invalid address)
|
||||
[OK] xpmem_make succeed(do twice to same address)
|
||||
*** XTP_901 PASSED
|
||||
|
||||
*** XTP_902 start ***
|
||||
[OK] xpmem_get in child failed (invalid segid)
|
||||
[OK] xpmem_get in child (do twice to same segid
|
||||
*** XTP_902 PASSED
|
||||
|
||||
*** XTP_903 start ***
|
||||
[OK] xpmem_attach in childi failed (invalid apid)
|
||||
[OK] xpmem_attach in child succeed (do twice to same apid)
|
||||
*** XTP_903 PASSED
|
||||
|
||||
*** XTP_904 start ***
|
||||
[OK] xpmem_detach in child succeed (invalid address)
|
||||
[OK] xpmem_detach in child succeed (do twice to same address)
|
||||
*** XTP_904 PASSED
|
||||
|
||||
*** XTP_905 start ***
|
||||
[OK] xpmem_remove failed (invalid segid)
|
||||
[OK] xpmem_remove failed (do twice to same segid)
|
||||
*** XTP_905 PASSED
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
#/bin/sh
|
||||
|
||||
USELTP=1
|
||||
USEOSTEST=0
|
||||
|
||||
BOOTPARAM="-c 1-7 -m 10G@0,10G@1 -O"
|
||||
. ../../common.sh
|
||||
|
||||
issue="1389"
|
||||
tid=01
|
||||
|
||||
for tsuf in "01" "02.sh"
|
||||
do
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
${MCEXEC} ./C1389T${tsuf}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "*** ${tname} PASSED ******************************"
|
||||
else
|
||||
echo "*** ${tname} FAILED ******************************"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
done
|
||||
|
||||
for tp in "mtest01 -p80" "mtest01 -p80 -w" "mem01"
|
||||
do
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
echo ${tp}
|
||||
sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee ${tname}.txt
|
||||
ok=`grep PASS ${tname}.txt | wc -l`
|
||||
ng=`grep FAIL ${tname}.txt | wc -l`
|
||||
if [ $ng = 0 ]; then
|
||||
echo "*** ${tname} PASSED ($ok)"
|
||||
else
|
||||
echo "*** ${tname} FAILED (ok=$ok ng=$ng)"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
done
|
||||
|
||||
@ -1,65 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct sysinfo *info;
|
||||
int ret = 0, rc = 0;
|
||||
unsigned long assigned_mem = (20UL << 30);
|
||||
unsigned long _totalram, _freeram;
|
||||
unsigned int _mem_unit;
|
||||
|
||||
info = malloc(sizeof(struct sysinfo));
|
||||
rc = sysinfo(info);
|
||||
if (rc) {
|
||||
perror("sysinfo fail: ");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
_totalram = info->totalram;
|
||||
_freeram = info->freeram;
|
||||
_mem_unit = info->mem_unit;
|
||||
|
||||
// Check totalram
|
||||
if (0.95 * assigned_mem < _totalram &&
|
||||
_totalram < assigned_mem) {
|
||||
printf("[OK] totalram: %ld\n", _totalram);
|
||||
}
|
||||
else {
|
||||
printf("[NG] unexpected totalram: %ld\n", _totalram);
|
||||
printf(" expected range: %ld - %ld\n",
|
||||
(unsigned long)(0.95 * assigned_mem),
|
||||
assigned_mem);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Check freeram
|
||||
if (0.95 * _totalram < _freeram &&
|
||||
_freeram < _totalram) {
|
||||
printf("[OK] freeram: %ld\n", _freeram);
|
||||
}
|
||||
else {
|
||||
printf("[NG] unexpected freeram: %ld\n", _freeram);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Check mem_unit
|
||||
if (_mem_unit == 1) {
|
||||
printf("[OK] mem_unit: %ld\n", _mem_unit);
|
||||
}
|
||||
else {
|
||||
printf("[NG] unexpected mem_unit: %ld\n", _mem_unit);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
free(info);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
ASSIGNED_MEM=`echo '1024 * 1024 * 1024 * 20' | bc`
|
||||
cat /proc/meminfo > ./cur_meminfo.txt
|
||||
|
||||
# Check MemTotal
|
||||
MemTotalTxt=`cat ./cur_meminfo.txt | grep MemTotal | awk '{print $(NF-1)}'`
|
||||
MemTotal=`echo "1024 * ${MemTotalTxt}" | bc`
|
||||
|
||||
lower_limit=`echo "${ASSIGNED_MEM} * 0.95" | bc`
|
||||
lower_limit=${lower_limit%.*}
|
||||
upper_limit=${ASSIGNED_MEM}
|
||||
tgt=${MemTotal}
|
||||
|
||||
if [ ${tgt} -ge ${lower_limit} -a ${tgt} -lt ${upper_limit} ]; then
|
||||
echo "[OK] MemTotal: ${tgt}"
|
||||
else
|
||||
echo "[NG] unexpected MemTotal: ${tgt}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check MemFree
|
||||
MemFreeTxt=`cat ./cur_meminfo.txt | grep MemFree | awk '{print $(NF-1)}'`
|
||||
MemFree=`echo "1024 * ${MemFreeTxt}" | bc`
|
||||
|
||||
lower_limit=`echo "${MemTotal} * 0.95" | bc`
|
||||
lower_limit=${lower_limit%.*}
|
||||
upper_limit=${MemTotal}
|
||||
tgt=${MemFree}
|
||||
|
||||
if [ ${tgt} -ge ${lower_limit} -a ${tgt} -lt ${upper_limit} ]; then
|
||||
echo "[OK] MemFree: ${tgt}"
|
||||
else
|
||||
echo "[NG] unexpected MemFree: ${tgt}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check SwapTotal
|
||||
SwapTotalTxt=`cat ./cur_meminfo.txt | grep SwapTotal | awk '{print $(NF-1)}'`
|
||||
SwapTotal=`echo "1024 * ${SwapTotalTxt}" | bc`
|
||||
|
||||
tgt=${SwapTotal}
|
||||
|
||||
if [ ${tgt} -eq 0 ]; then
|
||||
echo "[OK] SwapTotal: ${tgt}"
|
||||
else
|
||||
echo "[NG] unexpected SwapTotal: ${tgt}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check SwapFree
|
||||
SwapFreeTxt=`cat ./cur_meminfo.txt | grep SwapFree | awk '{print $(NF-1)}'`
|
||||
SwapFree=`echo "1024 * ${SwapFreeTxt}" | bc`
|
||||
|
||||
tgt=${SwapFree}
|
||||
|
||||
if [ ${tgt} -eq 0 ]; then
|
||||
echo "[OK] SwapFree: ${tgt}"
|
||||
else
|
||||
echo "[NG] unexpected SwapFree: ${tgt}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check CommitLimit
|
||||
CommitLimitTxt=`cat ./cur_meminfo.txt | grep CommitLimit | awk '{print $(NF-1)}'`
|
||||
CommitLimit=`echo "1024 * ${CommitLimitTxt}" | bc`
|
||||
|
||||
tgt=${CommitLimit}
|
||||
|
||||
if [ ${tgt} -eq ${MemFree} ]; then
|
||||
echo "[OK] CommitLimit: ${tgt}"
|
||||
else
|
||||
echo "[NG] unexpected CommitLimit: ${tgt}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Committed_AS
|
||||
Committed_ASTxt=`cat ./cur_meminfo.txt | grep Committed_AS | awk '{print $(NF-1)}'`
|
||||
Committed_AS=`echo "1024 * ${Committed_ASTxt}" | bc`
|
||||
|
||||
tgt=${Committed_AS}
|
||||
|
||||
if [ ${tgt} -eq $((${MemTotal} - ${MemFree})) ]; then
|
||||
echo "[OK] Committed_AS: ${tgt}"
|
||||
else
|
||||
echo "[NG] unexpected Committed_AS: ${tgt}"
|
||||
exit 1
|
||||
fi
|
||||
@ -1,11 +0,0 @@
|
||||
CFLAGS=-g
|
||||
LDFLAGS=
|
||||
|
||||
TARGET=C1389T01
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
test: all
|
||||
sh ./C1389.sh
|
||||
clean:
|
||||
rm -f $(TARGET) *.o *.txt
|
||||
@ -1,46 +0,0 @@
|
||||
【Issue#1389 動作確認】
|
||||
□ テスト内容
|
||||
本Issueの対応で、sysinfo()と/proc/meminfo の下記項目においてMcKernelの情報を
|
||||
返すようにした。
|
||||
[sysinfo]
|
||||
totalram : rusage_global の total_memory
|
||||
freeram : rusage_global の total_memory - usage_memory
|
||||
mem_unit : 常に1
|
||||
[/proc/meminfo]
|
||||
MemTotal : rusage_global の total_memory
|
||||
MemFree : rusage_global の total_memory - usage_memory
|
||||
SwapTotal : 常に0
|
||||
SwapFree : 常に0
|
||||
CommitLimit : rusage_global の total_memory - usage_memory
|
||||
Committed_AS : rusage_global の usage_memory
|
||||
|
||||
1. 本Issueで対応したsysinfo() と /proc/meminfo の値が想定どおりとなっていることを確認
|
||||
McKernelへのメモリ割り当てを 10G@0,10G@1 とした状態で下記プログラムを実行
|
||||
C1389T01: sysinfo() で取得される値が下記のとおりであることを確認
|
||||
totalram : 20GiB * 0.95 以上、20GiB 未満であること
|
||||
freeram : totralram * 0.95 以上、totalram 未満であること
|
||||
mem_unit : 1 であること
|
||||
C1389T02: /proc/meminfo から取得される値が下記のとおりであることを確認
|
||||
MemTotal : 20GiB * 0.95 以上、20GiB 未満であること
|
||||
MemFree : MemTotal * 0.95 以上、MemTotal 未満であること
|
||||
SwapTotal : 0 であること
|
||||
SwapFree : 0 であること
|
||||
CommitLimit : MemFreeと同値であること
|
||||
Committed_AS : MemTotal - MemFree と同値であること
|
||||
|
||||
2. 本Issueで対応したsysinfo() の項目を利用する以下のLTPを実行し、PASSすることを確認
|
||||
- mtest01 -p80
|
||||
- mtest01 -p80 -w
|
||||
- mem01
|
||||
|
||||
□ 実行手順
|
||||
$ 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していることを確認。
|
||||
@ -1,77 +0,0 @@
|
||||
sh ./C1389.sh
|
||||
mcstop+release.sh ... done
|
||||
mcreboot.sh -c 1-7 -m 10G@0,10G@1 -O ... done
|
||||
*** C1389T01 start *******************************
|
||||
[OK] totalram: 21472215040
|
||||
[OK] freeram: 21461794816
|
||||
[OK] mem_unit: 1
|
||||
*** C1389T01 PASSED ******************************
|
||||
|
||||
*** C1389T02 start *******************************
|
||||
[OK] MemTotal: 21472215040
|
||||
[OK] MemFree: 21452750848
|
||||
[OK] SwapTotal: 0
|
||||
[OK] SwapFree: 0
|
||||
[OK] CommitLimit: 21452750848
|
||||
[OK] Committed_AS: 19464192
|
||||
*** C1389T02 PASSED ******************************
|
||||
|
||||
*** C1389T03 start *******************************
|
||||
mtest01 -p80
|
||||
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
|
||||
mtest01.c:134: INFO: Filling up 80% of free ram which is 16760729 kbytes
|
||||
mtest01.c:149: INFO: ... child 50935 starting
|
||||
mtest01.c:149: INFO: ... child 50944 starting
|
||||
mtest01.c:149: INFO: ... child 50953 starting
|
||||
mtest01.c:149: INFO: ... child 50962 starting
|
||||
mtest01.c:149: INFO: ... child 50971 starting
|
||||
mtest01.c:149: INFO: ... child 50980 starting
|
||||
mtest01.c:169: INFO: ... [t=300] 1434451968 bytes allocated only in child 50980
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50935
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50944
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50953
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50962
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50971
|
||||
mtest01.c:221: PASS: 16760729 kbytes allocated
|
||||
|
||||
Summary:
|
||||
passed 1
|
||||
failed 0
|
||||
skipped 0
|
||||
warnings 0
|
||||
*** C1389T03 PASSED (1)
|
||||
|
||||
*** C1389T04 start *******************************
|
||||
mtest01 -p80 -w
|
||||
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
|
||||
mtest01.c:134: INFO: Filling up 80% of free ram which is 16759654 kbytes
|
||||
mtest01.c:149: INFO: ... child 51017 starting
|
||||
mtest01.c:149: INFO: ... child 51026 starting
|
||||
mtest01.c:149: INFO: ... child 51035 starting
|
||||
mtest01.c:149: INFO: ... child 51044 starting
|
||||
mtest01.c:149: INFO: ... child 51053 starting
|
||||
mtest01.c:149: INFO: ... child 51062 starting
|
||||
mtest01.c:166: INFO: ... [t=300] 1433403392 bytes allocated and used in child 51062
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51017
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51026
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51035
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51044
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51053
|
||||
mtest01.c:221: PASS: 16759654 kbytes allocated (and written to)
|
||||
|
||||
Summary:
|
||||
passed 1
|
||||
failed 0
|
||||
skipped 0
|
||||
warnings 0
|
||||
*** C1389T04 PASSED (1)
|
||||
|
||||
*** C1389T05 start *******************************
|
||||
mem01
|
||||
mem01 0 TINFO : Free Mem: 20465 Mb
|
||||
mem01 0 TINFO : Free Swap: 0 Mb
|
||||
mem01 0 TINFO : Total Free: 20465 Mb
|
||||
mem01 0 TINFO : Total Tested: 3056 Mb
|
||||
mem01 0 TINFO : touching 3056MB of malloc'ed memory (linear)
|
||||
mem01 1 TPASS : malloc - alloc of 3056MB succeeded
|
||||
*** C1389T05 PASSED (1)
|
||||
@ -1,77 +0,0 @@
|
||||
sh ./C1389.sh
|
||||
mcstop+release.sh ... done
|
||||
mcreboot.sh -c 1-7 -m 10G@0,10G@1 -O ... done
|
||||
*** C1389T01 start *******************************
|
||||
[OK] totalram: 21463240704
|
||||
[OK] freeram: 21459673088
|
||||
[OK] mem_unit: 1
|
||||
*** C1389T01 PASSED ******************************
|
||||
|
||||
*** C1389T02 start *******************************
|
||||
[OK] MemTotal: 21463240704
|
||||
[OK] MemFree: 21453983744
|
||||
[OK] SwapTotal: 0
|
||||
[OK] SwapFree: 0
|
||||
[OK] CommitLimit: 21453983744
|
||||
[OK] Committed_AS: 9256960
|
||||
*** C1389T02 PASSED ******************************
|
||||
|
||||
*** C1389T03 start *******************************
|
||||
mtest01 -p80
|
||||
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
|
||||
mtest01.c:134: INFO: Filling up 80% of free ram which is 16762396 kbytes
|
||||
mtest01.c:149: INFO: ... child 20718 starting
|
||||
mtest01.c:149: INFO: ... child 20727 starting
|
||||
mtest01.c:149: INFO: ... child 20736 starting
|
||||
mtest01.c:149: INFO: ... child 20745 starting
|
||||
mtest01.c:149: INFO: ... child 20754 starting
|
||||
mtest01.c:149: INFO: ... child 20763 starting
|
||||
mtest01.c:169: INFO: ... [t=300] 1436549120 bytes allocated only in child 20763
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20718
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20727
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20736
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20745
|
||||
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20754
|
||||
mtest01.c:221: PASS: 16762396 kbytes allocated
|
||||
|
||||
Summary:
|
||||
passed 1
|
||||
failed 0
|
||||
skipped 0
|
||||
warnings 0
|
||||
*** C1389T03 PASSED (1)
|
||||
|
||||
*** C1389T04 start *******************************
|
||||
mtest01 -p80 -w
|
||||
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
|
||||
mtest01.c:134: INFO: Filling up 80% of free ram which is 16761132 kbytes
|
||||
mtest01.c:149: INFO: ... child 20802 starting
|
||||
mtest01.c:149: INFO: ... child 20811 starting
|
||||
mtest01.c:149: INFO: ... child 20820 starting
|
||||
mtest01.c:149: INFO: ... child 20829 starting
|
||||
mtest01.c:149: INFO: ... child 20838 starting
|
||||
mtest01.c:149: INFO: ... child 20847 starting
|
||||
mtest01.c:166: INFO: ... [t=300] 1435500544 bytes allocated and used in child 20847
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20802
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20811
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20820
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20829
|
||||
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20838
|
||||
mtest01.c:221: PASS: 16761132 kbytes allocated (and written to)
|
||||
|
||||
Summary:
|
||||
passed 1
|
||||
failed 0
|
||||
skipped 0
|
||||
warnings 0
|
||||
*** C1389T04 PASSED (1)
|
||||
|
||||
*** C1389T05 start *******************************
|
||||
mem01
|
||||
mem01 0 TINFO : Free Mem: 20463 Mb
|
||||
mem01 0 TINFO : Free Swap: 0 Mb
|
||||
mem01 0 TINFO : Total Free: 20463 Mb
|
||||
mem01 0 TINFO : Total Tested: 3056 Mb
|
||||
mem01 0 TINFO : touching 3056MB of malloc'ed memory (linear)
|
||||
mem01 1 TPASS : malloc - alloc of 3056MB succeeded
|
||||
*** C1389T05 PASSED (1)
|
||||
@ -1,92 +0,0 @@
|
||||
#
|
||||
# Test script for issue #1439
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
mckdir = os.getenv('MCK_DIR')
|
||||
mckbin = mckdir + '/bin'
|
||||
mcksbin = mckdir + '/sbin'
|
||||
mcreboot = mcksbin + '/mcreboot.sh'
|
||||
mcstop = mcksbin + '/mcstop+release.sh'
|
||||
mcexec = mckbin + '/mcexec'
|
||||
|
||||
|
||||
def get_command_result(cmd):
|
||||
results = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE,
|
||||
shell=True).stdout.readlines()
|
||||
return [str(x).rstrip("\n") for x in results]
|
||||
|
||||
def enumerate_cpu(cpu_list):
|
||||
allcpus = []
|
||||
for ranged_cpu in cpu_list.split(','):
|
||||
try:
|
||||
cpu_begin, cpu_end = ranged_cpu.split('-')
|
||||
except ValueError:
|
||||
cpu_begin = cpu_end = ranged_cpu
|
||||
for i in range(int(cpu_begin), int(cpu_end) + 1):
|
||||
allcpus.append(i)
|
||||
allcpus.sort()
|
||||
return allcpus
|
||||
|
||||
def bind_cpu_core(catcmd, allcpus):
|
||||
cpucores = {}
|
||||
for cpu in allcpus:
|
||||
sysfile = '/sys/devices/system/cpu/cpu%d/topology/core_id' % cpu
|
||||
core_id = get_command_result(catcmd + ' ' + sysfile)[0]
|
||||
cpucores[cpu] = int(core_id)
|
||||
return cpucores
|
||||
|
||||
def compare_cores(linuxcpucores, mckernelcpucores):
|
||||
linuxcpus = linuxcpucores.keys()
|
||||
linuxcpus.sort()
|
||||
linuxcores = []
|
||||
for linuxcpu in linuxcpus:
|
||||
linuxcores.append(linuxcpucores[linuxcpu])
|
||||
mckernelcpus = mckernelcpucores.keys()
|
||||
mckernelcpus.sort()
|
||||
mckernelcores = []
|
||||
for mckernelcpu in mckernelcpus:
|
||||
mckernelcores.append(mckernelcpucores[mckernelcpu])
|
||||
coremap = {}
|
||||
seq = 0
|
||||
for i in range(len(linuxcores)):
|
||||
linuxcore = linuxcores[i]
|
||||
mckernelcore = mckernelcores[i]
|
||||
if linuxcore in coremap:
|
||||
if mckernelcore != coremap[linuxcore]:
|
||||
print 'FAIL'
|
||||
quit()
|
||||
else:
|
||||
if seq != mckernelcore:
|
||||
print 'FAIL'
|
||||
quit()
|
||||
seq = seq + 1
|
||||
coremap[linuxcore] = mckernelcore
|
||||
|
||||
def main():
|
||||
argvs = sys.argv
|
||||
argc = len(argvs)
|
||||
if (argc != 2):
|
||||
print 'Usage: python %s <cpu_list>' % argvs[0]
|
||||
quit()
|
||||
print 'cpu_list = %s' % argvs[1]
|
||||
cpulist = argvs[1]
|
||||
linuxcpus = enumerate_cpu(cpulist)
|
||||
linuxcpucores = bind_cpu_core('cat', linuxcpus)
|
||||
print 'linux: '
|
||||
print linuxcpucores
|
||||
get_command_result('sudo ' + mcreboot + ' -c ' + cpulist)
|
||||
mckernelcpus = [i for i in range(0, len(linuxcpus))]
|
||||
mckernelcpucores = bind_cpu_core(mcexec + ' cat', mckernelcpus)
|
||||
print 'mckernel: '
|
||||
print mckernelcpucores
|
||||
get_command_result('sudo ' + mcstop)
|
||||
compare_cores(linuxcpucores, mckernelcpucores)
|
||||
print 'SUCCESS'
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -1,16 +0,0 @@
|
||||
|
||||
all:: show-omp-cpu-affinity
|
||||
|
||||
show-omp-cpu-affinity:: show-omp-cpu-affinity.c
|
||||
fcc -Nclang -fopenmp -Nlibomp -o $@ $<
|
||||
|
||||
test:: test-core, test-omp
|
||||
|
||||
test-core::
|
||||
. ${HOME}/.mck_test_config && export MCK_DIR && python C1439.py 1-4,30-33,56-61
|
||||
|
||||
test-omp:: show-omp-cpu-affinity
|
||||
./test-affinity.sh
|
||||
|
||||
clean::
|
||||
rm show-omp-cpu-affinity
|
||||
@ -1,50 +0,0 @@
|
||||
□ テスト内容
|
||||
|
||||
/sys/devices/system/cpu/cpuX/topology/core_idについて、以下を確かめる。
|
||||
|
||||
(A) 物理コア番号の振り方について以下を確かめる
|
||||
1) 物理コアの第1の論理コアのcore_idはCPU番号(=cpu_id)と一致する
|
||||
2) 論理コアのcore_idは、それが属する物理コアの第1の論理コアのcore_idと一致する
|
||||
|
||||
(B) McKernelがcpu_idをrenumberすることによる悪影響がないか確認する
|
||||
1) 富士通OpenMPで、OMP_PROC_BINDの
|
||||
close(物理コアをラウンドロビンで選ぶ)と
|
||||
spread(CPUトポロジ上なるべく離れるように配置する)
|
||||
について、期待通りのバインディングになることを確認する
|
||||
なお、apolloでのテストでは、OMP_NUM_THREADSは2から物理コア数*2の間で、
|
||||
OMP_NUM_THREADSと物理コア数のうち、大きいほうが小さい方で
|
||||
割り切れる関係にあるものに設定した。
|
||||
|
||||
□ 実行手順
|
||||
|
||||
(1) $HOME/.mck_test_configを、MCK_DIRがMcKernelのインストール先を指すように編集する
|
||||
|
||||
(2) apolloログインノードにおいて一般ユーザで以下のコマンドを実行し、
|
||||
富士通コンパイラでテストに使うOpenMPアプリケーションバイナリを作成する。
|
||||
ソースコードはmckernelユーザでcheckoutしていると思われるが、その場合、
|
||||
本ディレクトリを、その一般ユーザが書き込めるようにwrite permissionを
|
||||
つけておく必要がある。
|
||||
|
||||
$ make
|
||||
|
||||
(3) (2)で作られたバイナリを(mckernelユーザの)apolloの計算ノードにて
|
||||
動かすために、富士通コンパイラのDLLを当該ユーザが読める場所に
|
||||
コピーして、その場所にLD_LIBRARY_PATHを通す。
|
||||
コピー元のディレクトリは富士通コンパイラ0.36では以下のディレクトリである。
|
||||
|
||||
/usr/local/FJSVxtclang/fujitsu_compilers_sve_own_20191226/sve_own/lib64
|
||||
|
||||
(4) apolloの計算ノードにおいてmckernelユーザで以下のコマンドを実行し、
|
||||
(A)(B)のテストを実行する。
|
||||
|
||||
$ make test-core # .... (A)
|
||||
$ make test-omp # .... (B)
|
||||
|
||||
|
||||
□ 確認方法
|
||||
|
||||
(A) (B) いずれにおいてもSUCCESSが出力され、FAILが出力されていないこと。
|
||||
|
||||
サンプル出力は以下のとおり
|
||||
(A) aarch64_result_core.log
|
||||
(B) aarch64_result_omp.log
|
||||
@ -1,8 +0,0 @@
|
||||
$ make test
|
||||
python C1439.py 1-4,30-33,56-61
|
||||
cpu_list = 1-4,30-33,56-61
|
||||
linux:
|
||||
{32: 4, 1: 1, 2: 2, 3: 3, 4: 4, 33: 5, 56: 256, 57: 257, 58: 258, 59: 259, 60: 260, 61: 261, 30: 2, 31: 3}
|
||||
mckernel:
|
||||
{0: 0, 1: 1, 2: 2, 3: 3, 4: 1, 5: 2, 6: 3, 7: 4, 8: 5, 9: 6, 10: 7, 11: 8, 12: 9, 13: 10}
|
||||
SUCCESS
|
||||
@ -1,108 +0,0 @@
|
||||
./test-affinity.sh
|
||||
sudo /home/toshi/install/dev2-mckernel/sbin/mcreboot.sh -m 1G@0,1G@1 -c 4-27,32-55 -O
|
||||
/home/toshi/install/dev2-mckernel/bin/mcexec python -u test-affinity.py
|
||||
CPUS: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]
|
||||
PLACES: [[0, 24], [1, 25], [2, 26], [3, 27], [4, 28], [5, 29], [6, 30], [7, 31], [8, 32], [9, 33], [10, 34], [11, 35], [12, 36], [13, 37], [14, 38], [15, 39], [16, 40], [17, 41], [18, 42], [19, 43], [20, 44], [21, 45], [22, 46], [23, 47]]
|
||||
MAP_CPU_TO_PLACE {0: [0, 24], 1: [1, 25], 2: [2, 26], 3: [3, 27], 4: [4, 28], 5: [5, 29], 6: [6, 30], 7: [7, 31], 8: [8, 32], 9: [9, 33], 10: [10, 34], 11: [11, 35], 12: [12, 36], 13: [13, 37], 14: [14, 38], 15: [15, 39], 16: [16, 40], 17: [17, 41], 18: [18, 42], 19: [19, 43], 20: [20, 44], 21: [21, 45], 22: [22, 46], 23: [23, 47], 24: [0, 24], 25: [1, 25], 26: [2, 26], 27: [3, 27], 28: [4, 28], 29: [5, 29], 30: [6, 30], 31: [7, 31], 32: [8, 32], 33: [9, 33], 34: [10, 34], 35: [11, 35], 36: [12, 36], 37: [13, 37], 38: [14, 38], 39: [15, 39], 40: [16, 40], 41: [17, 41], 42: [18, 42], 43: [19, 43], 44: [20, 44], 45: [21, 45], 46: [22, 46], 47: [23, 47]}
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [1, 25]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 1}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 2, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [12, 36]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 12}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 2, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [1, 25], 2: [2, 26]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 1, 2: 2}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 3, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [8, 32], 2: [16, 40]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 8, 2: 16}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 3, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [1, 25], 2: [2, 26], 3: [3, 27]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 1, 2: 2, 3: 3}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 4, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [6, 30], 2: [12, 36], 3: [18, 42]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 6, 2: 12, 3: 18}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 4, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [1, 25], 2: [2, 26], 3: [3, 27], 4: [4, 28], 5: [5, 29]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 6, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [4, 28], 2: [8, 32], 3: [12, 36], 4: [16, 40], 5: [20, 44]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 4, 2: 8, 3: 12, 4: 16, 5: 20}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 6, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [1, 25], 2: [2, 26], 3: [3, 27], 4: [4, 28], 5: [5, 29], 6: [6, 30], 7: [7, 31]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 8, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [3, 27], 2: [6, 30], 3: [9, 33], 4: [12, 36], 5: [15, 39], 6: [18, 42], 7: [21, 45]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 3, 2: 6, 3: 9, 4: 12, 5: 15, 6: 18, 7: 21}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 8, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [1, 25], 2: [2, 26], 3: [3, 27], 4: [4, 28], 5: [5, 29], 6: [6, 30], 7: [7, 31], 8: [8, 32], 9: [9, 33], 10: [10, 34], 11: [11, 35]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 12, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [2, 26], 2: [4, 28], 3: [6, 30], 4: [8, 32], 5: [10, 34], 6: [12, 36], 7: [14, 38], 8: [16, 40], 9: [18, 42], 10: [20, 44], 11: [22, 46]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18, 10: 20, 11: 22}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 12, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [1, 25], 2: [2, 26], 3: [3, 27], 4: [4, 28], 5: [5, 29], 6: [6, 30], 7: [7, 31], 8: [8, 32], 9: [9, 33], 10: [10, 34], 11: [11, 35], 12: [12, 36], 13: [13, 37], 14: [14, 38], 15: [15, 39], 16: [16, 40], 17: [17, 41], 18: [18, 42], 19: [19, 43], 20: [20, 44], 21: [21, 45], 22: [22, 46], 23: [23, 47]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 24, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [1, 25], 2: [2, 26], 3: [3, 27], 4: [4, 28], 5: [5, 29], 6: [6, 30], 7: [7, 31], 8: [8, 32], 9: [9, 33], 10: [10, 34], 11: [11, 35], 12: [12, 36], 13: [13, 37], 14: [14, 38], 15: [15, 39], 16: [16, 40], 17: [17, 41], 18: [18, 42], 19: [19, 43], 20: [20, 44], 21: [21, 45], 22: [22, 46], 23: [23, 47]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 24, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [0, 24], 2: [1, 25], 3: [1, 25], 4: [2, 26], 5: [2, 26], 6: [3, 27], 7: [3, 27], 8: [4, 28], 9: [4, 28], 10: [5, 29], 11: [5, 29], 12: [6, 30], 13: [6, 30], 14: [7, 31], 15: [7, 31], 16: [8, 32], 17: [8, 32], 18: [9, 33], 19: [9, 33], 20: [10, 34], 21: [10, 34], 22: [11, 35], 23: [11, 35], 24: [12, 36], 25: [12, 36], 26: [13, 37], 27: [13, 37], 28: [14, 38], 29: [14, 38], 30: [15, 39], 31: [15, 39], 32: [16, 40], 33: [16, 40], 34: [17, 41], 35: [17, 41], 36: [18, 42], 37: [18, 42], 38: [19, 43], 39: [19, 43], 40: [20, 44], 41: [20, 44], 42: [21, 45], 43: [21, 45], 44: [22, 46], 45: [22, 46], 46: [23, 47], 47: [23, 47]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 0, 2: 1, 3: 1, 4: 2, 5: 2, 6: 3, 7: 3, 8: 4, 9: 4, 10: 5, 11: 5, 12: 6, 13: 6, 14: 7, 15: 7, 16: 8, 17: 8, 18: 9, 19: 9, 20: 10, 21: 10, 22: 11, 23: 11, 24: 12, 25: 12, 26: 13, 27: 13, 28: 14, 29: 14, 30: 15, 31: 15, 32: 16, 33: 16, 34: 17, 35: 17, 36: 18, 37: 18, 38: 19, 39: 19, 40: 20, 41: 20, 42: 21, 43: 21, 44: 22, 45: 22, 46: 23, 47: 47}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 48, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [0, 24], 2: [1, 25], 3: [1, 25], 4: [2, 26], 5: [2, 26], 6: [3, 27], 7: [3, 27], 8: [4, 28], 9: [4, 28], 10: [5, 29], 11: [5, 29], 12: [6, 30], 13: [6, 30], 14: [7, 31], 15: [7, 31], 16: [8, 32], 17: [8, 32], 18: [9, 33], 19: [9, 33], 20: [10, 34], 21: [10, 34], 22: [11, 35], 23: [11, 35], 24: [12, 36], 25: [12, 36], 26: [13, 37], 27: [13, 37], 28: [14, 38], 29: [14, 38], 30: [15, 39], 31: [15, 39], 32: [16, 40], 33: [16, 40], 34: [17, 41], 35: [17, 41], 36: [18, 42], 37: [18, 42], 38: [19, 43], 39: [19, 43], 40: [20, 44], 41: [20, 44], 42: [21, 45], 43: [21, 45], 44: [22, 46], 45: [22, 46], 46: [23, 47], 47: [23, 47]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 0, 2: 1, 3: 1, 4: 2, 5: 2, 6: 3, 7: 3, 8: 4, 9: 4, 10: 5, 11: 5, 12: 6, 13: 6, 14: 7, 15: 7, 16: 8, 17: 8, 18: 9, 19: 9, 20: 10, 21: 10, 22: 11, 23: 11, 24: 12, 25: 12, 26: 13, 27: 13, 28: 14, 29: 14, 30: 15, 31: 15, 32: 16, 33: 16, 34: 17, 35: 17, 36: 18, 37: 18, 38: 19, 39: 19, 40: 20, 41: 20, 42: 21, 43: 21, 44: 22, 45: 22, 46: 23, 47: 47}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 48, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [0, 24], 2: [0, 24], 3: [1, 25], 4: [1, 25], 5: [1, 25], 6: [2, 26], 7: [2, 26], 8: [2, 26], 9: [3, 27], 10: [3, 27], 11: [3, 27], 12: [4, 28], 13: [4, 28], 14: [4, 28], 15: [5, 29], 16: [5, 29], 17: [5, 29], 18: [6, 30], 19: [6, 30], 20: [6, 30], 21: [7, 31], 22: [7, 31], 23: [7, 31], 24: [8, 32], 25: [8, 32], 26: [8, 32], 27: [9, 33], 28: [9, 33], 29: [9, 33], 30: [10, 34], 31: [10, 34], 32: [10, 34], 33: [11, 35], 34: [11, 35], 35: [11, 35], 36: [12, 36], 37: [12, 36], 38: [12, 36], 39: [13, 37], 40: [13, 37], 41: [13, 37], 42: [14, 38], 43: [14, 38], 44: [14, 38], 45: [15, 39], 46: [15, 39], 47: [15, 39], 48: [16, 40], 49: [16, 40], 50: [16, 40], 51: [17, 41], 52: [17, 41], 53: [17, 41], 54: [18, 42], 55: [18, 42], 56: [18, 42], 57: [19, 43], 58: [19, 43], 59: [19, 43], 60: [20, 44], 61: [20, 44], 62: [20, 44], 63: [21, 45], 64: [21, 45], 65: [21, 45], 66: [22, 46], 67: [22, 46], 68: [22, 46], 69: [23, 47], 70: [23, 47], 71: [23, 47]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 0, 2: 0, 3: 1, 4: 1, 5: 1, 6: 2, 7: 2, 8: 2, 9: 3, 10: 3, 11: 3, 12: 4, 13: 4, 14: 4, 15: 5, 16: 5, 17: 5, 18: 6, 19: 6, 20: 6, 21: 7, 22: 7, 23: 7, 24: 8, 25: 8, 26: 8, 27: 9, 28: 9, 29: 9, 30: 10, 31: 10, 32: 10, 33: 11, 34: 11, 35: 35, 36: 36, 37: 12, 38: 12, 39: 13, 40: 13, 41: 13, 42: 14, 43: 14, 44: 14, 45: 15, 46: 15, 47: 15, 48: 16, 49: 16, 50: 16, 51: 17, 52: 17, 53: 17, 54: 18, 55: 18, 56: 18, 57: 19, 58: 19, 59: 19, 60: 20, 61: 20, 62: 20, 63: 21, 64: 21, 65: 21, 66: 22, 67: 22, 68: 22, 69: 23, 70: 23, 71: 23}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 72, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [0, 24], 2: [0, 24], 3: [1, 25], 4: [1, 25], 5: [1, 25], 6: [2, 26], 7: [2, 26], 8: [2, 26], 9: [3, 27], 10: [3, 27], 11: [3, 27], 12: [4, 28], 13: [4, 28], 14: [4, 28], 15: [5, 29], 16: [5, 29], 17: [5, 29], 18: [6, 30], 19: [6, 30], 20: [6, 30], 21: [7, 31], 22: [7, 31], 23: [7, 31], 24: [8, 32], 25: [8, 32], 26: [8, 32], 27: [9, 33], 28: [9, 33], 29: [9, 33], 30: [10, 34], 31: [10, 34], 32: [10, 34], 33: [11, 35], 34: [11, 35], 35: [11, 35], 36: [12, 36], 37: [12, 36], 38: [12, 36], 39: [13, 37], 40: [13, 37], 41: [13, 37], 42: [14, 38], 43: [14, 38], 44: [14, 38], 45: [15, 39], 46: [15, 39], 47: [15, 39], 48: [16, 40], 49: [16, 40], 50: [16, 40], 51: [17, 41], 52: [17, 41], 53: [17, 41], 54: [18, 42], 55: [18, 42], 56: [18, 42], 57: [19, 43], 58: [19, 43], 59: [19, 43], 60: [20, 44], 61: [20, 44], 62: [20, 44], 63: [21, 45], 64: [21, 45], 65: [21, 45], 66: [22, 46], 67: [22, 46], 68: [22, 46], 69: [23, 47], 70: [23, 47], 71: [23, 47]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 0, 2: 0, 3: 1, 4: 1, 5: 1, 6: 2, 7: 2, 8: 2, 9: 3, 10: 3, 11: 3, 12: 4, 13: 4, 14: 4, 15: 5, 16: 5, 17: 5, 18: 6, 19: 6, 20: 6, 21: 7, 22: 7, 23: 7, 24: 8, 25: 8, 26: 8, 27: 9, 28: 9, 29: 9, 30: 10, 31: 10, 32: 10, 33: 11, 34: 11, 35: 35, 36: 36, 37: 12, 38: 12, 39: 13, 40: 13, 41: 13, 42: 14, 43: 14, 44: 14, 45: 15, 46: 15, 47: 15, 48: 16, 49: 16, 50: 16, 51: 17, 52: 17, 53: 17, 54: 18, 55: 18, 56: 18, 57: 19, 58: 19, 59: 19, 60: 20, 61: 20, 62: 20, 63: 21, 64: 21, 65: 21, 66: 22, 67: 22, 68: 22, 69: 23, 70: 23, 71: 23}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 72, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(close): {0: [0, 24], 1: [0, 24], 2: [0, 24], 3: [0, 24], 4: [1, 25], 5: [1, 25], 6: [1, 25], 7: [1, 25], 8: [2, 26], 9: [2, 26], 10: [2, 26], 11: [2, 26], 12: [3, 27], 13: [3, 27], 14: [3, 27], 15: [3, 27], 16: [4, 28], 17: [4, 28], 18: [4, 28], 19: [4, 28], 20: [5, 29], 21: [5, 29], 22: [5, 29], 23: [5, 29], 24: [6, 30], 25: [6, 30], 26: [6, 30], 27: [6, 30], 28: [7, 31], 29: [7, 31], 30: [7, 31], 31: [7, 31], 32: [8, 32], 33: [8, 32], 34: [8, 32], 35: [8, 32], 36: [9, 33], 37: [9, 33], 38: [9, 33], 39: [9, 33], 40: [10, 34], 41: [10, 34], 42: [10, 34], 43: [10, 34], 44: [11, 35], 45: [11, 35], 46: [11, 35], 47: [11, 35], 48: [12, 36], 49: [12, 36], 50: [12, 36], 51: [12, 36], 52: [13, 37], 53: [13, 37], 54: [13, 37], 55: [13, 37], 56: [14, 38], 57: [14, 38], 58: [14, 38], 59: [14, 38], 60: [15, 39], 61: [15, 39], 62: [15, 39], 63: [15, 39], 64: [16, 40], 65: [16, 40], 66: [16, 40], 67: [16, 40], 68: [17, 41], 69: [17, 41], 70: [17, 41], 71: [17, 41], 72: [18, 42], 73: [18, 42], 74: [18, 42], 75: [18, 42], 76: [19, 43], 77: [19, 43], 78: [19, 43], 79: [19, 43], 80: [20, 44], 81: [20, 44], 82: [20, 44], 83: [20, 44], 84: [21, 45], 85: [21, 45], 86: [21, 45], 87: [21, 45], 88: [22, 46], 89: [22, 46], 90: [22, 46], 91: [22, 46], 92: [23, 47], 93: [23, 47], 94: [23, 47], 95: [23, 47]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 0, 2: 0, 3: 0, 4: 1, 5: 1, 6: 1, 7: 1, 8: 2, 9: 2, 10: 2, 11: 2, 12: 3, 13: 3, 14: 3, 15: 3, 16: 4, 17: 4, 18: 4, 19: 4, 20: 5, 21: 5, 22: 5, 23: 5, 24: 6, 25: 6, 26: 6, 27: 6, 28: 7, 29: 7, 30: 7, 31: 31, 32: 32, 33: 8, 34: 8, 35: 8, 36: 9, 37: 9, 38: 9, 39: 9, 40: 10, 41: 10, 42: 10, 43: 10, 44: 11, 45: 11, 46: 11, 47: 11, 48: 12, 49: 12, 50: 12, 51: 12, 52: 13, 53: 13, 54: 13, 55: 13, 56: 14, 57: 14, 58: 14, 59: 14, 60: 15, 61: 15, 62: 15, 63: 15, 64: 16, 65: 16, 66: 16, 67: 16, 68: 17, 69: 17, 70: 17, 71: 17, 72: 18, 73: 18, 74: 18, 75: 18, 76: 19, 77: 19, 78: 19, 79: 19, 80: 20, 81: 20, 82: 20, 83: 20, 84: 21, 85: 21, 86: 21, 87: 21, 88: 22, 89: 22, 90: 22, 91: 22, 92: 23, 93: 23, 94: 47, 95: 23}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: close, OMP_NUM_THREAD: 96, RESULT: SUCCESS
|
||||
|
||||
./show-omp-cpu-affinity
|
||||
MAP_THREAD_TO_PLACE(spread): {0: [0, 24], 1: [0, 24], 2: [0, 24], 3: [0, 24], 4: [1, 25], 5: [1, 25], 6: [1, 25], 7: [1, 25], 8: [2, 26], 9: [2, 26], 10: [2, 26], 11: [2, 26], 12: [3, 27], 13: [3, 27], 14: [3, 27], 15: [3, 27], 16: [4, 28], 17: [4, 28], 18: [4, 28], 19: [4, 28], 20: [5, 29], 21: [5, 29], 22: [5, 29], 23: [5, 29], 24: [6, 30], 25: [6, 30], 26: [6, 30], 27: [6, 30], 28: [7, 31], 29: [7, 31], 30: [7, 31], 31: [7, 31], 32: [8, 32], 33: [8, 32], 34: [8, 32], 35: [8, 32], 36: [9, 33], 37: [9, 33], 38: [9, 33], 39: [9, 33], 40: [10, 34], 41: [10, 34], 42: [10, 34], 43: [10, 34], 44: [11, 35], 45: [11, 35], 46: [11, 35], 47: [11, 35], 48: [12, 36], 49: [12, 36], 50: [12, 36], 51: [12, 36], 52: [13, 37], 53: [13, 37], 54: [13, 37], 55: [13, 37], 56: [14, 38], 57: [14, 38], 58: [14, 38], 59: [14, 38], 60: [15, 39], 61: [15, 39], 62: [15, 39], 63: [15, 39], 64: [16, 40], 65: [16, 40], 66: [16, 40], 67: [16, 40], 68: [17, 41], 69: [17, 41], 70: [17, 41], 71: [17, 41], 72: [18, 42], 73: [18, 42], 74: [18, 42], 75: [18, 42], 76: [19, 43], 77: [19, 43], 78: [19, 43], 79: [19, 43], 80: [20, 44], 81: [20, 44], 82: [20, 44], 83: [20, 44], 84: [21, 45], 85: [21, 45], 86: [21, 45], 87: [21, 45], 88: [22, 46], 89: [22, 46], 90: [22, 46], 91: [22, 46], 92: [23, 47], 93: [23, 47], 94: [23, 47], 95: [23, 47]}
|
||||
RESULT_MAP_THREAD_TO_CPU: {0: 0, 1: 0, 2: 0, 3: 0, 4: 1, 5: 1, 6: 1, 7: 1, 8: 2, 9: 2, 10: 2, 11: 2, 12: 3, 13: 3, 14: 3, 15: 3, 16: 4, 17: 4, 18: 4, 19: 4, 20: 5, 21: 5, 22: 5, 23: 5, 24: 6, 25: 6, 26: 6, 27: 6, 28: 7, 29: 7, 30: 7, 31: 31, 32: 32, 33: 8, 34: 8, 35: 8, 36: 9, 37: 9, 38: 9, 39: 9, 40: 10, 41: 10, 42: 10, 43: 10, 44: 11, 45: 11, 46: 11, 47: 11, 48: 12, 49: 12, 50: 12, 51: 12, 52: 13, 53: 13, 54: 13, 55: 13, 56: 14, 57: 14, 58: 14, 59: 14, 60: 15, 61: 15, 62: 15, 63: 15, 64: 16, 65: 16, 66: 16, 67: 16, 68: 17, 69: 17, 70: 17, 71: 17, 72: 18, 73: 18, 74: 18, 75: 18, 76: 19, 77: 19, 78: 19, 79: 19, 80: 20, 81: 20, 82: 20, 83: 20, 84: 21, 85: 21, 86: 21, 87: 21, 88: 22, 89: 22, 90: 22, 91: 22, 92: 23, 93: 23, 94: 47, 95: 23}
|
||||
#CPU: 48, #PLACE: 24, OMP_PLACES: cores, OMP_PROC_BIND: spread, OMP_NUM_THREAD: 96, RESULT: SUCCESS
|
||||
|
||||
sudo /home/toshi/install/dev2-mckernel/sbin/mcstop+release.sh
|
||||
@ -1,19 +0,0 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
#include <omp.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#pragma omp parallel
|
||||
{
|
||||
int thread_num = omp_get_thread_num();
|
||||
int cpu_num = sched_getcpu();
|
||||
|
||||
printf("Thread %d CPU %d\n", thread_num, cpu_num);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,190 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import math
|
||||
|
||||
def get_command_result(cmd):
|
||||
print cmd
|
||||
results = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE,
|
||||
shell=True).stdout.readlines()
|
||||
return [str(x).rstrip("\n") for x in results]
|
||||
|
||||
def get_cpus():
|
||||
cpus = []
|
||||
online_file = open('/sys/devices/system/cpu/online', 'r')
|
||||
for cpurange in online_file.readlines()[0].strip().split(','):
|
||||
try:
|
||||
cpurange_start, cpurange_end = cpurange.split('-')
|
||||
except ValueError:
|
||||
cpurange_start = cpurange_end = cpurange
|
||||
for cpu in range(int(cpurange_start), int(cpurange_end) + 1):
|
||||
cpus.append(cpu)
|
||||
return cpus
|
||||
|
||||
def get_omp_places_cores(cpus):
|
||||
places = []
|
||||
map_cpu_to_place = {}
|
||||
for cpu in cpus:
|
||||
if cpu not in map_cpu_to_place:
|
||||
siblings_file = open('/sys/devices/system/cpu/cpu{0}/topology/thread_siblings_list'.format(cpu))
|
||||
place = []
|
||||
siblings = siblings_file.readlines()[0].strip().split(',')
|
||||
for sibling in siblings:
|
||||
place.append(int(sibling))
|
||||
places.append(place)
|
||||
for sibling in siblings:
|
||||
map_cpu_to_place[int(sibling)] = place
|
||||
return places, map_cpu_to_place
|
||||
|
||||
def index_of_place(places, cpu):
|
||||
i = 0
|
||||
for place in places:
|
||||
if cpu in place:
|
||||
return i
|
||||
i = i + 1
|
||||
return -1
|
||||
|
||||
def index_of_subpartition(subpartition, place):
|
||||
i = 0
|
||||
for placelist in subpartition:
|
||||
if place in placelist:
|
||||
return i
|
||||
i = i + 1
|
||||
return -1
|
||||
|
||||
def get_estimated_bind(omp_proc_bind, nthreads, places):
|
||||
if omp_proc_bind == 'close':
|
||||
return get_estimated_bind_close(0, 0, nthreads, places)
|
||||
elif omp_proc_bind == 'spread':
|
||||
return get_estimated_bind_spread(0, 0, nthreads, places)
|
||||
return None
|
||||
|
||||
def get_estimated_bind_close(master_thread, master_cpu, nthreads, places):
|
||||
map_thread_to_place = {}
|
||||
nplaces = len(places)
|
||||
# print 'nthreads =', nthreads
|
||||
# print 'nplaces =', nplaces
|
||||
if nthreads <= nplaces:
|
||||
place_idx = index_of_place(places, master_cpu)
|
||||
# print 'place_idx =', place_idx
|
||||
for i in range(nthreads):
|
||||
thread = (master_thread + i) % nthreads
|
||||
map_thread_to_place[thread] = places[(place_idx + i) % nplaces]
|
||||
else:
|
||||
s = [0] * nplaces
|
||||
for p in range(nplaces):
|
||||
if nplaces - p <= nthreads % nplaces: # implementation defined
|
||||
s[p] = nthreads / nplaces + 1 # ceil
|
||||
else:
|
||||
s[p] = nthreads / nplaces # floor
|
||||
# print 's[', p, '] =', s[p]
|
||||
i_begin = 0
|
||||
place_idx = index_of_place(places, master_cpu)
|
||||
for p in range(nplaces):
|
||||
for i in range(i_begin, i_begin + s[p]):
|
||||
thread = (master_thread + i) % nthreads
|
||||
map_thread_to_place[thread] = places[(place_idx + p) % nplaces]
|
||||
i_begin = i_begin + s[p]
|
||||
return map_thread_to_place
|
||||
|
||||
def get_estimated_bind_spread(master_thread, master_cpu, nthreads, places):
|
||||
map_thread_to_place = {}
|
||||
nplaces = len(places)
|
||||
if nthreads <= nplaces:
|
||||
places_subpartition = []
|
||||
p_begin = 0
|
||||
for i in range(nthreads):
|
||||
if nthreads - i <= nplaces % nthreads: # implementation defined
|
||||
size_places_subpartition = nplaces / nthreads + 1 # ceil
|
||||
else:
|
||||
size_places_subpartition = nplaces / nthreads # floor
|
||||
places_subpartition.append(places[p_begin:p_begin + size_places_subpartition])
|
||||
p_begin = p_begin + size_places_subpartition
|
||||
place_idx = index_of_place(places, master_cpu)
|
||||
places_subpartition_idx = index_of_subpartition(places_subpartition, places[place_idx])
|
||||
for i in range(nthreads):
|
||||
thread = (master_thread + i) % nthreads
|
||||
if thread == master_thread:
|
||||
map_thread_to_place[thread] = places[place_idx]
|
||||
else:
|
||||
map_thread_to_place[thread] = places_subpartition[(places_subpartition_idx + i) % nthreads][0]
|
||||
else:
|
||||
threads = []
|
||||
for i in range(nthreads):
|
||||
threads.append(i)
|
||||
threads_subpartition = []
|
||||
i_begin = 0
|
||||
for p in range(nplaces):
|
||||
if nplaces - p <= nthreads % nplaces: # implementation defined
|
||||
size_threads_subpartition = nthreads / nplaces + 1 # ceil
|
||||
else:
|
||||
size_threads_subpartition = nthreads / nplaces # floor
|
||||
threads_subpartition.append(threads[i_begin:i_begin + size_threads_subpartition])
|
||||
i_begin = i_begin + size_threads_subpartition
|
||||
place_idx = index_of_place(places, master_cpu)
|
||||
for p in range(nplaces):
|
||||
for i in threads_subpartition[p]:
|
||||
thread = (master_thread + i) % nthreads
|
||||
map_thread_to_place[thread] = places[p]
|
||||
return map_thread_to_place
|
||||
|
||||
def run_and_get_omp_cpu_affinity(omp_proc_bind, nthreads):
|
||||
os.environ['NODES'] = '1'
|
||||
os.environ['PPN'] = '1'
|
||||
os.environ['HWLOC_HIDE_ERRORS'] = '1'
|
||||
os.environ['OMP_PLACES'] = 'cores'
|
||||
os.environ['OMP_PROC_BIND'] = omp_proc_bind
|
||||
os.environ['OMP_NUM_THREADS'] = str(nthreads)
|
||||
command = './show-omp-cpu-affinity'
|
||||
result_map_thread_to_cpu = {}
|
||||
for line in get_command_result(command):
|
||||
outputs = line.split(' ')
|
||||
thread = outputs[1]
|
||||
cpu = outputs[3]
|
||||
result_map_thread_to_cpu[int(thread)] = int(cpu)
|
||||
return result_map_thread_to_cpu
|
||||
|
||||
def compare_result(nthreads, map_thread_to_place, result_map_thread_to_cpu):
|
||||
try:
|
||||
for thread in range(nthreads):
|
||||
place = map_thread_to_place[thread]
|
||||
if result_map_thread_to_cpu[thread] not in place:
|
||||
return False
|
||||
return True
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
def test_cpu_affinity(cpus, omp_proc_bind, nthreads, places):
|
||||
map_thread_to_place = get_estimated_bind(omp_proc_bind, nthreads, places)
|
||||
result_map_thread_to_cpu = run_and_get_omp_cpu_affinity(omp_proc_bind, nthreads)
|
||||
if compare_result(nthreads, map_thread_to_place, result_map_thread_to_cpu):
|
||||
result = 'SUCCESS'
|
||||
else:
|
||||
result = 'FAIL'
|
||||
print "MAP_THREAD_TO_PLACE({0}): {1}".format(omp_proc_bind, map_thread_to_place)
|
||||
print "RESULT_MAP_THREAD_TO_CPU: {0}".format(result_map_thread_to_cpu)
|
||||
print "#CPU: {}, #PLACE: {}, OMP_PLACES: cores, OMP_PROC_BIND: {}, OMP_NUM_THREAD: {}, RESULT: {}".format(len(cpus), len(places), omp_proc_bind, nthreads, result)
|
||||
|
||||
def main():
|
||||
cpus = get_cpus()
|
||||
print 'CPUS:', cpus
|
||||
places, map_cpu_to_place = get_omp_places_cores(cpus)
|
||||
print 'PLACES:', places
|
||||
print 'MAP_CPU_TO_PLACE', map_cpu_to_place
|
||||
print
|
||||
|
||||
nplaces = len(places)
|
||||
for nthreads in range(2, nplaces * 4 + 1):
|
||||
if nthreads < nplaces and nplaces % nthreads > 0:
|
||||
continue
|
||||
if nthreads >= nplaces and nthreads % nplaces > 0:
|
||||
continue
|
||||
test_cpu_affinity(cpus, 'close', nthreads, places)
|
||||
print
|
||||
test_cpu_affinity(cpus, 'spread', nthreads, places)
|
||||
print
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${HOME}/.mck_test_config
|
||||
export MCK_DIR
|
||||
echo sudo ${MCK_DIR}/sbin/mcreboot.sh -m 1G@0,1G@1 -c 4-27,32-55 -O
|
||||
sudo ${MCK_DIR}/sbin/mcreboot.sh -m 1G@0,1G@1 -c 4-27,32-55 -O
|
||||
#sudo ${MCK_DIR}/sbin/mcreboot.sh -m 1G@0,1G@1 -c 4-27,32-55,60-83,88-111 -r 4-7,32-35:0+8-11,36-39:1+12-15,40-43:2+16-19,44-47:3+20-23,48-51:28+24-27,52-55:29+60-63,88-91:56+64-67,92-95:57+68-71,96-99:58+72-75,100-103:59+76-79,104-107:84+80-83,108-111:85 -O
|
||||
echo ${MCK_DIR}/bin/mcexec python -u test-affinity.py
|
||||
${MCK_DIR}/bin/mcexec python -u test-affinity.py
|
||||
echo sudo ${MCK_DIR}/sbin/mcstop+release.sh
|
||||
sudo ${MCK_DIR}/sbin/mcstop+release.sh
|
||||
|
||||
|
||||
@ -1,63 +0,0 @@
|
||||
#
|
||||
# Test script for issue #1439
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
def get_command_result(cmd):
|
||||
results = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE,
|
||||
shell=True).stdout.readlines()
|
||||
return [str(x).rstrip("\n") for x in results]
|
||||
|
||||
def enumerate_cpu(cpu_list):
|
||||
allcpus = []
|
||||
for ranged_cpu in cpu_list.split(','):
|
||||
try:
|
||||
cpu_begin, cpu_end = ranged_cpu.split('-')
|
||||
except ValueError:
|
||||
cpu_begin = cpu_end = ranged_cpu
|
||||
for i in range(int(cpu_begin), int(cpu_end) + 1):
|
||||
allcpus.append(i)
|
||||
allcpus.sort()
|
||||
return allcpus
|
||||
|
||||
def get_online_cpu():
|
||||
online_file = open('/sys/devices/system/cpu/online', 'r')
|
||||
return online_file.readlines()[0].strip()
|
||||
|
||||
def get_cpuinfo_processors():
|
||||
processors = []
|
||||
cpuinfo_file = open('/proc/cpuinfo', 'r')
|
||||
for line in cpuinfo_file.readlines():
|
||||
if line.startswith('processor'):
|
||||
processor = int(line.strip().split()[-1])
|
||||
processors.append(processor)
|
||||
return processors
|
||||
|
||||
def main():
|
||||
onlines = enumerate_cpu(get_online_cpu())
|
||||
processors = get_cpuinfo_processors()
|
||||
|
||||
print '# of online cpus:', len(onlines)
|
||||
print '# of cpuinfo processors:', len(processors)
|
||||
if len(onlines) != len(processors):
|
||||
print 'ERROR: # of processors is not equal to # of cpus'
|
||||
print 'FAIL'
|
||||
exit()
|
||||
|
||||
i = 0
|
||||
for cpu in processors:
|
||||
print i, 'processor:', cpu
|
||||
if i != cpu:
|
||||
print 'ERROR: processor number is not ordered'
|
||||
print 'FAIL'
|
||||
exit()
|
||||
i = i + 1
|
||||
|
||||
print 'SUCCESS'
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${HOME}/.mck_test_config
|
||||
export MCK_DIR
|
||||
sudo ${MCK_DIR}/sbin/mcreboot.sh 1,3,5,7,9-12,50-58
|
||||
${MCK_DIR}/bin/mcexec python C1457.py
|
||||
sudo ${MCK_DIR}/sbin/mcstop+release.sh
|
||||
@ -1,2 +0,0 @@
|
||||
test::
|
||||
./C1457.shy
|
||||
@ -1,22 +0,0 @@
|
||||
□ テスト内容
|
||||
|
||||
arm64環境における/proc/cpuinfoについて、以下を確かめる。
|
||||
|
||||
(1) "processor" フィールドが/sys/devices/system/cpu/onlineファイルが示す
|
||||
CPUの数だけ存在すること。
|
||||
(2) "processor" フィールドの値が0からはじまる連番であること。
|
||||
|
||||
|
||||
□ 実行手順
|
||||
|
||||
(1) $HOME/.mck_test_configを、MCK_DIRがMcKernelのインストール先を指すように編集する
|
||||
(2) 以下を実行する
|
||||
|
||||
$ make test
|
||||
|
||||
|
||||
□ 確認方法
|
||||
|
||||
標準出力にSUCCESSが出力されること
|
||||
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
# of online cpus: 28
|
||||
# of cpuinfo processors: 28
|
||||
0 processor: 0
|
||||
1 processor: 1
|
||||
2 processor: 2
|
||||
3 processor: 3
|
||||
4 processor: 4
|
||||
5 processor: 5
|
||||
6 processor: 6
|
||||
7 processor: 7
|
||||
8 processor: 8
|
||||
9 processor: 9
|
||||
10 processor: 10
|
||||
11 processor: 11
|
||||
12 processor: 12
|
||||
13 processor: 13
|
||||
14 processor: 14
|
||||
15 processor: 15
|
||||
16 processor: 16
|
||||
17 processor: 17
|
||||
18 processor: 18
|
||||
19 processor: 19
|
||||
20 processor: 20
|
||||
21 processor: 21
|
||||
22 processor: 22
|
||||
23 processor: 23
|
||||
24 processor: 24
|
||||
25 processor: 25
|
||||
26 processor: 26
|
||||
27 processor: 27
|
||||
SUCCESS
|
||||
@ -1,145 +0,0 @@
|
||||
#/bin/sh
|
||||
|
||||
USELTP=0
|
||||
USEOSTEST=0
|
||||
|
||||
. ../../common.sh
|
||||
|
||||
issue="929"
|
||||
tid=01
|
||||
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
TEST_CMD="mpirun -f ./hostfile -ppn 5 ${MCEXEC} -n 5 ./test_prog.sh"
|
||||
echo ${TEST_CMD}
|
||||
${TEST_CMD} &> ${tname}.txt
|
||||
mpi_ret=$?
|
||||
|
||||
cat ./${tname}.txt
|
||||
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
|
||||
|
||||
if [ ${mpi_ret} -eq 0 -a ${started_num} -eq 5 ]; then
|
||||
echo "*** ${tname} PASSED ******************************"
|
||||
else
|
||||
echo "*** ${tname} FAILED ******************************"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
TEST_CMD="mpirun -f ./hostfile -ppn 5 ${MCEXEC} -n 3 ./test_prog.sh"
|
||||
echo ${TEST_CMD}
|
||||
${TEST_CMD} &> ${tname}.txt
|
||||
mpi_ret=$?
|
||||
|
||||
cat ./${tname}.txt
|
||||
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
|
||||
|
||||
if [ ${mpi_ret} -ne 0 -a ${started_num} -eq 3 ]; then
|
||||
echo "*** ${tname} PASSED ******************************"
|
||||
else
|
||||
echo "*** ${tname} FAILED ******************************"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
TEST_CMD="mpirun -f ./hostfile -ppn 3 ${MCEXEC} -n 5 ./test_prog.sh"
|
||||
echo ${TEST_CMD}
|
||||
${TEST_CMD} &> ${tname}.txt
|
||||
mpi_ret=$?
|
||||
|
||||
cat ./${tname}.txt
|
||||
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
|
||||
|
||||
if [ ${mpi_ret} -ne 0 -a ${started_num} -eq 0 ]; then
|
||||
echo "*** ${tname} PASSED ******************************"
|
||||
else
|
||||
echo "*** ${tname} FAILED ******************************"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
TEST_CMD="mpirun -f ./hostfile -ppn 6 ${MCEXEC} -n 3 ./test_prog.sh"
|
||||
echo ${TEST_CMD}
|
||||
${TEST_CMD} &> ${tname}.txt
|
||||
mpi_ret=$?
|
||||
|
||||
cat ./${tname}.txt
|
||||
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
|
||||
|
||||
if [ ${mpi_ret} -ne 0 -a ${started_num} -eq 3 ]; then
|
||||
echo "*** ${tname} PASSED ******************************"
|
||||
else
|
||||
echo "*** ${tname} FAILED ******************************"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
TEST_CMD="mpirun -f ./hostfile -ppn 250 ${MCEXEC} -n 250 ./test_prog.sh"
|
||||
echo ${TEST_CMD}
|
||||
${TEST_CMD} &> ${tname}.txt
|
||||
mpi_ret=$?
|
||||
|
||||
head -n 10 ./${tname}.txt
|
||||
echo "..."
|
||||
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
|
||||
|
||||
if [ ${mpi_ret} -ne 0 -a ${started_num} -eq 0 ]; then
|
||||
echo "*** ${tname} PASSED ******************************"
|
||||
else
|
||||
echo "*** ${tname} FAILED ******************************"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
|
||||
tname=`printf "C${issue}T%02d" ${tid}`
|
||||
echo "*** ${tname} start *******************************"
|
||||
ng=0
|
||||
TEST_CMD="mpirun -f ./hostfile -ppn 5 ${MCEXEC} -n 5 ./test_prog.sh"
|
||||
echo "** reboot mcrernel for check pe_list_len"
|
||||
mcreboot
|
||||
echo "** enable debug message in mcexec_get_cpuset"
|
||||
sudo sh -c "echo -n 'func mcexec_get_cpuset +p' > /sys/kernel/debug/dynamic_debug/control"
|
||||
echo ${TEST_CMD}
|
||||
for i in `seq 1 20`
|
||||
do
|
||||
${TEST_CMD} &> ${tname}.txt
|
||||
mpi_ret=$?
|
||||
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
|
||||
if [ ${mpi_ret} -eq 0 -a ${started_num} -eq 5 ]; then
|
||||
echo "[OK] exec: $i"
|
||||
else
|
||||
echo "[NG] exec: $i"
|
||||
let ng++
|
||||
fi
|
||||
done
|
||||
echo "** check pe_list_len"
|
||||
dmesg --notime | grep "mcexec_get_cpuset: pe_list" | tail -n 20 | cut -f 2-3 -d ':' > ./pe_list_len.txt
|
||||
cat ./pe_list_len.txt | while read line
|
||||
do
|
||||
len=`echo ${line} | cut -f 2 -d ':'`
|
||||
if [ ${len} -ge 0 -a ${len} -le 5 ]; then
|
||||
echo "[OK] ${line}"
|
||||
else
|
||||
echo "[NG] ${line}"
|
||||
let ng++
|
||||
fi
|
||||
done
|
||||
echo "** disable debug message in mcexec_get_cpuset"
|
||||
sudo sh -c "echo -n 'func mcexec_get_cpuset -p' > /sys/kernel/debug/dynamic_debug/control"
|
||||
|
||||
if [ ${ng} -eq 0 ]; then
|
||||
echo "*** ${tname} PASSED ******************************"
|
||||
else
|
||||
echo "*** ${tname} FAILED ******************************"
|
||||
fi
|
||||
let tid++
|
||||
echo ""
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
CFLAGS=-g
|
||||
LDFLAGS=
|
||||
|
||||
TARGET=
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
test: all
|
||||
./C929.sh
|
||||
clean:
|
||||
rm -f $(TARGET) *.o *.txt
|
||||
@ -1,36 +0,0 @@
|
||||
【Issue#929 動作確認】
|
||||
□ テスト内容
|
||||
1. mpirunで指定する-ppnと、mcexecで指定する-n の指定状況ごとに
|
||||
想定どおりの動作となることを確認
|
||||
C929T01:
|
||||
-ppn == -n の場合に、プログラムが実行され、mpirunが成功する
|
||||
|
||||
C929T02:
|
||||
-ppn > -n の場合に、プログラムの一部が実行され、mpirunが失敗する
|
||||
|
||||
C929T03:
|
||||
-ppn < -n の場合に、プログラムが実行されず、mpirunが失敗する
|
||||
|
||||
C929T04:
|
||||
-ppn が -n の整数倍である場合に、プログラムの一部が実行され、mpirunが失敗する
|
||||
|
||||
C929T05:
|
||||
-ppn と -n がMcKernelに割り当てたCPU数よりも大きい場合に、
|
||||
プログラムが実行されず、mpirunが失敗する
|
||||
|
||||
C929T06:
|
||||
-ppn == -n での正常実行を20回連続で行った場合に、
|
||||
プログラムが実行され、mpirunが成功する
|
||||
また、mcctrlで管理しているpart_exec_list の要素数が5を超えない
|
||||
|
||||
□ 実行手順
|
||||
$ 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していることを確認。
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user