Compare commits

...

98 Commits

Author SHA1 Message Date
542418b1fc spec: prerelase 0.9 for testing libdwarf related package requirements
Change-Id: Iaaa116018505c4f89813883f5a99c8194cb4f99e
2020-07-29 12:22:08 +09:00
b95a2fcfab spec, README.md: fix libdwarf related package requirements
Change-Id: I460d440e33d0ff5e8ab3d4f7b328f7f2ea11bc16
2020-07-29 12:08:04 +09:00
1b11496f26 spec, README.md: add package dependency including libdwarf
Change-Id: Ie612c5dc642a9f5d6d2ba31747adb991cb568113
2020-07-22 06:59:37 +00:00
7c0e624b13 spec: prerelase 0.8 for testing mcexec -n issue
Change-Id: Ie54f7bc74097c8390f75ddbd0d6e58a8ea87ea7c
2020-07-21 13:31:45 +09:00
0b66bab992 Revert "mcexec: detect mismatch of mcexec -n and mpirun -ppn"
This reverts commit 1d135492c3.

Conflicts:
	executer/kernel/mcctrl/control.c

Change-Id: I224cced408aa4b77691a153c5e1d2fdf8043fa04
2020-07-21 13:08:21 +09:00
63ed4e7af0 spec: prerelase 0.7 for testing hugetlb map for stack
Change-Id: I4997340cd984ca8915e45749b91b1d72c1de85af
2020-07-20 08:11:40 +09:00
d7cf39883f Revert "shmobj: Support large page"
This reverts commit 9a60997ea0.

Change-Id: Id60959b4e03451987239faa0bbc2e780b72fafaa
2020-07-19 12:53:45 +00:00
40f8091fab stack: grow on page fault
The steps of the technique to replace stack with hugetlbfs map are as
follows:

(1) Prepare a hugetlbfs map with the size of rlim_cur
(2) Copy the active region of the stack to the hugetlbfs map.
    The range to copy is determined by reading /proc/[pid]/maps.
(3) Replace the stack map with the hugetlbfs map

The step (2) tries to copy a huge region if McKernel doesn't grow the
stack at run-time.

Change-Id: I5858c35b5c26dd0a42cccf9e3cc4c64b1a81f160
2020-07-19 12:53:31 +00:00
a20e1acf01 syscall: add prlimit64
Change-Id: Iad882813d54b439c236c0df74dc81508190e6707
2020-07-19 21:52:46 +09:00
b3d7bbda56 rus_vm_fault: compat: RHEL-8.2
This applies the following patch:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1c8f422059ae5da07db7406ab916203f9417e396
mm: change return type to vm_fault_t

Change-Id: I7189fc92824d21b4906f1033f1de5899bbad4680
2020-07-15 13:02:32 +09:00
9a60997ea0 shmobj: Support large page
Mixing page sizes is allowed by shmobj.

Change-Id: Ic48b71da2db6ce3f68fa3dbc8ad5ae96347d6018
Refs: #1381
Refs: #1458
2020-07-15 03:50:56 +00:00
4b66373813 mcexec: Don't forward SIGTSTP SIGTTIN SIGTTOUT to mckernel
Change-Id: I72bb74d6b98e1f0bf519c8f0fef742624a2a699a
Refs: #1425
2020-07-14 08:34:11 +00:00
b44b11ace7 set_robust_list: Add error check
set_robust_list is not supported by McKernel.

Change-Id: I1f679e2e4df24139cceb1f2294bc072cb7956002
Refs: 1399
2020-07-14 01:06:49 +00:00
ebc91cea0e tgkill: Fix argument validatation
Formerly, if tgid is specified as -1, tgkill() was equivalent to tkill().
Now it is treated as an error EINVAL.

Change-Id: I47bc75d439662a36dc6167c4446a5277422de507
Refs: 1380
2020-07-14 01:03:47 +00:00
58106d791a struct process: fix type of group_exit_status
Change-Id: Ib8492cbb077106cef1d0fa2d6d5e8e13bbb209c0
Refs: #1377
2020-07-13 08:33:07 +00:00
56b51d4f97 spec: prerelase 0.6 for testing cpuinfo and mmap overcommit
Change-Id: Iab5acc2c08ebe19251c37782cff87a4b5c914448
2020-07-13 10:14:23 +09:00
bafe540d86 mmap: allow unlimited overcommit
Change-Id: Iba07b5c504b4a202cd163ce682f3fc72a31284a0
2020-07-10 14:52:57 +09:00
d78a0fd05d sysinfo: support basic entries
Change-Id: I27f3e55058cc29f895831a1dddfafbc8585746a5
refs: #1389
2020-07-10 14:51:25 +09:00
999bc91b4f arch: Move some functions from arch-dependent to common part
Moved syscall rt_sigaction and functions related to signal.

Change-Id: I39f619e008d9c6018d91099a76dfb30e48757673
Refs: 1487
2020-07-10 03:54:28 +00:00
b3bd2ea9b3 procfs cpuinfo: use sequence number as processor
Change-Id: Id54ea74c5fda198a0bb9c9b6a19e6799fee0ed3f
2020-07-09 13:10:08 +09:00
d3d9e2400d test: ihklib: syscall_list.h: add robust marker for patch
Change-Id: Ie5f72b4b296db4d44e9839f38fd9a68854be78c3
2020-07-06 16:25:11 +09:00
199407b2a1 spec: prerelease 0.5 for testing ppoll
Change-Id: I51deb1c1703a986ba0aa4e02da9f53009554dbb7
2020-07-01 08:49:08 +09:00
5973d66e2d Revert "epoll_wait(): make sure to schedule in offload"
This reverts commit 5e44c9c9f9.

Change-Id: I826336f1ece31a84072c3e62c6c6c68a641e8fb5
2020-06-30 17:11:26 +09:00
d7ef74659b Revert "epoll, ppoll: deschedule on offload, don't do it when exiting system call"
This reverts commit d4056acfc3.

