Compare commits

...

71 Commits

Author SHA1 Message Date
1cfc5ca71f spec: prerelease 0.4 for testing cross-compile
Change-Id: I26908b6b415483711f55338e45d7b2d862b5c028
2020-06-23 08:34:10 +00:00
7ee533d620 spec: remove unnecessary mcinspect*.debug file
Fixes: 612f364 "spec: include recently added debug tools"
Change-Id: I29779132567d18f9468e3cecf2c713ad1c51729b
2020-06-23 08:34:10 +00:00
28334c7a29 cmake: treat libdwarf as required library when cross-compiling
Change-Id: I23ffb46c867b05de0e732c96912d62c630ebb44c
2020-06-23 16:18:35 +09:00
697e9386b3 cmake: fix resovling dwarf.h
Fixes: 0e787b7 "cmake: fix resolving libdwarf"
Change-Id: Iccb491c8ad07db0f15f6b1798ee8a91edc808cf7
2020-06-22 13:33:50 +09:00
0e787b731e cmake: fix resolving libdwarf
Change-Id: I14573f1ac7d779b4c90ed44cc310d4f584374559
2020-06-19 17:24:21 +09:00
612f364e6a spec: include recently added debug tools
Change-Id: I0318fe3551a75c7da774d26bc834c099bb235b67
2020-06-19 13:37:52 +09:00
ceee4c379f spec: prerelease 0.3 for testing fixes related to Fujitsu TSC and ihkmond
Change-Id: I4b9fcac086a3567e6e797f3e7515949c9e214c36
2020-06-18 16:23:43 +09:00
36c981bc34 sync with ihk
Change-Id: I052394121016a030d8873296b4a17b1f038d6b13
2020-06-18 16:23:43 +09:00
fd941dad44 Revert "procfs cpuinfo: use sequence number as processor"
This reverts commit bb7e140655.

Change-Id: If0c1719986706511c1e57d06bc61923d1adfc0aa
2020-06-16 13:26:55 +09:00
5f5b9f94d1 Revert "get_one_cpu_topology: Renumber core_id (physical core id)"
This reverts commit 0a4e6b49b4.

Change-Id: Icd9f2cda63d0daf661a40b146c72608b82cf2061
2020-06-16 13:26:55 +09:00
3f3c4acd71 madvise: do nothing (workaround for Fugaku)
Change-Id: Id2265e7eca4ae296dd22a8e99a2294a9a8b4c4dc
2020-06-16 13:26:54 +09:00
00007dafaa mbind: do nothing (workaround for Fugaku)
Change-Id: Id9d018304e18ed52ea7b0a872e03675c903bce6e
2020-06-16 13:26:54 +09:00
cbe2b2149d Revert "sysinfo, procfs: Support memory info partially"
This reverts commit 8f74888f87.

Change-Id: I65530dd8a4e1af2ca47cb02c02f5c54a9b4595a5
2020-06-16 13:26:54 +09:00
4cecde3fba Revert "mcexec: detect mismatch of mcexec -n and mpirun -ppn"
This reverts commit 72af689e69.

Change-Id: I25bc56cd8ac9c877852fc1092c8349fe318fd25d
2020-06-16 13:26:54 +09:00
8022a2a8c0 treat libfj90 as helper thread spawner (Fugaku specific)
Change-Id: I1f6170c7ebbfae4f575f13ac1f3106d292cd5b6a
2020-06-16 13:26:53 +09:00
3328ce03d9 Record pthread routine address in clone(), keep helper threads on caller CPU core (workaround for Fugaku)
Change-Id: I29d1589e430dc1396558cdf3df4d068c27173612
2020-06-16 13:26:53 +09:00
97b107f61c treat /var/opt/FJSVtcs/ple/daemonif/ as device file (Fugaku specific)
Change-Id: I047ec793a082f2fede3f2bd9c5fb358a30b8ea84
2020-06-16 13:26:53 +09:00
6f3be17c19 do_process_vm_read_writev: don't check vm_range (workaround for Fugaku)
Change-Id: I4ce9b5397ed876dff651c67658e43811d83658dd
2020-06-16 13:26:53 +09:00
dea7d00545 force allow_oversubscribe (workaround for Fugaku)
Change-Id: I5288f5ccbd967004fabbe71bca267feed3b9c2f8
2020-06-16 13:26:53 +09:00
4512778569 force time_sharing (workaround for Fugaku)
Change-Id: Ie3e3a0bbf00ef4e988bdee40d9d4dc93258dd4be
2020-06-16 13:26:52 +09:00
a7adb266ff mcinspect: add read memory value by specifying physical address
Change-Id: I2f2d6cb981e883c5e2ae1e0c764e10e0fec76a46
2020-06-16 13:26:52 +09:00
2566f4f213 devobj_free: don't report error on release-offload failure
Change-Id: I4179dab8cc46557a72eb3447ff0803743a1ba1a2
2020-06-16 13:26:52 +09:00
ac0081eddd handle_interrupt_gicv3: don't take runq_lock
To avoid dead-lock with the function taking the lock with
ihk_mc_spinlock_lock_noirq().

