Compare commits

...

12 Commits

Author SHA1 Message Date
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
37 changed files with 1544 additions and 619 deletions

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.4")
set(MCKERNEL_RELEASE "0.6")
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
# for rpmbuild

View File

@ -535,3 +535,6 @@ Restrictions on McKernel
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

@ -1279,7 +1279,7 @@ long ihk_mc_show_cpuinfo(char *buf, size_t buf_size, unsigned long read_off, int
/* generate strings */
loff += scnprintf(lbuf + loff, lbuf_size - loff,
"processor\t: %d\n", cpuinfo->hwid);
"processor\t: %d\n", i);
loff += scnprintf(lbuf + loff, lbuf_size - loff, "Features\t:");
for (j = 0; hwcap_str[j]; j++) {

View File

@ -83,6 +83,7 @@ SYSCALL_HANDLED(175, geteuid)
SYSCALL_HANDLED(176, getgid)
SYSCALL_HANDLED(177, getegid)
SYSCALL_HANDLED(178, gettid)
SYSCALL_HANDLED(179, sysinfo)
SYSCALL_DELEGATED(188, msgrcv)
SYSCALL_DELEGATED(189, msgsnd)
SYSCALL_DELEGATED(192, semtimedop)
@ -143,3 +144,8 @@ 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

@ -142,17 +142,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;
}
/* archtecture-depended syscall handlers */
extern unsigned long do_fork(int clone_flags, unsigned long newsp,
unsigned long parent_tidptr, unsigned long child_tidptr,
@ -185,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;
@ -1368,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)
{
@ -1455,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)
{

View File

@ -74,6 +74,7 @@ SYSCALL_DELEGATED(89, readlink)
SYSCALL_HANDLED(96, gettimeofday)
SYSCALL_HANDLED(97, getrlimit)
SYSCALL_HANDLED(98, getrusage)
SYSCALL_HANDLED(99, sysinfo)
SYSCALL_HANDLED(100, times)
SYSCALL_HANDLED(101, ptrace)
SYSCALL_HANDLED(102, getuid)
@ -179,4 +180,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

@ -147,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;
@ -1039,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)
{
@ -1129,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)

View File

@ -91,7 +91,10 @@ 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,13 +587,14 @@ 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;
struct mcctrl_part_exec *pe = NULL, *pe_itr;
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;
@ -613,24 +614,126 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
return -EINVAL;
}
pe = &udp->part_exec;
mutex_lock(&pe->lock);
if (copy_from_user(&req, (void *)arg, sizeof(req))) {
printk("%s: error copying user request\n", __FUNCTION__);
pr_err("%s: error copying user request\n", __func__);
ret = -EINVAL;
goto put_and_unlock_out;
goto put_out;
}
/* First process to enter CPU partitioning */
if (pe->nr_processes == -1) {
/* User requested CPU mask? */
if (req.req_cpu_list && req.req_cpu_list_len) {
char *cpu_list = NULL;
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;
}
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_lock(&udp->part_exec_lock);
/* Find part_exec having same node_proxy */
list_for_each_entry_reverse(pe_itr, &udp->part_exec_list, chain) {
pe_list_len++;
if (pe_itr->node_proxy_pid == req.ppid) {
pe = pe_itr;
break;
}
}
if (!pe) {
/* First process to enter CPU partitioning */
pr_debug("%s: pe_list_len:%d\n", __func__, pe_list_len);
if (pe_list_len >= PE_LIST_MAXLEN) {
/* delete head entry of pe_list */
pe_itr = list_first_entry(&udp->part_exec_list,
struct mcctrl_part_exec, chain);
list_del(&pe_itr->chain);
kfree(pe_itr);
}
pe = kzalloc(sizeof(struct mcctrl_part_exec), GFP_KERNEL);
if (!pe) {
mutex_unlock(&udp->part_exec_lock);
ret = -ENOMEM;
goto put_out;
}
/* Init part_exec */
mutex_init(&pe->lock);
INIT_LIST_HEAD(&pe->pli_list);
pe->nr_processes = req.nr_processes;
pe->nr_processes_left = req.nr_processes;
pe->nr_processes_joined = 0;
pe->node_proxy_pid = req.ppid;
list_add_tail(&pe->chain, &udp->part_exec_list);
dprintk("%s: nr_processes: %d (partitioned exec starts)\n",
__FUNCTION__,
pe->nr_processes);
__func__, pe->nr_processes);
}
mutex_unlock(&udp->part_exec_lock);
mutex_lock(&pe->lock);
if (pe->nr_processes != req.nr_processes) {
printk("%s: error: requested number of processes"
@ -640,7 +743,15 @@ 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,
@ -726,8 +837,6 @@ 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;
}
@ -975,16 +1084,8 @@ next_cpu:
/* Commit used cores to OS structure */
memcpy(&pe->cpus_used, cpus_used, sizeof(*cpus_used));
/* 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 {
/* If not last process, wake up next process in list */
if (pe->nr_processes_left != 0) {
++pe->process_rank;
pli_next = list_first_entry(&pe->pli_list,
struct process_list_item, list);
@ -997,11 +1098,14 @@ next_cpu:
ret = 0;
put_and_unlock_out:
mutex_unlock(&pe->lock);
put_out:
mcctrl_put_per_proc_data(ppd);
kfree(cpus_to_use);
kfree(cpus_used);
kfree(mcexec_cpu_set);
mcctrl_put_per_proc_data(ppd);
mutex_unlock(&pe->lock);
return ret;
}

View File

@ -513,6 +513,7 @@ 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]);
@ -521,10 +522,8 @@ 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);
@ -580,6 +579,18 @@ 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