Change-Id: I7df15b9d3957ca571f4b4e2d576799f8b97ae299
2020-06-30 17:11:23 +09:00
ac86affecc mcexec: fix FLIB_AFFINITY_ON_PROCESS mask for McKernel CPU numbers (Fugaku)
Change-Id: If42b139fb53866bcff0809d898d4a2a712946f0c
2020-06-30 16:29:03 +09:00
2026cf8dad mcexec: explicit CPU list in partitoned execution (for Fujitsu's FLIB_AFFINITY_ON_PROCESS)
Change-Id: I05c11f73553de8ccb5f79083ce2115ac57e62584
2020-06-30 16:29:00 +09:00
1d135492c3 mcexec: detect mismatch of mcexec -n and mpirun -ppn
Change-Id: I0c42e3119143da40ea2e69cd9ec99bde78a0ad2a
Refs: #929
2020-06-30 16:28:08 +09:00
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
135 changed files with 5136 additions and 6035 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.9")
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,9 @@ 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.
26. mmap() allows unlimited overcommit. Note that it corresponds to
setting sysctl ``vm.overcommit_memory`` to 1.

View File

@ -64,7 +64,7 @@ First, the proxy process is compiled as a position independent binary, which ena
For a smooth experience, we recommend the following combination of OS distributions and platforms:
- CentOS 7.3+ running on Intel Xeon / Xeon Phi
- CentOS 7.3+ running on Intel Xeon, Xeon Phi, Fujitsu A64FX
##### 1. Change SELinux settings
@ -85,7 +85,12 @@ sudo reboot
You will need the following packages installed:
~~~~
sudo yum install cmake kernel-devel binutils-devel systemd-devel numactl-devel gcc make nasm git
sudo yum install cmake kernel-devel binutils-devel systemd-devel numactl-devel gcc make nasm git libdwarf-devel
~~~~
Note that to install libdwarf-devel to RHEL-8.2, you need to enable the CodeReady Linux Builder (CLB) repository and the EPEL repository with the following commands:
~~~~
sudo subscription-manager repos --enable codeready-builder-for-rhel-8-$(/bin/arch)-rpms
~~~~
Grant read permission to the System.map file of your kernel version:
@ -128,7 +133,7 @@ The IHK kernel modules and McKernel kernel image should be installed under the *
###### 4.2 Install with rpm
Configure, compile and build rpm:
Build rpm:
~~~~
mkdir -p build && cd build
@ -179,7 +184,7 @@ IHK/McKernel booted.
~~~~
##### 5. Run a simple program on McKernel
##### 6. Run a simple program on McKernel
The mcexec command line tool (which is also the Linux proxy process) can be used for executing applications on McKernel:
@ -189,7 +194,7 @@ centos-vm
~~~~
##### 6. Shutdown McKernel
##### 7. Shutdown McKernel
Finally, to shutdown McKernel and release CPU/memory resources back to Linux use the following command:
@ -197,27 +202,27 @@ Finally, to shutdown McKernel and release CPU/memory resources back to Linux use
sudo ./sbin/mcstop+release.sh
~~~~
##### 7. Advanced: Enable Utility Thread offloading Interface (UTI)
##### 8. Advanced: Enable Utility Thread offloading Interface (UTI)
UTI enables a runtime such as MPI runtime to spawn utility threads such as MPI asynchronous progress threads to Linux cores.
1. Install capstone
###### 8.1 Install capstone
Install EPEL capstone-devel:
~~~~
sudo yum install epel-release
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
sudo yum install capstone-devel
~~~~
2. Install syscall_intercept
###### 8.2 Install syscall_intercept
~~~~
git clone https://github.com/RIKEN-SysSoft/syscall_intercept.git
cmake ../arch/aarch64 -DCMAKE_INSTALL_PREFIX=<syscall-intercept-install> -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DTREAT_WARNINGS_AS_ERRORS=OFF
~~~~
3. Install UTI for McKernel
###### 8.3 Install UTI for McKernel
Install:
@ -228,19 +233,19 @@ mkdir build && cd build
make && make install
~~~~
4. Install McKernel
###### 8.4 Install McKernel
~~~~
CMAKE_PREFIX_PATH=<syscall-intercept-install> cmake -DCMAKE_INSTALL_PREFIX=${HOME}/ihk+mckernel -DENABLE_UTI=ON $HOME/src/ihk+mckernel/mckernel
~~~~
5. Run executable
###### 8.5 Run executable
~~~~
mcexec --enable-uti <command>
~~~~
6. Install UTI for Linux for performance comparison
###### 8.6 Install UTI for Linux for performance comparison
Install by make:

View File

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

@ -85,7 +85,11 @@ enum __rlimit_resource
__RLIMIT_RTPRIO = 14,
#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
__RLIMIT_NLIMITS = 15,
/* timeout for RT tasks in us */
__RLIMIT_RTTIME = 15,
#define RLIMIT_RTTIME __RLIMIT_RTTIME
__RLIMIT_NLIMITS = 16,
__RLIM_NLIMITS = __RLIMIT_NLIMITS
#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
#define RLIM_NLIMITS __RLIM_NLIMITS

View File

@ -118,6 +118,7 @@ SYSCALL_HANDLED(241, perf_event_open)
SYSCALL_DELEGATED(241, perf_event_open)
#endif // PERF_ENABLE
SYSCALL_HANDLED(260, wait4)
SYSCALL_HANDLED(261, prlimit64)
SYSCALL_HANDLED(270, process_vm_readv)
SYSCALL_HANDLED(271, process_vm_writev)
SYSCALL_HANDLED(281, execveat)
@ -143,3 +144,9 @@ SYSCALL_HANDLED(1045, signalfd)
SYSCALL_DELEGATED(1049, stat)
SYSCALL_DELEGATED(1060, getpgrp)
SYSCALL_HANDLED(1062, time)
SYSCALL_DELEGATED(1069, epoll_wait)
/* Do not edit the lines including this comment and
* EOF just after it because those are used as a
* robust marker for the autotest patch.
*/

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,22 +128,20 @@ 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;
}
int
arch_clear_host_user_space()
{
struct thread *th = cpu_local_var(current);
/* XXX: might be unnecessary */
clear_host_pte(th->vm->region.user_start,
(th->vm->region.user_end - th->vm->region.user_start), 0);
return 0;
}
/* archtecture-depended syscall handlers */
extern unsigned long do_fork(int clone_flags, unsigned long newsp,
unsigned long parent_tidptr, unsigned long child_tidptr,
@ -152,33 +174,6 @@ SYSCALL_DECLARE(clone)
return ret;
}
SYSCALL_DECLARE(rt_sigaction)
{
int sig = ihk_mc_syscall_arg0(ctx);
const struct sigaction *act = (const struct sigaction *)ihk_mc_syscall_arg1(ctx);
struct sigaction *oact = (struct sigaction *)ihk_mc_syscall_arg2(ctx);
size_t sigsetsize = ihk_mc_syscall_arg3(ctx);
struct k_sigaction new_sa, old_sa;
int rc;
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
if(act)
if(copy_from_user(&new_sa.sa, act, sizeof new_sa.sa)){
goto fault;
}
rc = do_sigaction(sig, act? &new_sa: NULL, oact? &old_sa: NULL);
if(rc == 0 && oact)
if(copy_to_user(oact, &old_sa.sa, sizeof old_sa.sa)){
goto fault;
}
return rc;
fault:
return -EFAULT;
}
SYSCALL_DECLARE(prctl)
{
struct process *proc = cpu_local_var(current)->proc;
@ -1335,70 +1330,6 @@ out:
return restart;
}
static struct sig_pending *
getsigpending(struct thread *thread, int delflag){
struct list_head *head;
mcs_rwlock_lock_t *lock;
struct mcs_rwlock_node_irqsave mcs_rw_node;
struct sig_pending *next;
struct sig_pending *pending;
__sigset_t w;
w = thread->sigmask.__val[0];
lock = &thread->sigcommon->lock;
head = &thread->sigcommon->sigpending;
for(;;) {
if (delflag) {
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
}
else {
mcs_rwlock_reader_lock(lock, &mcs_rw_node);
}
list_for_each_entry_safe(pending, next, head, list){
if(!(pending->sigmask.__val[0] & w)){
if(delflag)
list_del(&pending->list);
if (delflag) {
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
}
else {
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
}
return pending;
}
}
if (delflag) {
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
}
else {
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
}
if(lock == &thread->sigpendinglock)
return NULL;
lock = &thread->sigpendinglock;
head = &thread->sigpending;
}
return NULL;
}
struct sig_pending *
hassigpending(struct thread *thread)
{
if (list_empty(&thread->sigpending) &&
list_empty(&thread->sigcommon->sigpending)) {
return NULL;
}
return getsigpending(thread, 0);
}
int
interrupt_from_user(void *regs0)
{
@ -1422,191 +1353,6 @@ void save_syscall_return_value(int num, unsigned long rc)
}
}
void
check_signal(unsigned long rc, void *regs0, int num)
{
__check_signal(rc, regs0, num, 0);
}
void
check_signal_irq_disabled(unsigned long rc, void *regs0, int num)
{
__check_signal(rc, regs0, num, 1);
}
static void
__check_signal(unsigned long rc, void *regs0, int num, int irq_disabled)
{
ihk_mc_user_context_t *regs = regs0;
struct thread *thread;
struct sig_pending *pending;
int irqstate;
if(clv == NULL)
return;
thread = cpu_local_var(current);
if(thread == NULL || thread->proc->pid == 0){
struct thread *t;
irqstate = cpu_disable_interrupt_save();
ihk_mc_spinlock_lock_noirq(&(cpu_local_var(runq_lock)));
list_for_each_entry(t, &(cpu_local_var(runq)), sched_list){
if(t->proc->pid <= 0)
continue;
if(t->status == PS_INTERRUPTIBLE &&
hassigpending(t)){
t->status = PS_RUNNING;
break;
}
}
ihk_mc_spinlock_unlock_noirq(&(cpu_local_var(runq_lock)));
cpu_restore_interrupt(irqstate);
goto out;
}
if(regs != NULL && !interrupt_from_user(regs)) {
goto out;
}
if (list_empty(&thread->sigpending) &&
list_empty(&thread->sigcommon->sigpending)) {
goto out;
}
for(;;){
/* When this function called from check_signal_irq_disabled,
* return with interrupt invalid.
* This is to eliminate signal loss.
*/
if (irq_disabled == 1) {
irqstate = cpu_disable_interrupt_save();
}
pending = getsigpending(thread, 1);
if(!pending) {
dkprintf("check_signal,queue is empty\n");
goto out;
}
if (irq_disabled == 1) {
cpu_restore_interrupt(irqstate);
}
if (do_signal(rc, regs, thread, pending, num)) {
num = -1;
}
}
out:
return;
}
static int
check_sig_pending_thread(struct thread *thread)
{
int found = 0;
struct list_head *head;
mcs_rwlock_lock_t *lock;
struct mcs_rwlock_node_irqsave mcs_rw_node;
struct sig_pending *next;
struct sig_pending *pending;
__sigset_t w;
__sigset_t x;
int sig = 0;
struct k_sigaction *k;
struct cpu_local_var *v;
v = get_this_cpu_local_var();
w = thread->sigmask.__val[0];
lock = &thread->sigcommon->lock;
head = &thread->sigcommon->sigpending;
for (;;) {
mcs_rwlock_reader_lock(lock, &mcs_rw_node);
list_for_each_entry_safe(pending, next, head, list) {
for (x = pending->sigmask.__val[0], sig = 0; x;
sig++, x >>= 1)
;
k = thread->sigcommon->action + sig - 1;
if ((sig != SIGCHLD &&
sig != SIGURG &&
sig != SIGCONT) ||
(k->sa.sa_handler != SIG_IGN &&
k->sa.sa_handler != NULL)) {
if (!(pending->sigmask.__val[0] & w)) {
if (pending->interrupted == 0) {
pending->interrupted = 1;
found = 1;
if (sig != SIGCHLD &&
sig != SIGURG &&
sig != SIGCONT &&
!k->sa.sa_handler) {
found = 2;
break;
}
}
}
}
}
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
if (found == 2) {
break;
}
if (lock == &thread->sigpendinglock) {
break;
}
lock = &thread->sigpendinglock;
head = &thread->sigpending;
}
if (found == 2) {
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
terminate_mcexec(0, sig);
return 1;
}
else if (found == 1) {
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
interrupt_syscall(thread, 0);
return 1;
}
return 0;
}
void
check_sig_pending(void)
{
struct thread *thread;
struct cpu_local_var *v;
if (clv == NULL)
return;
v = get_this_cpu_local_var();
repeat:
v->runq_irqstate = ihk_mc_spinlock_lock(&v->runq_lock);
list_for_each_entry(thread, &(v->runq), sched_list) {
if (thread == NULL || thread == &cpu_local_var(idle)) {
continue;
}
if (thread->in_syscall_offload == 0) {
continue;
}
if (thread->proc->group_exit_status & 0x0000000100000000L) {
continue;
}
if (check_sig_pending_thread(thread))
goto repeat;
}
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
}
unsigned long
do_kill(struct thread * thread, int pid, int tid, int sig, siginfo_t *info, int ptracecont)
{
@ -2043,7 +1789,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 +1883,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 +1898,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 +1922,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 +1992,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 +2022,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 +2035,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 +2065,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

@ -84,7 +84,11 @@ enum __rlimit_resource
__RLIMIT_RTPRIO = 14,
#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
__RLIMIT_NLIMITS = 15,
/* timeout for RT tasks in us */
__RLIMIT_RTTIME = 15,
#define RLIMIT_RTTIME __RLIMIT_RTTIME
__RLIMIT_NLIMITS = 16,
__RLIM_NLIMITS = __RLIMIT_NLIMITS
#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
#define RLIM_NLIMITS __RLIM_NLIMITS

View File

@ -158,6 +158,7 @@ SYSCALL_HANDLED(289, signalfd4)
#ifdef ENABLE_PERF
SYSCALL_HANDLED(298, perf_event_open)
#endif
SYSCALL_HANDLED(302, prlimit64)
#ifdef DCFA_KMOD
SYSCALL_HANDLED(303, mod_call)
#endif
@ -180,4 +181,8 @@ SYSCALL_HANDLED(802, linux_mlock)
SYSCALL_HANDLED(803, suspend_threads)
SYSCALL_HANDLED(804, resume_threads)
SYSCALL_HANDLED(811, linux_spawn)
/**** End of File ****/
/* Do not edit the lines including this comment and
* EOF just after it because those are used as a
* robust marker for the autotest patch.
*/

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>
@ -148,44 +147,6 @@ int obtain_clone_cpuid(cpu_set_t *cpu_set, int use_last) {
return min_cpu;
}
int
arch_clear_host_user_space()
{
struct thread *th = cpu_local_var(current);
/* XXX: might be unnecessary */
clear_host_pte(th->vm->region.user_start,
(th->vm->region.user_end - th->vm->region.user_start), 0);
return 0;
}
SYSCALL_DECLARE(rt_sigaction)
{
int sig = ihk_mc_syscall_arg0(ctx);
const struct sigaction *act = (const struct sigaction *)ihk_mc_syscall_arg1(ctx);
struct sigaction *oact = (struct sigaction *)ihk_mc_syscall_arg2(ctx);
size_t sigsetsize = ihk_mc_syscall_arg3(ctx);
struct k_sigaction new_sa, old_sa;
int rc;
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
if(act)
if(copy_from_user(&new_sa.sa, act, sizeof new_sa.sa)){
goto fault;
}
rc = do_sigaction(sig, act? &new_sa: NULL, oact? &old_sa: NULL);
if(rc == 0 && oact)
if(copy_to_user(oact, &old_sa.sa, sizeof old_sa.sa)){
goto fault;
}
return rc;
fault:
return -EFAULT;
}
SYSCALL_DECLARE(prctl)
{
struct process *proc = cpu_local_var(current)->proc;
@ -1040,82 +1001,6 @@ out:
return restart;
}
static struct sig_pending *
getsigpending(struct thread *thread, int delflag){
struct list_head *head;
mcs_rwlock_lock_t *lock;
struct mcs_rwlock_node_irqsave mcs_rw_node;
struct sig_pending *next;
struct sig_pending *pending;
__sigset_t w;
__sigset_t x;
int sig;
struct k_sigaction *k;
w = thread->sigmask.__val[0];
lock = &thread->sigcommon->lock;
head = &thread->sigcommon->sigpending;
for(;;) {
if (delflag) {
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
}
else {
mcs_rwlock_reader_lock(lock, &mcs_rw_node);
}
list_for_each_entry_safe(pending, next, head, list){
for(x = pending->sigmask.__val[0], sig = 0; x; sig++, x >>= 1);
k = thread->sigcommon->action + sig - 1;
if(delflag ||
(sig != SIGCHLD &&
sig != SIGURG &&
sig != SIGCONT) ||
(k->sa.sa_handler != (void *)1 &&
k->sa.sa_handler != NULL)){
if(!(pending->sigmask.__val[0] & w)){
if(delflag)
list_del(&pending->list);
if (delflag) {
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
}
else {
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
}
return pending;
}
}
}
if (delflag) {
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
}
else {
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
}
if(lock == &thread->sigpendinglock)
return NULL;
lock = &thread->sigpendinglock;
head = &thread->sigpending;
}
return NULL;
}
struct sig_pending *
hassigpending(struct thread *thread)
{
if (list_empty(&thread->sigpending) &&
list_empty(&thread->sigcommon->sigpending)) {
return NULL;
}
return getsigpending(thread, 0);
}
int
interrupt_from_user(void *regs0)
{
@ -1130,175 +1015,6 @@ void save_syscall_return_value(int num, unsigned long rc)
return;
}
/** \brief check arrived signals and processing
*
* @param rc return value of syscall
* @param regs0 context
* @param num syscall number (-1: Not called on exiting system call)
*/
void
check_signal(unsigned long rc, void *regs0, int num)
{
struct x86_user_context *regs = regs0;
struct thread *thread;
struct sig_pending *pending;
int irqstate;
if(clv == NULL)
return;
thread = cpu_local_var(current);
if(thread == NULL || thread == &cpu_local_var(idle)){
struct thread *t;
irqstate = cpu_disable_interrupt_save();
ihk_mc_spinlock_lock_noirq(&(cpu_local_var(runq_lock)));
list_for_each_entry(t, &(cpu_local_var(runq)), sched_list){
if(t == &cpu_local_var(idle))
continue;
if(t->status == PS_INTERRUPTIBLE &&
hassigpending(t)){
t->status = PS_RUNNING;
break;
}
}
ihk_mc_spinlock_unlock_noirq(&(cpu_local_var(runq_lock)));
cpu_restore_interrupt(irqstate);
goto out;
}
if(regs != NULL && !interrupt_from_user(regs)) {
goto out;
}
if (list_empty(&thread->sigpending) &&
list_empty(&thread->sigcommon->sigpending)) {
goto out;
}
for(;;){
pending = getsigpending(thread, 1);
if(!pending) {
dkprintf("check_signal,queue is empty\n");
goto out;
}
if (do_signal(rc, regs, thread, pending, num)) {
num = -1;
}
}
out:
return;
}
static int
check_sig_pending_thread(struct thread *thread)
{
int found = 0;
struct list_head *head;
mcs_rwlock_lock_t *lock;
struct mcs_rwlock_node_irqsave mcs_rw_node;
struct sig_pending *next;
struct sig_pending *pending;
__sigset_t w;
__sigset_t x;
int sig = 0;
struct k_sigaction *k;
struct cpu_local_var *v;
v = get_this_cpu_local_var();
w = thread->sigmask.__val[0];
lock = &thread->sigcommon->lock;
head = &thread->sigcommon->sigpending;
for (;;) {
mcs_rwlock_reader_lock(lock, &mcs_rw_node);
list_for_each_entry_safe(pending, next, head, list){
for (x = pending->sigmask.__val[0], sig = 0; x;
sig++, x >>= 1);
k = thread->sigcommon->action + sig - 1;
if ((sig != SIGCHLD &&
sig != SIGURG &&
sig != SIGCONT) ||
(k->sa.sa_handler != (void *)1 &&
k->sa.sa_handler != NULL)) {
if (!(pending->sigmask.__val[0] & w)) {
if (pending->interrupted == 0) {
pending->interrupted = 1;
found = 1;
if (sig != SIGCHLD &&
sig != SIGURG &&
sig != SIGCONT &&
!k->sa.sa_handler) {
found = 2;
break;
}
}
}
}
}
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
if (found == 2) {
break;
}
if (lock == &thread->sigpendinglock) {
break;
}
lock = &thread->sigpendinglock;
head = &thread->sigpending;
}
if (found == 2) {
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
terminate_mcexec(0, sig);
return 1;
}
else if (found == 1) {
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
interrupt_syscall(thread, 0);
return 1;
}
return 0;
}
void
check_sig_pending(void)
{
struct thread *thread;
struct cpu_local_var *v;
if (clv == NULL)
return;
v = get_this_cpu_local_var();
repeat:
v->runq_irqstate = ihk_mc_spinlock_lock(&v->runq_lock);
list_for_each_entry(thread, &(v->runq), sched_list) {
if (thread == NULL || thread == &cpu_local_var(idle)) {
continue;
}
if (thread->in_syscall_offload == 0) {
continue;
}
if (thread->proc->group_exit_status & 0x0000000100000000L) {
continue;
}
if (check_sig_pending_thread(thread))
goto repeat;
}
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
}
unsigned long
do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
int ptracecont)
@ -1786,7 +1502,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 +1831,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 +1863,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 +2005,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 +2027,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 +2096,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 +2126,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 +2139,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 +2169,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