Change-Id: If689e8cc5fff81f627bcf98bfa7df7d4c13f4209
2020-06-16 13:26:52 +09:00
d4056acfc3 epoll, ppoll: deschedule on offload, don't do it when exiting system call
Change-Id: Ib1d0553ca5c50f4de055a1a5fe40b406c9c26dc7
2020-06-16 13:26:52 +09:00
1910543380 armv8pmu_write_counter: sign-extend properly
ihk_mc_event_set_period() calls armv8pmu_write_counter() by
cpu_pmu.write_counter(..., (uint64_t)(-left) & max_period)

Change-Id: I2ac8fbe5957db044ac54946f620163e3c486cb5f
2020-06-16 13:26:51 +09:00
6332903f0d Revert "xpmem: Support large page attachment"
This reverts commit a8696d811d.

Conflicts:
	kernel/include/process.h
	kernel/syscall.c
	kernel/xpmem.c

Change-Id: I726e74450f6228d3fc78fc62dda15b2067732a53
2020-06-16 13:25:57 +09:00
29d27b7c8d Revert "xpmem: Use correct process_vm in xpmem functions"
This reverts commit 0c63a2a3cd.

Change-Id: I7a67def6c45a67396b15cc55e96ffb5fc5898f28
2020-06-16 13:25:51 +09:00
7136384384 Revert "xpmem: Make sure vm_range is used under memory_range_lock"
This reverts commit 91ea69cf8f.

Conflicts:
	kernel/xpmem.c

Change-Id: Iff3eed010ad3610d63e165f53484ac56528ce384
2020-06-16 13:22:49 +09:00
2fe5c8de2e Revert "xpmem: Fix deadlock in xpmem_remove_process_memory_range()"
This reverts commit d052acab1d.

Change-Id: I31e982465ef9e0936145f27c8d1587c01737ec81
2020-06-16 12:13:49 +09:00
e774e1b984 Revert "xpmem: fix mapping of attachment and segment"
This reverts commit a5fcc91656.

Change-Id: If29415369d724391b291939ecce76482138e82f5
2020-06-16 11:28:02 +09:00
33b7414615 Revert "xpmem: map only resident segment pages at attach time (workaround for Fugaku)"
This reverts commit 3c646e2485.

Change-Id: Ibae8100403586775a32d6eb36c74383131066ac9
2020-06-16 11:27:59 +09:00
3c646e2485 xpmem: map only resident segment pages at attach time (workaround for Fugaku)
Change-Id: I50ac8ba88b208608206b68b4c57e278041913503
2020-06-16 09:17:26 +09:00
a5fcc91656 xpmem: fix mapping of attachment and segment
* Mapping attached part of segment is done at attach time instead of
  make time to work with runtimes (e.g. OpenMPI) xpmem_make-ing the
  entire user-space
* Mapping attached part of segment at attach time can be turned off by
  specifying xpmem_remote_on_demand in kernel argument
* Mapping attachment chooses appropriate page-sizes, i.e., largest
  allowed by memory range and segment page boundary