@ -324,13 +324,20 @@ 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))
@ -353,6 +360,7 @@ 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];
@ -368,7 +376,7 @@ struct mcctrl_usrdata {
nodemask_t numa_online;
struct list_head cpu_topology_list;
struct list_head node_topology_list;
struct mcctrl_part_exec part_exec;
struct list_head part_exec_list;
int perf_event_num;
};

View File

@ -2211,6 +2211,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,9 +2541,12 @@ 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;
@ -2493,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);
@ -2501,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) {

2
ihk

Submodule ihk updated: 1a6150c5bb...7c4b8d6b40

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

@ -11,6 +11,7 @@
#include <ihk/ihk_monitor.h>
#include <ihk/debug.h>
#include <memory.h>
#include <mman.h>
#ifdef ENABLE_RUSAGE
@ -56,6 +57,24 @@ rusage_total_memory_add(unsigned long size)
#endif
}
static inline unsigned long
rusage_get_total_memory()
{
return rusage.total_memory;
}
static inline unsigned long
rusage_get_free_memory()
{
return rusage.total_memory - rusage.total_memory_usage;
}
static inline unsigned long
rusage_get_usage_memory()
{
return rusage.total_memory_usage;
}
static inline void
rusage_rss_add(unsigned long size)
{
@ -293,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;
@ -399,6 +421,24 @@ rusage_rss_add(unsigned long size)
{
}
static inline unsigned long
rusage_get_total_memory()
{
return 0;
}
static inline unsigned long
rusage_get_free_memory()
{
return 0;
}
static inline unsigned long
rusage_get_usage_memory()
{
return 0;
}
static inline void
rusage_rss_sub(unsigned long size)
{

View File

@ -443,6 +443,22 @@ struct rusage {
long ru_nivcsw;
};
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding for libc5 */
};
extern void terminate(int, int);
struct tod_data_s {
@ -635,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

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

View File

@ -120,7 +120,6 @@ extern int num_processors;
extern unsigned long ihk_mc_get_ns_per_tsc(void);
extern int ptrace_detach(int pid, int data);
extern void debug_log(unsigned long);
extern int arch_clear_host_user_space();
extern long arch_ptrace(long request, int pid, long addr, long data);
extern struct cpu_local_var *clv;
@ -242,11 +241,6 @@ long do_syscall(struct syscall_request *req, int cpu)
unsigned long flags;
DECLARE_WAITQ_ENTRY(scd_wq_entry, cpu_local_var(current));
if (req->number == __NR_epoll_wait ||
req->number == __NR_epoll_pwait ||
req->number == __NR_ppoll)
goto schedule;
cpu_pause();
/* Spin if not preemptable */
@ -275,7 +269,6 @@ long do_syscall(struct syscall_request *req, int cpu)
continue;
}
schedule:
flags = cpu_disable_interrupt_save();
/* Try to sleep until notified */
@ -2660,10 +2653,8 @@ static int do_execveat(ihk_mc_user_context_t *ctx, int dirfd,
}
/* Clear host user space PTEs */
if (arch_clear_host_user_space()) {
kprintf("execve(): ERROR: clearing PTEs in host process\n");
panic("");
}
clear_host_pte(vm->region.user_start,
(vm->region.user_end - vm->region.user_start), 0);
/* Request host to transfer ELF image */
request.number = __NR_execve;
@ -5140,6 +5131,37 @@ SYSCALL_DECLARE(rt_sigsuspend)
return do_sigsuspend(thread, &wset);
}
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(sigaltstack)
{
struct thread *thread = cpu_local_var(current);
@ -6686,6 +6708,27 @@ SYSCALL_DECLARE(getrusage)
return 0;
}
SYSCALL_DECLARE(sysinfo)
{
struct sysinfo *sysinfo = (struct sysinfo *)ihk_mc_syscall_arg0(ctx);
struct sysinfo __sysinfo;
int ret = 0;
memset(&__sysinfo, '\0', sizeof(struct sysinfo));
__sysinfo.totalram = rusage_get_total_memory();
__sysinfo.freeram = rusage_get_free_memory();
__sysinfo.mem_unit = 1; // always one unit for McKernel
if (copy_to_user(sysinfo, &__sysinfo, sizeof(struct sysinfo))) {
ret = -EFAULT;
goto out;
}
out:
return ret;
}
extern int ptrace_traceme(void);
extern void set_single_step(struct thread *thread);
@ -10320,11 +10363,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
}
#endif // PROFILE_ENABLE
/* Do not deschedule when returning from an event (e.g., MPI) */
if (!(num == __NR_epoll_wait ||
num == __NR_epoll_pwait ||
num == __NR_ppoll) &&
smp_load_acquire(&v->flags) & CPU_FLAG_NEED_RESCHED) {
if (smp_load_acquire(&v->flags) & CPU_FLAG_NEED_RESCHED) {
check_need_resched();
}
@ -10345,3 +10384,275 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
return l;
}
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;
}
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);
}
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);
}
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;
}
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);
}