@ -91,8 +91,9 @@ struct program_image_section {
struct get_cpu_set_arg {
int nr_processes;
char *req_cpu_list; // Requested by user-space
int req_cpu_list_len; // Lenght of request string
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;
@ -615,54 +614,96 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
}
if (copy_from_user(&req, (void *)arg, sizeof(req))) {
pr_err("%s: error copying user request\n", __func__);
printk("%s: error copying user request\n", __FUNCTION__);
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;
}
}
/* User requested CPU mask? */
if (req.req_cpu_list && req.req_cpu_list_len) {
char *cpu_list = NULL;
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);
cpu_list = kmalloc(req.req_cpu_list_len, GFP_KERNEL);
if (!cpu_list) {
printk("%s: error: allocating CPU list\n", __FUNCTION__);
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);
if (copy_from_user(cpu_list,
req.req_cpu_list, req.req_cpu_list_len)) {
printk("%s: error copying CPU list request\n", __FUNCTION__);
kfree(cpu_list);
ret = -EINVAL;
goto put_out;
}
cpus_used = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
cpus_to_use = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
if (!cpus_to_use || !cpus_used) {
printk("%s: error: allocating CPU mask\n", __FUNCTION__);
ret = -ENOMEM;
kfree(cpu_list);
goto put_out;
}
memset(cpus_used, 0, sizeof(cpumask_t));
memset(cpus_to_use, 0, sizeof(cpumask_t));
/* Parse CPU list */
if (cpulist_parse(cpu_list, cpus_to_use) < 0) {
printk("%s: invalid CPUs requested: %s\n",
__FUNCTION__, cpu_list);
ret = -EINVAL;
kfree(cpu_list);
goto put_out;
}
memcpy(cpus_used, cpus_to_use, sizeof(cpumask_t));
/* Copy mask to user-space */
if (copy_to_user(req.cpu_set, cpus_used,
(req.cpu_set_size < sizeof(cpumask_t) ?
req.cpu_set_size : sizeof(cpumask_t)))) {
printk("%s: error copying mask to user\n", __FUNCTION__);
ret = -EINVAL;
kfree(cpu_list);
goto put_out;
}
/* Copy IKC target core */
cpu = cpumask_next(-1, cpus_used);
if (copy_to_user(req.target_core, &cpu, sizeof(cpu))) {
printk("%s: error copying target core to user\n",
__FUNCTION__);
ret = -EINVAL;
kfree(cpu_list);
goto put_out;
}
/* Save in per-process structure */
memcpy(&ppd->cpu_set, cpus_used, sizeof(cpumask_t));
ppd->ikc_target_cpu = cpu;
printk("%s: %s -> target McKernel CPU: %d\n",
__func__, cpu_list, cpu);
ret = 0;
kfree(cpu_list);
goto put_out;
}
mutex_unlock(&udp->part_exec_lock);
pe = &udp->part_exec;
mutex_lock(&pe->lock);
/* 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 +712,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 +798,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 +1047,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);
@ -1237,7 +1280,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 +1495,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 +1505,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 +3442,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 +3505,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 +3529,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,
@ -537,7 +539,11 @@ retry_alloc:
#define USE_VM_INSERT_PFN 1
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#if defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8, 2)
static vm_fault_t rus_vm_fault(struct vm_fault *vmf)
#else
static int rus_vm_fault(struct vm_fault *vmf)
#endif
{
struct vm_area_struct *vma = vmf->vma;
#else
@ -970,6 +976,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 +1059,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 +1067,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 +1439,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 +1472,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 +1626,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

@ -1322,7 +1322,8 @@ void init_sigaction(void)
master_tid = gettid();
for (i = 1; i <= 64; i++) {
if (i != SIGKILL && i != SIGSTOP && i != SIGCHLD) {
if (i != SIGKILL && i != SIGSTOP && i != SIGCHLD &&
i != SIGTSTP && i != SIGTTIN && i != SIGTTOU) {
struct sigaction act;
sigaction(i, NULL, &act);
@ -2211,6 +2212,64 @@ int main(int argc, char **argv)
pthread_spin_init(&overlay_fd_lock, 0);
/* XXX: Fugaku: Fujitsu process placement fix */
if (getenv("FLIB_AFFINITY_ON_PROCESS")) {
char *cpu_s;
int flib_size;
char *flib_aff_orig, *flib_aff;
int cpu, off = 0;
flib_aff_orig = strdup(getenv("FLIB_AFFINITY_ON_PROCESS"));
if (!flib_aff_orig) {
fprintf(stderr, "error: dupping FLIB_AFFINITY_ON_PROCESS\n");
exit(EXIT_FAILURE);
}
flib_size = strlen(flib_aff_orig) * 2;
flib_aff = malloc(flib_size);
if (!flib_aff) {
fprintf(stderr, "error: allocating memory for "
"FLIB_AFFINITY_ON_PROCESS\n");
exit(EXIT_FAILURE);
}
memset(flib_aff, 0, flib_size);
cpu_s = strtok(flib_aff_orig, ",");
while (cpu_s) {
int ret;
/* "Shift" left by 12 CPUs */
cpu = atoi(cpu_s) - 12;
/* Prepend "," */
if (off > 0) {
ret = snprintf(flib_aff + off, flib_size - off, "%s", ",");
if (ret < 0) {
fprintf(stderr, "error: constructing "
"FLIB_AFFINITY_ON_PROCESS\n");
exit(EXIT_FAILURE);
}
off += ret;
}
ret = snprintf(flib_aff + off, flib_size - off, "%d", cpu);
if (ret < 0) {
fprintf(stderr, "error: constructing "
"FLIB_AFFINITY_ON_PROCESS\n");
exit(EXIT_FAILURE);
}
off += ret;
cpu_s = strtok(NULL, ",");
}
__dprintf("FLIB_AFFINITY_ON_PROCESS: %s -> %s\n",
getenv("FLIB_AFFINITY_ON_PROCESS"), flib_aff);
setenv("FLIB_AFFINITY_ON_PROCESS", flib_aff, 1);
}
ld_preload_init();
#ifdef ADD_ENVS_OPTION
@ -2483,10 +2542,11 @@ int main(int argc, char **argv)
CPU_ZERO(&mcexec_cpu_set);
cpu_set_arg.req_cpu_list = NULL;
cpu_set_arg.req_cpu_list_len = 0;
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;
@ -2494,6 +2554,16 @@ int main(int argc, char **argv)
cpu_set_arg.mcexec_cpu_set_size = sizeof(mcexec_cpu_set);
cpu_set_arg.ikc_mapped = &ikc_mapped;
/* Fugaku specific: Fujitsu CPU binding */
if (getenv("FLIB_AFFINITY_ON_PROCESS")) {
cpu_set_arg.req_cpu_list =
getenv("FLIB_AFFINITY_ON_PROCESS");
cpu_set_arg.req_cpu_list_len =
strlen(cpu_set_arg.req_cpu_list) + 1;
__dprintf("%s: requesting CPUs: %s\n",
__func__, cpu_set_arg.req_cpu_list);
}
if (ioctl(fd, MCEXEC_UP_GET_CPUSET, (void *)&cpu_set_arg) != 0) {
perror("getting CPU set for partitioned execution");
close(fd);
@ -2502,6 +2572,12 @@ int main(int argc, char **argv)
desc->cpu = target_core;
desc->process_rank = process_rank;
/* Fugaku specific: Fujitsu node-local rank */
if (getenv("PLE_RANK_ON_NODE")) {
desc->process_rank = atoi(getenv("PLE_RANK_ON_NODE"));
__dprintf("%s: rank: %d, target CPU: %d\n",
__func__, desc->process_rank, desc->cpu);
}
/* Bind to CPU cores where the LWK process' IKC target maps to */
if (ikc_mapped && !no_bind_ikc_map) {

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

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

@ -139,7 +139,6 @@ static void hugefileobj_free(struct memobj *memobj)
struct memobj_ops hugefileobj_ops = {
.free = hugefileobj_free,
.get_page = hugefileobj_get_page,
};
void hugefileobj_cleanup(void)

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

@ -72,4 +72,11 @@
#define MS_INVALIDATE 0x02
#define MS_SYNC 0x04
/* include/uapi/linux/mman.h */
#define OVERCOMMIT_GUESS 0
#define OVERCOMMIT_ALWAYS 1
#define OVERCOMMIT_NEVER 2
extern int sysctl_overcommit_memory;
#endif /* HEADER_MMAN_H */

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)
@ -506,10 +505,12 @@ struct process {
// PS_STOPPED -----+
// (PS_TRACED)
/* Store exit_status for a group of threads when stopped by SIGSTOP.
exit_status can't be used because values of exit_status of threads
might divert while the threads are exiting by group_exit(). */
int group_exit_status;
/* Store exit_status for a group of threads when stopped by SIGSTOP. */
/* exit_status can't be used because values of exit_status of threads */
/* might divert while the threads are exiting by group_exit(). */
/* The upper 4 bytes of group_exit_status is the confirmation flag of */
/* exit status. The lower 4 bytes is the exit status. */
unsigned long group_exit_status;
/* Manage ptraced processes in the separate list to make it easy to
restore the orginal parent child relationship when
@ -609,6 +610,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 +720,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 +752,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 +808,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

@ -11,6 +11,7 @@
#include <ihk/ihk_monitor.h>
#include <ihk/debug.h>
#include <memory.h>
#include <mman.h>
#ifdef ENABLE_RUSAGE
@ -27,30 +28,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;
}
@ -324,6 +312,9 @@ rusage_check_overmap(size_t len, int pgshift)
{
int npages = 0, remain_pages = 0;
if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)
return 0;
npages = (len + (1UL << pgshift) - 1) >> pgshift;
remain_pages = (rusage.total_memory - rusage.total_memory_usage)
>> pgshift;

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;
};
@ -508,7 +508,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);
@ -651,4 +651,6 @@ extern int (*linux_clock_gettime)(clockid_t clk_id, struct timespec *tp);
#define COREDUMP_TO_BE_WOKEN 2
extern void terminate_host(int pid, struct thread *thread);
struct sig_pending *getsigpending(struct thread *thread, int delflag);
int interrupt_from_user(void *regs0);
#endif

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

@ -62,6 +62,7 @@ extern int interrupt_from_user(void *);
struct tlb_flush_entry tlb_flush_vector[IHK_TLB_FLUSH_IRQ_VECTOR_SIZE];
int anon_on_demand = 0;
int sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;
static struct ihk_mc_pa_ops *pa_ops;
@ -1276,8 +1277,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 +1602,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 +2563,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 +2633,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);
@ -2181,16 +2176,65 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
{
int error;
const uintptr_t fault_addr = (uintptr_t)fault_addr0;
struct vm_range *range;
struct vm_range *range = NULL;
struct thread *thread = cpu_local_var(current);
int locked = 0;
dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx)\n",
ihk_mc_get_processor_id(), vm, fault_addr0, reason);
/* grow stack */
if (fault_addr >= thread->vm->region.stack_start &&
fault_addr < thread->vm->region.stack_end) {
range = lookup_process_memory_range(vm,
thread->vm->region.stack_end - 1,
thread->vm->region.stack_end);
if (range == NULL) {
error = -EFAULT;
ekprintf("%s: vm: %p, addr: %p, reason: %lx):"
"stack not found: %d\n",
__func__, vm, fault_addr0, reason, error);
goto out;
}
/* don't grow if replaced with hugetlbfs */
if (range->memobj) {
goto skip;
}
if (fault_addr >= range->start) {
goto skip;
}
if (thread->vm->is_memory_range_lock_taken == -1 ||
thread->vm->is_memory_range_lock_taken !=
ihk_mc_get_processor_id()) {
ihk_rwspinlock_write_lock_noirq(&vm->memory_range_lock);
locked = 1;
}
if (range->pgshift) {
range->start = fault_addr &
~((1UL << range->pgshift) - 1);
} else {
range->start = fault_addr & PAGE_MASK;
}
if (locked) {
ihk_rwspinlock_write_unlock_noirq(&vm->memory_range_lock);
locked = 0;
}
dkprintf("%s: addr: %lx, reason: %lx, range: %lx-%lx:"
"stack found\n",
__func__, (unsigned long)fault_addr, reason,
range->start, range->end);
}
skip:
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",
@ -2202,13 +2246,16 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
goto out;
}
range = lookup_process_memory_range(vm, fault_addr, fault_addr+1);
if (range == NULL) {
error = -EFAULT;
dkprintf("do_page_fault_process_vm(): vm: %p, addr: %p, reason: %lx):"
"out of range: %d\n",
vm, fault_addr0, reason, error);
goto out;
if (!range) {
range = lookup_process_memory_range(vm, fault_addr,
fault_addr+1);
if (range == NULL) {
error = -EFAULT;
dkprintf("%s: vm: %p, addr: %p, reason: %lx):"
"out of range: %d\n",
__func__, vm, fault_addr0, reason, error);
goto out;
}
}
if (((range->flag & VR_PROT_MASK) == VR_PROT_NONE)
@ -2305,7 +2352,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 +2371,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;
@ -2370,16 +2419,15 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
size = minsz;
}
size = (size + USER_STACK_PREPAGE_SIZE - 1) & USER_STACK_PAGE_MASK;
dkprintf("%s: stack_premap: %lu, rlim_cur: %lu, minsz: %lu, size: %lu\n",
__FUNCTION__,
pn->stack_premap,
proc->rlimit[MCK_RLIMIT_STACK].rlim_cur,
minsz, size);
start = (end - size) & USER_STACK_PAGE_MASK;
dkprintf("%s: stack_premap: %lu, rlim_cur: %lu, minsz: %lu, size: %lu, maxsz: %lx\n",
__func__, pn->stack_premap,
proc->rlimit[MCK_RLIMIT_STACK].rlim_cur,
minsz, size, maxsz);
start = (end - minsz) & USER_STACK_PAGE_MASK;
/* Apply user allocation policy to stacks */
/* TODO: make threshold kernel or mcexec argument */
ap_flag = (size >= proc->mpol_threshold &&
ap_flag = (minsz >= proc->mpol_threshold &&
!(proc->mpol_flags & MPOL_NO_STACK)) ? IHK_MC_AP_USER : 0;
dkprintf("%s: max size: %lu, mapped size: %lu %s\n",
__FUNCTION__, size, minsz,
@ -2404,8 +2452,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;
@ -2512,7 +2559,7 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
ihk_mc_modify_user_context(thread->uctx, IHK_UCR_STACK_POINTER,
end + sizeof(unsigned long) * s_ind);
thread->vm->region.stack_end = end;
thread->vm->region.stack_start = start;
thread->vm->region.stack_start = (end - size) & USER_STACK_PAGE_MASK;
return 0;
}
@ -2569,7 +2616,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 +2656,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 +2674,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 +2689,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 +2702,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 +2792,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 +2805,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 +2861,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 +2875,7 @@ int populate_process_memory(struct process_vm *vm, void *start, size_t len)
error = 0;
out:
preempt_enable();
return error;
}
@ -3189,7 +3238,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 +3348,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 +3378,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 +3388,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 +3568,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 +3732,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);

File diff suppressed because it is too large Load Diff

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@
@ -23,6 +23,8 @@ Summary: IHK/McKernel
License: GPLv2
Source0: mckernel-%{version}.tar.gz
Requires: systemd-libs numactl-libs libdwarf
# kernel_module_package macro does not handle cross build...
%if "%{?_host_cpu}" == "x86_64" && "%{?_target_cpu}" == "aarch64"
%define cross_compile 1
@ -34,7 +36,7 @@ Requires: kernel = %{krequires}
Requires(post): /usr/sbin/depmod
Requires(postun): /usr/sbin/depmod
%else
BuildRequires: systemd-devel numactl-devel binutils-devel kernel-devel
BuildRequires: systemd-devel numactl-devel binutils-devel kernel-devel libdwarf-devel
# Friendly reminder of the fact that kernel-rpm-macros is no longer included in kernel-devel
%if 0%{?rhel} >= 8
BuildRequires: redhat-rpm-config kernel-rpm-macros elfutils-libelf-devel kmod
@ -96,6 +98,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

56
test/issues/1377/C1377.sh Normal file
View File

@ -0,0 +1,56 @@
#!/bin/sh
USELTP=1
USEOSTEST=0
. ../../common.sh
################################################################################
if [ ! -f "$LTPBIN/dirtyc0w" ]; then
echo BAD environment: LTP is too old >&2
exit 1
fi
echo "*** C1377T01 start"
ng=0
ok=0
tp=dirtyc0w
for ((i=0; i<20; i++)); do
for ((j=0; j<50; j++)); do
sudo PATH=$PATH:$LTPBIN $MCEXEC $LTPBIN/$tp > $tp.txt 2>&1
wok=`grep PASS $tp.txt | wc -l`
wng=`grep FAIL $tp.txt | wc -l`
if [ $wng != 0 ]; then
echo -n '*'
ng=`expr $ng + 1`
elif [ $wok == 0 ]; then
echo -n '?'
else
echo -n '.'
ok=`expr $ok + 1`
fi
done
echo
done
if [ $ng != 0 ]; then
echo "*** C1377T01 FAILED ok: $ok, ng: $ng"
else
echo "*** C1377T01 PASS ok: $ok"
fi
for i in wait02:02 wait401:03 waitpid01:04 waitpid02:05 waitpid04:06 \
waitpid05:07 waitpid06:08 waitpid07:09 waitpid08:10 waitpid09:11 \
waitpid10:12 waitpid11:13 waitpid12:14 waitpid13:15; do
tp=`echo $i|sed 's/:.*//'`
id=`echo $i|sed 's/.*://'`
sudo PATH=$PATH:$LTPBIN $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
ok=`grep PASS $tp.txt | wc -l`
ng=`grep FAIL $tp.txt | wc -l`
if [ $ng = 0 ]; then
echo "*** C1377T$id: $tp PASS ($ok)"
else
echo "*** C1377T$id: $tp FAIL (ok=$ok ng=$ng)"
fi
done

View File

@ -0,0 +1,179 @@
Script started on Tue 16 Jun 2020 02:42:48 PM JST
[shirasawa@apollo04 1377]$ make test
sh ./C1377.sh
mcstop+release.sh ... done
mcreboot.sh -c 2-31 -m 2G@0,2G@1 -O ... done
*** C1377T01 start
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
*** C1377T01 PASS ok: 1000
wait02 1 TPASS : wait(&status) returned 78343
*** C1377T02: wait02 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
wait401.c:55: PASS: waitpid() returned correct pid 78457
wait401.c:64: PASS: WIFEXITED() is set in status
wait401.c:69: PASS: WEXITSTATUS() == 0
Summary:
passed 3
failed 0
skipped 0
warnings 0
*** C1377T03: wait401 PASS (3)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid01.c:51: PASS: waitpid() returned correct pid 78571
waitpid01.c:60: PASS: WIFSIGNALED() set in status
waitpid01.c:68: PASS: WTERMSIG() == SIGALRM
Summary:
passed 3
failed 0
skipped 0
warnings 0
*** C1377T04: waitpid01 PASS (3)
waitpid02 1 TPASS : received expected pid
waitpid02 2 TPASS : received expected signal
waitpid02 3 TPASS : received expected exit value
*** C1377T05: waitpid02 PASS (3)
waitpid04 1 TPASS : condition 1 test passed
waitpid04 2 TPASS : condition 2 test passed
waitpid04 3 TPASS : condition 3 test passed
*** C1377T06: waitpid04 PASS (3)
waitpid05 1 TPASS : received expected pid.
waitpid05 2 TPASS : received expected exit number.
waitpid05 3 TPASS : received expected pid.
waitpid05 4 TPASS : received expected exit number.
waitpid05 5 TPASS : received expected pid.
waitpid05 6 TPASS : received expected exit number.
waitpid05 7 TPASS : received expected pid.
waitpid05 8 TPASS : received expected exit number.
waitpid05 9 TPASS : received expected pid.
waitpid05 10 TPASS : received expected exit number.
waitpid05 11 TPASS : received expected pid.
waitpid05 12 TPASS : received expected exit number.
waitpid05 13 TPASS : received expected pid.
waitpid05 14 TPASS : received expected exit number.
waitpid05 15 TPASS : received expected pid.
waitpid05 16 TPASS : received expected exit number.
waitpid05 17 TPASS : received expected pid.
waitpid05 18 TPASS : received expected exit number.
waitpid05 19 TPASS : received expected pid.
waitpid05 20 TPASS : received expected exit number.
waitpid05 21 TPASS : received expected pid.
waitpid05 22 TPASS : received expected exit number.
waitpid05 23 TPASS : received expected pid.
waitpid05 24 TPASS : received expected exit number.
*** C1377T07: waitpid05 PASS (24)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid06.c:54: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T08: waitpid06 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid07.c:59: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T09: waitpid07 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid_common.h:142: INFO: Sending SIGCONT to 80073
waitpid_common.h:142: INFO: Sending SIGCONT to 80105
waitpid_common.h:142: INFO: Sending SIGCONT to 80137
waitpid_common.h:142: INFO: Sending SIGCONT to 80169
waitpid_common.h:142: INFO: Sending SIGCONT to 80201
waitpid_common.h:142: INFO: Sending SIGCONT to 80233
waitpid_common.h:142: INFO: Sending SIGCONT to 80266
waitpid_common.h:142: INFO: Sending SIGCONT to 80298
waitpid08.c:62: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T10: waitpid08 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid09.c:83: PASS: waitpid(pid, WNOHANG) = 0 for a running child
waitpid09.c:123: PASS: waitpid(pid, WNOHANG) = pid for an exited child
waitpid09.c:143: PASS: waitpid(-1, 0) = -1 with ECHILD if no children
waitpid09.c:162: PASS: waitpid(-1, WNOHANG) = -1 with ECHILD if no children
Summary:
passed 4
failed 0
skipped 0
warnings 0
*** C1377T11: waitpid09 PASS (4)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid10.c:62: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T12: waitpid10 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid11.c:60: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T13: waitpid11 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid12.c:70: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T14: waitpid12 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid_common.h:142: INFO: Sending SIGCONT to 85038
waitpid_common.h:142: INFO: Sending SIGCONT to 85070
waitpid_common.h:142: INFO: Sending SIGCONT to 85102
waitpid_common.h:142: INFO: Sending SIGCONT to 85134
waitpid_common.h:142: INFO: Sending SIGCONT to 84910
waitpid_common.h:142: INFO: Sending SIGCONT to 84942
waitpid_common.h:142: INFO: Sending SIGCONT to 84974
waitpid_common.h:142: INFO: Sending SIGCONT to 85006
waitpid13.c:70: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T15: waitpid13 PASS (1)
[shirasawa@apollo04 1377]$ exit
exit
Script done on Tue 16 Jun 2020 03:02:48 PM JST

View File

@ -0,0 +1,179 @@
Script started on Tue Jun 16 15:36:06 2020
bash-4.2$ make test
sh ./C1377.sh
mcstop+release.sh ... done
mcreboot.sh -c 1-7,9-15,17-23,25-31 -m 10G@0,10G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24 ... done
*** C1377T01 start
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
*** C1377T01 PASS ok: 1000
wait02 1 TPASS : wait(&status) returned 32240
*** C1377T02: wait02 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
wait401.c:55: PASS: waitpid() returned correct pid 32347
wait401.c:64: PASS: WIFEXITED() is set in status
wait401.c:69: PASS: WEXITSTATUS() == 0
Summary:
passed 3
failed 0
skipped 0
warnings 0
*** C1377T03: wait401 PASS (3)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid01.c:51: PASS: waitpid() returned correct pid 32454
waitpid01.c:60: PASS: WIFSIGNALED() set in status
waitpid01.c:68: PASS: WTERMSIG() == SIGALRM
Summary:
passed 3
failed 0
skipped 0
warnings 0
*** C1377T04: waitpid01 PASS (3)
waitpid02 1 TPASS : received expected pid
waitpid02 2 TPASS : received expected signal
waitpid02 3 TPASS : received expected exit value
*** C1377T05: waitpid02 PASS (3)
waitpid04 1 TPASS : condition 1 test passed
waitpid04 2 TPASS : condition 2 test passed
waitpid04 3 TPASS : condition 3 test passed
*** C1377T06: waitpid04 PASS (3)
waitpid05 1 TPASS : received expected pid.
waitpid05 2 TPASS : received expected exit number.
waitpid05 3 TPASS : received expected pid.
waitpid05 4 TPASS : received expected exit number.
waitpid05 5 TPASS : received expected pid.
waitpid05 6 TPASS : received expected exit number.
waitpid05 7 TPASS : received expected pid.
waitpid05 8 TPASS : received expected exit number.
waitpid05 9 TPASS : received expected pid.
waitpid05 10 TPASS : received expected exit number.
waitpid05 11 TPASS : received expected pid.
waitpid05 12 TPASS : received expected exit number.
waitpid05 13 TPASS : received expected pid.
waitpid05 14 TPASS : received expected exit number.
waitpid05 15 TPASS : received expected pid.
waitpid05 16 TPASS : received expected exit number.
waitpid05 17 TPASS : received expected pid.
waitpid05 18 TPASS : received expected exit number.
waitpid05 19 TPASS : received expected pid.
waitpid05 20 TPASS : received expected exit number.
waitpid05 21 TPASS : received expected pid.
waitpid05 22 TPASS : received expected exit number.
waitpid05 23 TPASS : received expected pid.
waitpid05 24 TPASS : received expected exit number.
*** C1377T07: waitpid05 PASS (24)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid06.c:54: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T08: waitpid06 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid07.c:59: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T09: waitpid07 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid_common.h:142: INFO: Sending SIGCONT to 1524
waitpid_common.h:142: INFO: Sending SIGCONT to 1554
waitpid_common.h:142: INFO: Sending SIGCONT to 1584
waitpid_common.h:142: INFO: Sending SIGCONT to 1614
waitpid_common.h:142: INFO: Sending SIGCONT to 1644
waitpid_common.h:142: INFO: Sending SIGCONT to 1674
waitpid_common.h:142: INFO: Sending SIGCONT to 1704
waitpid_common.h:142: INFO: Sending SIGCONT to 1734
waitpid08.c:62: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T10: waitpid08 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid09.c:83: PASS: waitpid(pid, WNOHANG) = 0 for a running child
waitpid09.c:123: PASS: waitpid(pid, WNOHANG) = pid for an exited child
waitpid09.c:143: PASS: waitpid(-1, 0) = -1 with ECHILD if no children
waitpid09.c:162: PASS: waitpid(-1, WNOHANG) = -1 with ECHILD if no children
Summary:
passed 4
failed 0
skipped 0
warnings 0
*** C1377T11: waitpid09 PASS (4)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid10.c:62: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T12: waitpid10 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid11.c:60: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T13: waitpid11 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid12.c:70: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T14: waitpid12 PASS (1)
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
waitpid_common.h:142: INFO: Sending SIGCONT to 6219
waitpid_common.h:142: INFO: Sending SIGCONT to 6249
waitpid_common.h:142: INFO: Sending SIGCONT to 6279
waitpid_common.h:142: INFO: Sending SIGCONT to 6309
waitpid_common.h:142: INFO: Sending SIGCONT to 6099
waitpid_common.h:142: INFO: Sending SIGCONT to 6129
waitpid_common.h:142: INFO: Sending SIGCONT to 6159
waitpid_common.h:142: INFO: Sending SIGCONT to 6189
waitpid13.c:70: PASS: Test PASSED
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1377T15: waitpid13 PASS (1)
bash-4.2$ exit
exit
Script done on Tue Jun 16 15:55:52 2020

View File

@ -0,0 +1,9 @@
CC = gcc
all::
test:: all
sh ./C1377.sh
clean::
rm -f $(TARGET) *.o

38
test/issues/1377/README Normal file
View File

@ -0,0 +1,38 @@
【Issue#1377 動作確認】
□ テスト内容
1. Issue 指摘事項の再現確認
現象はタイミングに依存し、ARM64環境でdirtyc0wを繰り返し実行した際に、
数回〜数十回に1回程度発生する。
問題の発生はタイミングに依存するため、dirtyc0wを十分な回数繰り返し
実行し、問題が再発しないことを確認する。
C1377T01 dirtyc0wを1000回連続実行し、全てPASSすることを確認
2. LTP を用いて既存処理に影響しないことを確認
プロセスの終了ステータスを変更したため、修正が既存処理に影響しないことを
wait系システムコールのLTPを用いて確認する。
C1377T02 wait02: waitの基本機能の確認
C1377T03 wait401: wait4の基本機能の確認
C1377T04 waitpid01: waitpidの基本機能の確認
C1377T05 waitpid02: waitpidの基本機能の確認
C1377T06 waitpid04: waitpidの基本機能の確認
C1377T07 waitpid05: waitpidの基本機能の確認
C1377T08 waitpid06: waitpidの基本機能の確認
C1377T09 waitpid07: waitpidの基本機能の確認
C1377T10 waitpid08: waitpidの基本機能の確認
C1377T11 waitpid09: waitpidの基本機能の確認
C1377T12 waitpid10: waitpidの基本機能の確認
C1377T13 waitpid11: waitpidの基本機能の確認
C1377T14 waitpid12: waitpidの基本機能の確認
C1377T15 waitpid13: waitpidの基本機能の確認
□ 実行手順
$ make test
McKernelのインストール先や LTP の配置場所は、$HOME/.mck_test_config を
参照する。.mck_test_config は、McKernel をビルドした際に生成される
mck_test_config.sample ファイルを $HOME にコピーし、適宜編集すること。
□ 実行結果
C1377_x86_64.txt(x86_64実行結果)、C1377_arm64.txt(arm64実行結果)参照。
全ての項目が PASS していることを確認。

26
test/issues/1380/C1380.sh Executable file
View File

@ -0,0 +1,26 @@
#/bin/sh
USELTP=1
USEOSTEST=0
. ../../common.sh
issue="1380"
tid=01
for tp in tgkill03 tgkill01 tkill01 tkill02
do
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
ok=`grep PASS $tp.txt | wc -l`
ng=`grep FAIL $tp.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

@ -6,6 +6,6 @@ TARGET=
all: $(TARGET)
test: all
./C929.sh
./C1380.sh
clean:
rm -f $(TARGET) *.o *.txt

21
test/issues/1380/README Normal file
View File

@ -0,0 +1,21 @@
【Issue#1324 動作確認】
□ テスト内容
1. 以下のLTPを用いてIssueで報告された症状が発生しないことを確認
- tgkill03
3. 以下のLTPを用いて既存機能に影響が無いことを確認
- tgkill01
- tkill01
- tkill02
□ 実行手順
$ 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

@ -0,0 +1,37 @@
*** C1380T01 start *******************************
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
tgkill03.c:92: PASS: Invalid tgid failed as expected: EINVAL
tgkill03.c:92: PASS: Invalid tid failed as expected: EINVAL
tgkill03.c:92: PASS: Invalid signal failed as expected: EINVAL
tgkill03.c:92: PASS: Defunct tid failed as expected: ESRCH
tgkill03.c:92: PASS: Defunct tgid failed as expected: ESRCH
tgkill03.c:99: PASS: Valid tgkill call succeeded
Summary:
passed 6
failed 0
skipped 0
warnings 0
*** C1380T01 PASSED (6)
*** C1380T02 start *******************************
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
tgkill01.c:99: PASS: SIGUSR1 delivered to correct threads
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1380T02 PASSED (1)
*** C1380T03 start *******************************
tkill01 1 TPASS : tkill call succeeded
tkill01 2 TPASS : tkill call succeeded
*** C1380T03 PASSED (2)
*** C1380T04 start *******************************
tkill02 1 TPASS : tkill(-1, SIGUSR1) failed as expected: TEST_ERRNO=EINVAL(22): Invalid argument
tkill02 2 TPASS : tkill(29822, SIGUSR1) failed as expected: TEST_ERRNO=ESRCH(3): No such process
*** C1380T04 PASSED (2)

View File

@ -0,0 +1,37 @@
*** C1380T01 start *******************************
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
tgkill03.c:92: PASS: Invalid tgid failed as expected: EINVAL
tgkill03.c:92: PASS: Invalid tid failed as expected: EINVAL
tgkill03.c:92: PASS: Invalid signal failed as expected: EINVAL
tgkill03.c:92: PASS: Defunct tid failed as expected: ESRCH
tgkill03.c:92: PASS: Defunct tgid failed as expected: ESRCH
tgkill03.c:99: PASS: Valid tgkill call succeeded
Summary:
passed 6
failed 0
skipped 0
warnings 0
*** C1380T01 PASSED (6)
*** C1380T02 start *******************************
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
tgkill01.c:99: PASS: SIGUSR1 delivered to correct threads
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1380T02 PASSED (1)
*** C1380T03 start *******************************
tkill01 1 TPASS : tkill call succeeded
tkill01 2 TPASS : tkill call succeeded
*** C1380T03 PASSED (2)
*** C1380T04 start *******************************
tkill02 1 TPASS : tkill(-1, SIGUSR1) failed as expected: TEST_ERRNO=EINVAL(22): Invalid argument
tkill02 2 TPASS : tkill(32768, SIGUSR1) failed as expected: TEST_ERRNO=ESRCH(3): No such process
*** C1380T04 PASSED (2)

41
test/issues/1399/C1399.sh Executable file
View File

@ -0,0 +1,41 @@
#/bin/sh
USELTP=1
USEOSTEST=0
. ../../common.sh
issue="1399"
tid=01
for tno in 01
do
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
sudo ${MCEXEC} ./C1399T${tno}
if [ $? -eq 0 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
done
for tp in set_robust_list01 get_robust_list01
do
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
ok=`grep PASS $tp.txt | wc -l`
ng=`grep FAIL $tp.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

@ -0,0 +1,36 @@
#include <stdio.h>
#include <unistd.h>
#include <linux/futex.h>
#include <syscall.h>
#include <errno.h>
int main(int argc, void *argv[])
{
struct robust_list_head rlh;
size_t len = sizeof(struct robust_list_head);
int rc = 0, ret = 0;
errno = 0;
rc = syscall(__NR_set_robust_list, &rlh, len + 1);
if (rc == -1 && errno == EINVAL) {
printf("[OK] invalid len (1 greater than correct): EINVAL\n");
} else {
printf("[NG] invalid len (1 greater than correct): Succeed\n");
ret = -1;
goto out;
}
errno = 0;
rc = syscall(__NR_set_robust_list, &rlh, len - 1);
if (rc == -1 && errno == EINVAL) {
printf("[OK] invalid len (1 less than correct): EINVAL\n");
} else {
printf("[NG] invalid len (1 less than correct): Succeed\n");
ret = -1;
goto out;
}
out:
return ret;
}

11
test/issues/1399/Makefile Normal file
View File

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

24
test/issues/1399/README Normal file
View File

@ -0,0 +1,24 @@
【Issue#1399 動作確認】
□ テスト内容
1. 下記のテストプログラムを実行し、症状が発生しないことを確認する
C1399T01:
1. struct robust_list_head のサイズよりも1大きい値をサイズとして指定して
set_robsut_list を呼び出し、EINVALで失敗することを確認
2. struct robust_list_head のサイズよりも1小さい値をサイズとして指定して
set_robsut_list を呼び出し、EINVALで失敗することを確認
2. 以下のLTPを用いて既存のrobust_list機能に影響が無いことを確認
- set_robst_list01
- get_robst_list01
□ 実行手順
$ 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

@ -0,0 +1,18 @@
*** C1399T01 start *******************************
[OK] invalid len (1 greater than correct): EINVAL
[OK] invalid len (1 less than correct): EINVAL
*** C1399T01 PASSED ******************************
*** C1399T02 start *******************************
set_robust_list01 1 TPASS : set_robust_list: retval = -1 (expected -1), errno = 22 (expected 22)
set_robust_list01 2 TPASS : set_robust_list: retval = 0 (expected 0), errno = 0 (expected 0)
*** C1399T02 PASSED (2)
*** C1399T03 start *******************************
get_robust_list01 1 TPASS : get_robust_list failed as expected with EFAULT
get_robust_list01 2 TPASS : get_robust_list failed as expected with EFAULT
get_robust_list01 3 TPASS : get_robust_list failed as expected with ESRCH
get_robust_list01 4 TPASS : get_robust_list succeeded
get_robust_list01 5 TPASS : get_robust_list failed as expected with EPERM
*** C1399T03 PASSED (5)

View File

@ -0,0 +1,18 @@
*** C1399T01 start *******************************
[OK] invalid len (1 greater than correct): EINVAL
[OK] invalid len (1 less than correct): EINVAL
*** C1399T01 PASSED ******************************
*** C1399T02 start *******************************
set_robust_list01 1 TPASS : set_robust_list: retval = -1 (expected -1), errno = 22 (expected 22)
set_robust_list01 2 TPASS : set_robust_list: retval = 0 (expected 0), errno = 0 (expected 0)
*** C1399T02 PASSED (2)
*** C1399T03 start *******************************
get_robust_list01 1 TPASS : get_robust_list failed as expected with EFAULT
get_robust_list01 2 TPASS : get_robust_list failed as expected with EFAULT
get_robust_list01 3 TPASS : get_robust_list failed as expected with ESRCH
get_robust_list01 4 TPASS : get_robust_list succeeded
get_robust_list01 5 TPASS : get_robust_list failed as expected with EPERM
*** C1399T03 PASSED (5)

43
test/issues/1425/C1425.sh Executable file
View File

@ -0,0 +1,43 @@
#/bin/sh
USELTP=1
USEOSTEST=0
. ../../common.sh
issue="1425"
tid=01
STOPSIG_LIST="TSTP TTIN TTOU"
for signame in ${STOPSIG_LIST}
do
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
sh ./check_stopsig.sh ${MCEXEC} ${signame}
if [ $? -eq 0 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
done
for tp in kill01 kill02 kill06 kill07 kill08 kill09 signal01 signal03 signal04 signal05
do
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
ok=`grep PASS $tp.txt | wc -l`
ng=`grep FAIL $tp.txt | wc -l`
if [ $ng = 0 ]; then
echo "*** ${tname} PASSED ($ok)"
else
echo "*** ${tname} FAILED (ok=$ok ng=$ng)"
fi
let tid++
echo ""
done

11
test/issues/1425/Makefile Normal file
View File

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

Some files were not shown because too many files have changed in this diff Show More