Fixes: a8696d8 "xpmem: Support large page attachment"
Change-Id: I44663865204036520e5f62fe22b9134ee4629f9b
2020-06-15 10:11:29 +09:00
d370e9241f Toggle preemption while faulting pages
Change-Id: I74201061bb3e7c7c4032e3884658ace87cb85948
2020-06-15 10:11:29 +09:00
3e254c06bf SCD_MSG_WAKE_UP_SYSCALL_THREAD: hold target thread through wake-up
Change-Id: I35b2c56f78430135b2d197d2a2cfe364dbd03947
2020-06-15 10:11:29 +09:00
07537cd2e7 eclair-dump-backtrace: expect script to dump backtrace on all CPUs
Change-Id: I358c5d5ca81903b0eaab88d227c36373164c0950
2020-06-15 10:11:29 +09:00
a37f72da0e futex_wake(): disable IRQs while iterating plist
Change-Id: I796794b2159816183c6487ef0048f42f97aac73b
2020-06-15 10:11:28 +09:00
ab11b168f0 ptrace_setoptions: debug msg
Change-Id: Iea5fdb26884c7af6e3d5aa26b5f71932f730cc9d
2020-06-15 10:11:28 +09:00
eac414d6d8 CPU read/write reg: use generic IHK messaging interface
Change-Id: Ia9637d1516d9329fdadf37822bfce7594d69105f
2020-06-15 10:11:28 +09:00
bb725f5f50 crash: print actual PTE in lookup mode
Change-Id: Ie2c1b97780347d6172ef8961ed62258117cbf115
2020-06-15 10:11:28 +09:00
5224551782 mcinspect: vtop (in progress)
Change-Id: I09f487e96edc7c4f59c97e6fb6dde28baf84c1e5
2020-06-15 10:11:28 +09:00
91146acfe5 Make struct ihk_os_rusage compatible with mckernel_rusage (workaround for Fugaku)
Change-Id: Iebae1e8b0aaf9c23cb1c9411aa1ad111b2e61028
2020-06-15 10:10:57 +09:00
f64731ab34 do_migrate: kick scheduler on target CPU
Change-Id: Ib5875ecf0c6a3118d32973329a6f1595a910562f
2020-06-15 09:58:55 +09:00
cd46cbd4b3 mcinspect and mcps: DWARF based LWK inspection
Change-Id: Ie9e209d8f77999b61afa39c38832bfc416a2c34f
2020-06-15 09:58:54 +09:00
39780917af libdwarf: compile locally if not present
Change-Id: I70d1f653f4fc4ee4daeaa2c9c6bdbf1416e43c9b
2020-06-15 09:58:52 +09:00
0f8f6d298e CMakeLists.txt: fail on missing libraries at config time
Change-Id: Ia7e4cf469d94f97fa1c565e59d2d4587f3a3d081
2020-06-13 17:18:10 +09:00
f8e8b21f04 /dev/shm: use Linux PFNs and populate mappings
Change-Id: I921c1f43c8411f896343be17e0ac6762a1bc26d1
2020-06-13 17:18:10 +09:00
5c2f9b8239 pager: prefetch all shared libraries
Change-Id: Ic62e1284d540362df817098b3926ac223245e3b6
2020-06-13 17:18:10 +09:00
1afc3d9b70 Keep track of number of context switches per CPU
Change-Id: I7a2194c8777a7efcd34e1ed7f4734da03fb4d433
2020-06-13 17:18:10 +09:00
17a8f68d60 set_timer(): treat spin wait as PS_RUNNING
Change-Id: Iea1ad5b0a49a12d5e1aef38ad68fccb8d789af5e
2020-06-13 17:18:10 +09:00
2b9a053504 syscall offload: avoid double IRQ enabling
Change-Id: I202c9f348b66672b1c9f8c146d4e28ec1d9c7658
2020-06-13 17:18:09 +09:00
6441aa1abb __sched_wakeup_thread(): check if timesharing needs to be enabled
Change-Id: I081d700f345abbbdb14dcac3b6246b79475d059b
2020-06-13 17:18:09 +09:00
9b55b68934 Allow other threads to run while waiting for I/O in page faults
Change-Id: I51e847a02a698b0ecf1e356d51599aa1c9400b15
2020-06-13 17:18:09 +09:00
83ef96a739 fileobj: disable IRQs while holding page hash locks, schedule() in I/O loop
Change-Id: Iaf72d55980f1a5df6c93c4a57fa57b0ae5b1d229
2020-06-13 17:18:09 +09:00
b5337358cf IKC: increase message queue sizes
Change-Id: Ib1eee4d26b8304cbee16fe50caabfc2c19e5c2e3
2020-06-13 17:18:09 +09:00
2db3717e57 handle_interrupt_gicv3(): check for CPU_FLAG_NEED_RESCHED as well
Change-Id: Id6ade08e4e572a6d837476de2872126442d3591c
2020-06-13 17:18:09 +09:00
5395891966 pager_req_map: fix printk
Change-Id: I98488169f02656c2df711b827d0002762de69f7a
2020-06-13 17:18:09 +09:00
c32a5e261b PF handler: print VM range's file path if available
Change-Id: I5ba55b19a0b874bc9f4b58e94bfc4afc440e6a8a
2020-06-13 17:18:09 +09:00
c0c80b71ca mmap and fileobj: handle MF_ZEROFILL properly
Change-Id: I6ee52b4cab212b1973339bc8d49065c1ec9263b0
2020-06-13 17:18:09 +09:00
d15a396d5a pager: use host physical for PMIx shared memory
Change-Id: Idfebc768ba03b5536a0e5eb1c6076769806fa7aa
2020-06-13 17:18:08 +09:00
e35ec09da1 UCX: fix page size for shared memory
Change-Id: I75b0beef8345b391e7619887765ed1a89d74c29b
2020-06-13 17:18:08 +09:00
5e44c9c9f9 epoll_wait(): make sure to schedule in offload
Change-Id: I435416cb0ac005a03cd995bf1aae75c9ce7b2082
2020-06-13 17:18:08 +09:00
0f6c36870c mcexec_syscall(): disable no per-process structure warning
Change-Id: I951575f0077054ebcfe4b3f7e29416799ab6ade8
2020-06-13 17:18:08 +09:00
2ec2112cc5 IKC: use atomic allocation during initialization
Change-Id: I5bb5d7040092d47e4cdbdad87f9d1dd5b2ceaee5
2020-06-13 17:18:08 +09:00
c86a38e18f physical memory: guard rbtree allocator with IHK_RBTREE_ALLOCATOR macro
Change-Id: I468c6bf1f641875c02b091704ef63f59fd390be5
2020-06-13 17:18:08 +09:00
6aa7b50e26 profile: refactor display code and fix ARM support
Change-Id: Ic48102c42abe17eed014f2bfe7523d0d6f03c2e9
2020-06-13 17:18:08 +09:00
c3c57940ba Memory ordering and usage of ASM cmpxchg() instead of compiler atomic intrinsics
Change-Id: I4dadebc32721744dad982f3fc5b3eea7ab7ca745
2020-06-13 17:18:08 +09:00
7aa2d64294 obtain_clone_cpuid(): avoid locking while partitioned execution
Change-Id: Iabb4784835be7dc9b2f555acc3a711fcc23ee7da
2020-06-13 17:18:08 +09:00
51fe77cdae mmap()/shmget(): use Linux huge page size when not specified
Fixes: 089b443 "mmap()/shmget(): use Linux default huge page size when not specified"
Change-Id: If8043a0993d1131ea0344aa6d500b35c7a291884
2020-06-13 17:18:08 +09:00
d5aafca1ae VM: use RW spinlock for vm_range_lock
Change-Id: Id4654084207d55bf77cc9f8b42795e0f9873cfa0
2020-06-12 03:07:33 +00:00
54b529c82d An arch independent RW spinlock implementation
Change-Id: I426d3f7b643660e6685b5c39c0ae849a9f08b9bb
2020-06-12 03:07:33 +00:00
121 changed files with 3143 additions and 5981 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -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.4")
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,36 @@ 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()
find_library(LIBDWARF dwarf)
if (NOT LIBDWARF)
if (CMAKE_CROSSCOMPILING)
message(FATAL_ERROR "Could not find libdwarf.so, install libdwarf-devel to ${CMAKE_FIND_ROOT_PATH}")
endif()
message("WARNING: libdwarf will be compiled locally")
enable_language(CXX)
else()
# Note that libdwarf-devel provides /usr/include/libdwarf/dwarf.h
# but elfutils-devel provides /usr/include/dwarf.h
# while mcinspect.c performs "#include <dwarf.h>"
find_path(DWARF_H dwarf.h PATH_SUFFIXES libdwarf)
endif()
if (ENABLE_QLMPI)
find_package(MPI REQUIRED)
@ -186,10 +214,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"