43
test/issues/1389/C1389.sh Executable file
View File

@ -0,0 +1,43 @@
#/bin/sh
USELTP=1
USEOSTEST=0
BOOTPARAM="-c 1-7 -m 10G@0,10G@1 -O"
. ../../common.sh
issue="1389"
tid=01
for tsuf in "01" "02.sh"
do
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
${MCEXEC} ./C1389T${tsuf}
if [ $? -eq 0 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
done
for tp in "mtest01 -p80" "mtest01 -p80 -w" "mem01"
do
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
echo ${tp}
sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee ${tname}.txt
ok=`grep PASS ${tname}.txt | wc -l`
ng=`grep FAIL ${tname}.txt | wc -l`
if [ $ng = 0 ]; then
echo "*** ${tname} PASSED ($ok)"
else
echo "*** ${tname} FAILED (ok=$ok ng=$ng)"
fi
let tid++
echo ""
done

View File

@ -0,0 +1,65 @@
#include <stdio.h>
#include <stdlib.h>
#include <linux/kernel.h>
#include <sys/sysinfo.h>
#include <errno.h>
int main(void)
{
struct sysinfo *info;
int ret = 0, rc = 0;
unsigned long assigned_mem = (20UL << 30);
unsigned long _totalram, _freeram;
unsigned int _mem_unit;
info = malloc(sizeof(struct sysinfo));
rc = sysinfo(info);
if (rc) {
perror("sysinfo fail: ");
ret = -1;
goto out;
}
_totalram = info->totalram;
_freeram = info->freeram;
_mem_unit = info->mem_unit;
// Check totalram
if (0.95 * assigned_mem < _totalram &&
_totalram < assigned_mem) {
printf("[OK] totalram: %ld\n", _totalram);
}
else {
printf("[NG] unexpected totalram: %ld\n", _totalram);
printf(" expected range: %ld - %ld\n",
(unsigned long)(0.95 * assigned_mem),
assigned_mem);
ret = -1;
goto out;
}
// Check freeram
if (0.95 * _totalram < _freeram &&
_freeram < _totalram) {
printf("[OK] freeram: %ld\n", _freeram);
}
else {
printf("[NG] unexpected freeram: %ld\n", _freeram);
ret = -1;
goto out;
}
// Check mem_unit
if (_mem_unit == 1) {
printf("[OK] mem_unit: %ld\n", _mem_unit);
}
else {
printf("[NG] unexpected mem_unit: %ld\n", _mem_unit);
ret = -1;
goto out;
}
free(info);
out:
return ret;
}

88
test/issues/1389/C1389T02.sh Executable file
View File

@ -0,0 +1,88 @@
#!/bin/sh
ASSIGNED_MEM=`echo '1024 * 1024 * 1024 * 20' | bc`
cat /proc/meminfo > ./cur_meminfo.txt
# Check MemTotal
MemTotalTxt=`cat ./cur_meminfo.txt | grep MemTotal | awk '{print $(NF-1)}'`
MemTotal=`echo "1024 * ${MemTotalTxt}" | bc`
lower_limit=`echo "${ASSIGNED_MEM} * 0.95" | bc`
lower_limit=${lower_limit%.*}
upper_limit=${ASSIGNED_MEM}
tgt=${MemTotal}
if [ ${tgt} -ge ${lower_limit} -a ${tgt} -lt ${upper_limit} ]; then
echo "[OK] MemTotal: ${tgt}"
else
echo "[NG] unexpected MemTotal: ${tgt}"
exit 1
fi
# Check MemFree
MemFreeTxt=`cat ./cur_meminfo.txt | grep MemFree | awk '{print $(NF-1)}'`
MemFree=`echo "1024 * ${MemFreeTxt}" | bc`
lower_limit=`echo "${MemTotal} * 0.95" | bc`
lower_limit=${lower_limit%.*}
upper_limit=${MemTotal}
tgt=${MemFree}
if [ ${tgt} -ge ${lower_limit} -a ${tgt} -lt ${upper_limit} ]; then
echo "[OK] MemFree: ${tgt}"
else
echo "[NG] unexpected MemFree: ${tgt}"
exit 1
fi
# Check SwapTotal
SwapTotalTxt=`cat ./cur_meminfo.txt | grep SwapTotal | awk '{print $(NF-1)}'`
SwapTotal=`echo "1024 * ${SwapTotalTxt}" | bc`
tgt=${SwapTotal}
if [ ${tgt} -eq 0 ]; then
echo "[OK] SwapTotal: ${tgt}"
else
echo "[NG] unexpected SwapTotal: ${tgt}"
exit 1
fi
# Check SwapFree
SwapFreeTxt=`cat ./cur_meminfo.txt | grep SwapFree | awk '{print $(NF-1)}'`
SwapFree=`echo "1024 * ${SwapFreeTxt}" | bc`
tgt=${SwapFree}
if [ ${tgt} -eq 0 ]; then
echo "[OK] SwapFree: ${tgt}"
else
echo "[NG] unexpected SwapFree: ${tgt}"
exit 1
fi
# Check CommitLimit
CommitLimitTxt=`cat ./cur_meminfo.txt | grep CommitLimit | awk '{print $(NF-1)}'`
CommitLimit=`echo "1024 * ${CommitLimitTxt}" | bc`
tgt=${CommitLimit}
if [ ${tgt} -eq ${MemFree} ]; then
echo "[OK] CommitLimit: ${tgt}"
else
echo "[NG] unexpected CommitLimit: ${tgt}"
exit 1
fi
# Check Committed_AS
Committed_ASTxt=`cat ./cur_meminfo.txt | grep Committed_AS | awk '{print $(NF-1)}'`
Committed_AS=`echo "1024 * ${Committed_ASTxt}" | bc`
tgt=${Committed_AS}
if [ ${tgt} -eq $((${MemTotal} - ${MemFree})) ]; then
echo "[OK] Committed_AS: ${tgt}"
else
echo "[NG] unexpected Committed_AS: ${tgt}"
exit 1
fi

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

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

46
test/issues/1389/README Normal file
View File

@ -0,0 +1,46 @@
【Issue#1389 動作確認】
□ テスト内容
本Issueの対応で、sysinfo()と/proc/meminfo の下記項目においてMcKernelの情報を
返すようにした。
[sysinfo]
totalram : rusage_global の total_memory
freeram : rusage_global の total_memory - usage_memory
mem_unit : 常に1
[/proc/meminfo]
MemTotal : rusage_global の total_memory
MemFree : rusage_global の total_memory - usage_memory
SwapTotal : 常に0
SwapFree : 常に0
CommitLimit : rusage_global の total_memory - usage_memory
Committed_AS : rusage_global の usage_memory
1. 本Issueで対応したsysinfo() と /proc/meminfo の値が想定どおりとなっていることを確認
McKernelへのメモリ割り当てを 10G@0,10G@1 とした状態で下記プログラムを実行
C1389T01: sysinfo() で取得される値が下記のとおりであることを確認
totalram : 20GiB * 0.95 以上、20GiB 未満であること
freeram : totralram * 0.95 以上、totalram 未満であること
mem_unit : 1 であること
C1389T02: /proc/meminfo から取得される値が下記のとおりであることを確認
MemTotal : 20GiB * 0.95 以上、20GiB 未満であること
MemFree : MemTotal * 0.95 以上、MemTotal 未満であること
SwapTotal : 0 であること
SwapFree : 0 であること
CommitLimit : MemFreeと同値であること
Committed_AS : MemTotal - MemFree と同値であること
2. 本Issueで対応したsysinfo() の項目を利用する以下のLTPを実行し、PASSすることを確認
- mtest01 -p80
- mtest01 -p80 -w
- mem01
□ 実行手順
$ make test
McKernelのインストール先や、OSTEST, LTPの配置場所は、
$HOME/.mck_test_config を参照している
.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを
$HOMEにコピーし、適宜編集する
□ 実行結果
x86_64_result.log aarch64_result.log 参照。
すべての項目をPASSしていることを確認。

View File

@ -0,0 +1,77 @@
sh ./C1389.sh
mcstop+release.sh ... done
mcreboot.sh -c 1-7 -m 10G@0,10G@1 -O ... done
*** C1389T01 start *******************************
[OK] totalram: 21472215040
[OK] freeram: 21461794816
[OK] mem_unit: 1
*** C1389T01 PASSED ******************************
*** C1389T02 start *******************************
[OK] MemTotal: 21472215040
[OK] MemFree: 21452750848
[OK] SwapTotal: 0
[OK] SwapFree: 0
[OK] CommitLimit: 21452750848
[OK] Committed_AS: 19464192
*** C1389T02 PASSED ******************************
*** C1389T03 start *******************************
mtest01 -p80
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
mtest01.c:134: INFO: Filling up 80% of free ram which is 16760729 kbytes
mtest01.c:149: INFO: ... child 50935 starting
mtest01.c:149: INFO: ... child 50944 starting
mtest01.c:149: INFO: ... child 50953 starting
mtest01.c:149: INFO: ... child 50962 starting
mtest01.c:149: INFO: ... child 50971 starting
mtest01.c:149: INFO: ... child 50980 starting
mtest01.c:169: INFO: ... [t=300] 1434451968 bytes allocated only in child 50980
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50935
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50944
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50953
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50962
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 50971
mtest01.c:221: PASS: 16760729 kbytes allocated
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1389T03 PASSED (1)
*** C1389T04 start *******************************
mtest01 -p80 -w
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
mtest01.c:134: INFO: Filling up 80% of free ram which is 16759654 kbytes
mtest01.c:149: INFO: ... child 51017 starting
mtest01.c:149: INFO: ... child 51026 starting
mtest01.c:149: INFO: ... child 51035 starting
mtest01.c:149: INFO: ... child 51044 starting
mtest01.c:149: INFO: ... child 51053 starting
mtest01.c:149: INFO: ... child 51062 starting
mtest01.c:166: INFO: ... [t=300] 1433403392 bytes allocated and used in child 51062
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51017
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51026
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51035
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51044
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 51053
mtest01.c:221: PASS: 16759654 kbytes allocated (and written to)
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1389T04 PASSED (1)
*** C1389T05 start *******************************
mem01
mem01 0 TINFO : Free Mem: 20465 Mb
mem01 0 TINFO : Free Swap: 0 Mb
mem01 0 TINFO : Total Free: 20465 Mb
mem01 0 TINFO : Total Tested: 3056 Mb
mem01 0 TINFO : touching 3056MB of malloc'ed memory (linear)
mem01 1 TPASS : malloc - alloc of 3056MB succeeded
*** C1389T05 PASSED (1)

View File

@ -0,0 +1,77 @@
sh ./C1389.sh
mcstop+release.sh ... done
mcreboot.sh -c 1-7 -m 10G@0,10G@1 -O ... done
*** C1389T01 start *******************************
[OK] totalram: 21463240704
[OK] freeram: 21459673088
[OK] mem_unit: 1
*** C1389T01 PASSED ******************************
*** C1389T02 start *******************************
[OK] MemTotal: 21463240704
[OK] MemFree: 21453983744
[OK] SwapTotal: 0
[OK] SwapFree: 0
[OK] CommitLimit: 21453983744
[OK] Committed_AS: 9256960
*** C1389T02 PASSED ******************************
*** C1389T03 start *******************************
mtest01 -p80
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
mtest01.c:134: INFO: Filling up 80% of free ram which is 16762396 kbytes
mtest01.c:149: INFO: ... child 20718 starting
mtest01.c:149: INFO: ... child 20727 starting
mtest01.c:149: INFO: ... child 20736 starting
mtest01.c:149: INFO: ... child 20745 starting
mtest01.c:149: INFO: ... child 20754 starting
mtest01.c:149: INFO: ... child 20763 starting
mtest01.c:169: INFO: ... [t=300] 1436549120 bytes allocated only in child 20763
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20718
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20727
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20736
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20745
mtest01.c:169: INFO: ... [t=299] 3145728000 bytes allocated only in child 20754
mtest01.c:221: PASS: 16762396 kbytes allocated
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1389T03 PASSED (1)
*** C1389T04 start *******************************
mtest01 -p80 -w
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
mtest01.c:134: INFO: Filling up 80% of free ram which is 16761132 kbytes
mtest01.c:149: INFO: ... child 20802 starting
mtest01.c:149: INFO: ... child 20811 starting
mtest01.c:149: INFO: ... child 20820 starting
mtest01.c:149: INFO: ... child 20829 starting
mtest01.c:149: INFO: ... child 20838 starting
mtest01.c:149: INFO: ... child 20847 starting
mtest01.c:166: INFO: ... [t=300] 1435500544 bytes allocated and used in child 20847
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20802
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20811
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20820
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20829
mtest01.c:166: INFO: ... [t=299] 3145728000 bytes allocated and used in child 20838
mtest01.c:221: PASS: 16761132 kbytes allocated (and written to)
Summary:
passed 1
failed 0
skipped 0
warnings 0
*** C1389T04 PASSED (1)
*** C1389T05 start *******************************
mem01
mem01 0 TINFO : Free Mem: 20463 Mb
mem01 0 TINFO : Free Swap: 0 Mb
mem01 0 TINFO : Total Free: 20463 Mb
mem01 0 TINFO : Total Tested: 3056 Mb
mem01 0 TINFO : touching 3056MB of malloc'ed memory (linear)
mem01 1 TPASS : malloc - alloc of 3056MB succeeded
*** C1389T05 PASSED (1)

63
test/issues/1457/C1457.py Normal file
View File

@ -0,0 +1,63 @@
#
# Test script for issue #1439
#
import os
import sys
import subprocess
def get_command_result(cmd):
results = subprocess.Popen(
cmd, stdout=subprocess.PIPE,
shell=True).stdout.readlines()
return [str(x).rstrip("\n") for x in results]
def enumerate_cpu(cpu_list):
allcpus = []
for ranged_cpu in cpu_list.split(','):
try:
cpu_begin, cpu_end = ranged_cpu.split('-')
except ValueError:
cpu_begin = cpu_end = ranged_cpu
for i in range(int(cpu_begin), int(cpu_end) + 1):
allcpus.append(i)
allcpus.sort()
return allcpus
def get_online_cpu():
online_file = open('/sys/devices/system/cpu/online', 'r')
return online_file.readlines()[0].strip()
def get_cpuinfo_processors():
processors = []
cpuinfo_file = open('/proc/cpuinfo', 'r')
for line in cpuinfo_file.readlines():
if line.startswith('processor'):
processor = int(line.strip().split()[-1])
processors.append(processor)
return processors
def main():
onlines = enumerate_cpu(get_online_cpu())
processors = get_cpuinfo_processors()
print '# of online cpus:', len(onlines)
print '# of cpuinfo processors:', len(processors)
if len(onlines) != len(processors):
print 'ERROR: # of processors is not equal to # of cpus'
print 'FAIL'
exit()
i = 0
for cpu in processors:
print i, 'processor:', cpu
if i != cpu:
print 'ERROR: processor number is not ordered'
print 'FAIL'
exit()
i = i + 1
print 'SUCCESS'
if __name__ == '__main__':
main()

7
test/issues/1457/C1457.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
. ${HOME}/.mck_test_config
export MCK_DIR
sudo ${MCK_DIR}/sbin/mcreboot.sh 1,3,5,7,9-12,50-58
${MCK_DIR}/bin/mcexec python C1457.py
sudo ${MCK_DIR}/sbin/mcstop+release.sh

View File

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

22
test/issues/1457/README Normal file
View File

@ -0,0 +1,22 @@
□ テスト内容
arm64環境における/proc/cpuinfoについて、以下を確かめる。
(1) "processor" フィールドが/sys/devices/system/cpu/onlineファイルが示す
CPUの数だけ存在すること。
(2) "processor" フィールドの値が0からはじまる連番であること。
□ 実行手順
(1) $HOME/.mck_test_configを、MCK_DIRがMcKernelのインストール先を指すように編集する
(2) 以下を実行する
$ make test
□ 確認方法
標準出力にSUCCESSが出力されること

View File

@ -0,0 +1,31 @@
# of online cpus: 28
# of cpuinfo processors: 28
0 processor: 0
1 processor: 1
2 processor: 2
3 processor: 3
4 processor: 4
5 processor: 5
6 processor: 6
7 processor: 7
8 processor: 8
9 processor: 9
10 processor: 10
11 processor: 11
12 processor: 12
13 processor: 13
14 processor: 14
15 processor: 15
16 processor: 16
17 processor: 17
18 processor: 18
19 processor: 19
20 processor: 20
21 processor: 21
22 processor: 22
23 processor: 23
24 processor: 24
25 processor: 25
26 processor: 26
27 processor: 27
SUCCESS

145
test/issues/929/C929.sh Executable file
View File

@ -0,0 +1,145 @@
#/bin/sh
USELTP=0
USEOSTEST=0
. ../../common.sh
issue="929"
tid=01
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
TEST_CMD="mpirun -f ./hostfile -ppn 5 ${MCEXEC} -n 5 ./test_prog.sh"
echo ${TEST_CMD}
${TEST_CMD} &> ${tname}.txt
mpi_ret=$?
cat ./${tname}.txt
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
if [ ${mpi_ret} -eq 0 -a ${started_num} -eq 5 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
TEST_CMD="mpirun -f ./hostfile -ppn 5 ${MCEXEC} -n 3 ./test_prog.sh"
echo ${TEST_CMD}
${TEST_CMD} &> ${tname}.txt
mpi_ret=$?
cat ./${tname}.txt
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
if [ ${mpi_ret} -ne 0 -a ${started_num} -eq 3 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
TEST_CMD="mpirun -f ./hostfile -ppn 3 ${MCEXEC} -n 5 ./test_prog.sh"
echo ${TEST_CMD}
${TEST_CMD} &> ${tname}.txt
mpi_ret=$?
cat ./${tname}.txt
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
if [ ${mpi_ret} -ne 0 -a ${started_num} -eq 0 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
TEST_CMD="mpirun -f ./hostfile -ppn 6 ${MCEXEC} -n 3 ./test_prog.sh"
echo ${TEST_CMD}
${TEST_CMD} &> ${tname}.txt
mpi_ret=$?
cat ./${tname}.txt
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
if [ ${mpi_ret} -ne 0 -a ${started_num} -eq 3 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
TEST_CMD="mpirun -f ./hostfile -ppn 250 ${MCEXEC} -n 250 ./test_prog.sh"
echo ${TEST_CMD}
${TEST_CMD} &> ${tname}.txt
mpi_ret=$?
head -n 10 ./${tname}.txt
echo "..."
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
if [ ${mpi_ret} -ne 0 -a ${started_num} -eq 0 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""
tname=`printf "C${issue}T%02d" ${tid}`
echo "*** ${tname} start *******************************"
ng=0
TEST_CMD="mpirun -f ./hostfile -ppn 5 ${MCEXEC} -n 5 ./test_prog.sh"
echo "** reboot mcrernel for check pe_list_len"
mcreboot
echo "** enable debug message in mcexec_get_cpuset"
sudo sh -c "echo -n 'func mcexec_get_cpuset +p' > /sys/kernel/debug/dynamic_debug/control"
echo ${TEST_CMD}
for i in `seq 1 20`
do
${TEST_CMD} &> ${tname}.txt
mpi_ret=$?
started_num=`grep 'test_prog is started' ./${tname}.txt | wc -l`
if [ ${mpi_ret} -eq 0 -a ${started_num} -eq 5 ]; then
echo "[OK] exec: $i"
else
echo "[NG] exec: $i"
let ng++
fi
done
echo "** check pe_list_len"
dmesg --notime | grep "mcexec_get_cpuset: pe_list" | tail -n 20 | cut -f 2-3 -d ':' > ./pe_list_len.txt
cat ./pe_list_len.txt | while read line
do
len=`echo ${line} | cut -f 2 -d ':'`
if [ ${len} -ge 0 -a ${len} -le 5 ]; then
echo "[OK] ${line}"
else
echo "[NG] ${line}"
let ng++
fi
done
echo "** disable debug message in mcexec_get_cpuset"
sudo sh -c "echo -n 'func mcexec_get_cpuset -p' > /sys/kernel/debug/dynamic_debug/control"
if [ ${ng} -eq 0 ]; then
echo "*** ${tname} PASSED ******************************"
else
echo "*** ${tname} FAILED ******************************"
fi
let tid++
echo ""

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

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

36
test/issues/929/README Normal file
View File

@ -0,0 +1,36 @@
【Issue#929 動作確認】
□ テスト内容
1. mpirunで指定する-ppnと、mcexecで指定する-n の指定状況ごとに
想定どおりの動作となることを確認
C929T01:
-ppn == -n の場合に、プログラムが実行され、mpirunが成功する
C929T02:
-ppn > -n の場合に、プログラムの一部が実行され、mpirunが失敗する
C929T03:
-ppn < -n の場合に、プログラムが実行されず、mpirunが失敗する
C929T04:
-ppn が -n の整数倍である場合に、プログラムの一部が実行され、mpirunが失敗する
C929T05:
-ppn と -n がMcKernelに割り当てたCPU数よりも大きい場合に、
プログラムが実行されず、mpirunが失敗する
C929T06:
-ppn == -n での正常実行を20回連続で行った場合に、
プログラムが実行され、mpirunが成功する
また、mcctrlで管理しているpart_exec_list の要素数が5を超えない
□ 実行手順
$ make test
McKernelのインストール先や、OSTEST, LTPの配置場所は、
$HOME/.mck_test_config を参照している
.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを
$HOMEにコピーし、適宜編集する
□ 実行結果
x86_64_result.log aarch64_result.log 参照。
すべての項目をPASSしていることを確認。

View File

@ -0,0 +1,99 @@
*** C929T01 start *******************************
mpirun -f ./hostfile -ppn 5 /home/satoken/ihk+mckernel/bin/mcexec -n 5 ./test_prog.sh
test_prog is started.
test_prog is started.
test_prog is started.
test_prog is started.
test_prog is started.
*** C929T01 PASSED ******************************
*** C929T02 start *******************************
mpirun -f ./hostfile -ppn 5 /home/satoken/ihk+mckernel/bin/mcexec -n 3 ./test_prog.sh
getting CPU set for partitioned execution: Invalid argument
getting CPU set for partitioned execution: Invalid argument
test_prog is started.
test_prog is started.
test_prog is started.
*** C929T02 PASSED ******************************
*** C929T03 start *******************************
mpirun -f ./hostfile -ppn 3 /home/satoken/ihk+mckernel/bin/mcexec -n 5 ./test_prog.sh
getting CPU set for partitioned execution: Connection timed out
getting CPU set for partitioned execution: Connection timed out
getting CPU set for partitioned execution: Connection timed out
*** C929T03 PASSED ******************************
*** C929T04 start *******************************
mpirun -f ./hostfile -ppn 6 /home/satoken/ihk+mckernel/bin/mcexec -n 3 ./test_prog.sh
getting CPU set for partitioned execution: Invalid argument
getting CPU set for partitioned execution: Invalid argument
getting CPU set for partitioned execution: Invalid argument
test_prog is started.
test_prog is started.
test_prog is started.
*** C929T04 PASSED ******************************
*** C929T05 start *******************************
mpirun -f ./hostfile -ppn 250 /home/satoken/ihk+mckernel/bin/mcexec -n 250 ./test_prog.sh
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
...
*** C929T05 PASSED ******************************
*** C929T06 start *******************************
** reboot mcrernel for check pe_list_len
mcreboot.sh -c 1-6,29-34 -m 50G@0,50G@1 -r 1-6:0+29-34:28 -O ... done
** enable debug message in mcexec_get_cpuset
mpirun -f ./hostfile -ppn 5 /home/satoken/ihk+mckernel/bin/mcexec -n 5 ./test_prog.sh
[OK] exec: 1
[OK] exec: 2
[OK] exec: 3
[OK] exec: 4
[OK] exec: 5
[OK] exec: 6
[OK] exec: 7
[OK] exec: 8
[OK] exec: 9
[OK] exec: 10
[OK] exec: 11
[OK] exec: 12
[OK] exec: 13
[OK] exec: 14
[OK] exec: 15
[OK] exec: 16
[OK] exec: 17
[OK] exec: 18
[OK] exec: 19
[OK] exec: 20
** check pe_list_len
[OK] pe_list_len:0
[OK] pe_list_len:1
[OK] pe_list_len:2
[OK] pe_list_len:3
[OK] pe_list_len:4
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
[OK] pe_list_len:5
** disable debug message in mcexec_get_cpuset
*** C929T06 PASSED ******************************

1
test/issues/929/hostfile Normal file
View File

@ -0,0 +1 @@
localhost

3
test/issues/929/test_prog.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
echo "test_prog is started."

View File

@ -0,0 +1,74 @@
*** C929T01 start *******************************
mpirun -f ./hostfile -ppn 5 /home/satoken/ihk+mckernel/bin/mcexec -n 5 ./test_prog.sh
test_prog is started.
test_prog is started.
test_prog is started.
test_prog is started.
test_prog is started.
*** C929T01 PASSED ******************************
*** C929T02 start *******************************
mpirun -f ./hostfile -ppn 5 /home/satoken/ihk+mckernel/bin/mcexec -n 3 ./test_prog.sh
getting CPU set for partitioned execution: Invalid argument
getting CPU set for partitioned execution: Invalid argument
test_prog is started.
test_prog is started.
test_prog is started.
*** C929T02 PASSED ******************************
*** C929T03 start *******************************
mpirun -f ./hostfile -ppn 3 /home/satoken/ihk+mckernel/bin/mcexec -n 5 ./test_prog.sh
getting CPU set for partitioned execution: Connection timed out
getting CPU set for partitioned execution: Connection timed out
getting CPU set for partitioned execution: Connection timed out
*** C929T03 PASSED ******************************
*** C929T04 start *******************************
mpirun -f ./hostfile -ppn 6 /home/satoken/ihk+mckernel/bin/mcexec -n 3 ./test_prog.sh
getting CPU set for partitioned execution: Invalid argument
getting CPU set for partitioned execution: Invalid argument
getting CPU set for partitioned execution: Invalid argument
test_prog is started.
test_prog is started.
test_prog is started.
*** C929T04 PASSED ******************************
*** C929T05 start *******************************
mpirun -f ./hostfile -ppn 250 /home/satoken/ihk+mckernel/bin/mcexec -n 250 ./test_prog.sh
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
error: nr_processes can't exceed nr. of CPUs
...
*** C929T05 PASSED ******************************
*** C929T06 start *******************************
mpirun -f ./hostfile -ppn 5 /home/satoken/ihk+mckernel/bin/mcexec -n 5 ./test_prog.sh
[OK] exec: 1
[OK] exec: 2
[OK] exec: 3
[OK] exec: 4
[OK] exec: 5
[OK] exec: 6
[OK] exec: 7
[OK] exec: 8
[OK] exec: 9
[OK] exec: 10
[OK] exec: 11
[OK] exec: 12
[OK] exec: 13
[OK] exec: 14
[OK] exec: 15
[OK] exec: 16
[OK] exec: 17
[OK] exec: 18
[OK] exec: 19
[OK] exec: 20
*** C929T06 PASSED ******************************