View File

@ -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.

View File

@ -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;
}

View File

@ -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)

View File

@ -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();
}
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;
irqstate = ihk_mc_spinlock_lock(&runq_reservation_lock);
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);
}
ihk_mc_spinlock_unlock(&runq_reservation_lock, irqstate);
#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(&lthread->vm->memory_range_lock);
ihk_rwspinlock_read_lock_noirq(&lthread->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(&lthread->vm->memory_range_lock);
ihk_rwspinlock_read_unlock_noirq(&lthread->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(&lthread->vm->memory_range_lock);
ihk_rwspinlock_read_lock_noirq(&lthread->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(&lthread->vm->memory_range_lock);
ihk_rwspinlock_read_unlock_noirq(&lthread->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;

View File

@ -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");

View File

@ -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)

View File

@ -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(&lthread->vm->memory_range_lock);
ihk_rwspinlock_read_lock_noirq(&lthread->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(&lthread->vm->memory_range_lock);
ihk_rwspinlock_read_unlock_noirq(&lthread->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(&lthread->vm->memory_range_lock);
ihk_rwspinlock_read_lock_noirq(&lthread->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(&lthread->vm->memory_range_lock);
ihk_rwspinlock_read_unlock_noirq(&lthread->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;

View 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()

View 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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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),

View File

@ -228,18 +228,19 @@ 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);
__FUNCTION__, packet->pid);
return ret;
}
/* 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(&current->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,10 +1622,27 @@ 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;

View File

@ -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);

View File

@ -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,18 @@ 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_include_directories(mcinspect PRIVATE ${DWARF_H})
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 +86,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}")

View File

@ -0,0 +1,3 @@
if (NOT LIBDWARF)
add_subdirectory(libdwarf)
endif()

View 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()

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

10
executer/user/mcps.in Normal file
View 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

Submodule ihk updated: b680d18588...1a6150c5bb

View File

@ -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 */
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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 */

View File

@ -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.

View File

@ -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;
}

View File

@ -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;
@ -3299,8 +3297,11 @@ static void do_migrate(void)
dkprintf("%s: migrated TID %d from CPU %d to CPU %d\n",
__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;

View File

@ -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,

View File

@ -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",
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);
print_profile_events(thread->profile_events,
"TID: %4d elapsed cycles (excluding idle): %luk\n",
"TID",
thread->tid,
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",
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);
print_profile_events(proc->profile_events,
"PID: %4d elapsed cycles for all threads (excluding idle): %luk\n",
"PID",
proc->pid,
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",
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);
print_profile_events(job_profile_events,
"JOB: (%2d) elapsed cycles for all threads (excluding idle): %luk\n",
"JOB",
job_nr_processes,
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);

View File

@ -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,
IHK_SCD_REQ_THREAD_SPINNING,
IHK_SCD_REQ_THREAD_DESCHEDULED)) {
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_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,36 +1973,41 @@ 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)) {
int i;
enum ihk_mc_pt_attribute ptattr;
ptattr = arch_vrflag_to_ptattr(range->flag, PF_POPULATE, NULL);
if (memobj->flags & MF_ZEROFILL) {
int i;
enum ihk_mc_pt_attribute ptattr;
ptattr = arch_vrflag_to_ptattr(range->flag, PF_POPULATE, NULL);
for (i = 0; i < memobj->nr_pages; ++i) {
error = ihk_mc_pt_set_range(proc->vm->address_space->page_table,
proc->vm,
(void *)range->start + (i * PAGE_SIZE),
(void *)range->start + (i * PAGE_SIZE) +
PAGE_SIZE,
virt_to_phys(memobj->pages[i]),
ptattr,
PAGE_SHIFT,
range,
0);
if (error) {
kprintf("%s: ERROR: mapping %d page of pre-mapped file\n",
__FUNCTION__, i);
for (i = 0; i < memobj->nr_pages; ++i) {
error = ihk_mc_pt_set_range(proc->vm->address_space->page_table,
proc->vm,
(void *)range->start + (i * PAGE_SIZE),
(void *)range->start + (i * PAGE_SIZE) +
PAGE_SIZE,
virt_to_phys(memobj->pages[i]),
ptattr,
PAGE_SHIFT,
range,
0);
if (error) {
kprintf("%s: ERROR: mapping %d page of pre-mapped file\n",
__FUNCTION__, i);
}
}
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;
}
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 if (memobj->flags & MF_REG_FILE) {
@ -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,10 +2836,35 @@ 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 (cpuid == -1) {
kprintf("do_fork,core not available\n");
return -EAGAIN;
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,
@ -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();
}

View File

@ -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)) {
ret = ihk_mc_pt_set_pte(vm->address_space->page_table, att_pte,
seg_pgsize, seg_phys, att_attr);
if (att_pte) {
ret = ihk_mc_pt_set_pte(vm->address_space->page_table, att_pte,
att_pgsize, seg_phys, att_attr);
if (ret) {
ret = -EFAULT;
ekprintf("%s: ERROR: ihk_mc_pt_set_pte() failed %d\n",
__func__, ret);
ekprintf("%s: ERROR: ihk_mc_pt_set_pte() failed %d\n",
__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);
ret = ihk_mc_pt_set_range(vm->address_space->page_table, vm,
att_pgaddr, att_pgaddr + att_pgsize, seg_phys, att_attr,
vmr->pgshift, vmr, 0);
if (ret) {
ret = -EFAULT;
ekprintf("%s: ERROR: ihk_mc_pt_set_range() failed %d\n",
__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,7 +2026,8 @@ static pte_t * xpmem_vaddr_to_pte(
}
out:
return pte;
return pte;
}
@ -2143,35 +2037,37 @@ 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;
}
ihk_atomic_inc(&tg->n_pinned);
out:
if (is_remote_vm(src_vm)) {
ihk_mc_spinlock_unlock_noirq(&src_vm->memory_range_lock);
ret = page_fault_process_vm(src_vm, (void *)vaddr,
PF_POPULATE | PF_WRITE | PF_USER);
if (!ret) {
ihk_atomic_inc(&tg->n_pinned);
}
else {
return -ENOENT;
}
XPMEM_DEBUG("return: ret=%d", ret);
return 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;
}

View File

@ -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 */

View 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
}
}

View File

@ -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,9 @@ 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
%{_bindir}/vmcore2mckdump
%{_bindir}/mcstat
%{_libdir}/libihk.so

View File

@ -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

View File

@ -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

View File

@ -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していることを確認。

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,2 +0,0 @@
PGSHIFT_LIST=(21 29 34)
SMALL_PGSIZE=65536

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -1,2 +0,0 @@
PGSHIFT_LIST=(21 30)
SMALL_PGSIZE=4096

View File

@ -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

View File

@ -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していることを確認。

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -1,11 +0,0 @@
CFLAGS=-g
LDFLAGS=
TARGET=C1389T01
all: $(TARGET)
test: all
sh ./C1389.sh
clean:
rm -f $(TARGET) *.o *.txt

View File

@ -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していることを確認。

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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物理コアをラウンドロビンで選ぶ
spreadCPUトポロジ上なるべく離れるように配置する
について、期待通りのバインディングになることを確認する
なお、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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -1,2 +0,0 @@
test::
./C1457.shy

View File

@ -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が出力されること

View File

@ -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

View File

@ -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 ""

View File

@ -1,11 +0,0 @@
CFLAGS=-g
LDFLAGS=
TARGET=
all: $(TARGET)
test: all
./C929.sh
clean:
rm -f $(TARGET) *.o *.txt

View File

@ -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