Compare commits
152 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 14d819eff4 | |||
| 1cbe389879 | |||
| 0758f6254e | |||
| db732a245c | |||
| 08f2840f7d | |||
| 521bdc6181 | |||
| e7b6a3472b | |||
| 11756d96ef | |||
| f185be06eb | |||
| 854bc85602 | |||
| ab8fe0bbbf | |||
| b87c06cbcb | |||
| b939ca9370 | |||
| ec202a1ca9 | |||
| d4471df94e | |||
| a6ac4acf40 | |||
| 8ff754c466 | |||
| 90dba00742 | |||
| 86ae1380e4 | |||
| 9bb48186e6 | |||
| 139123dc12 | |||
| 6602cf442c | |||
| f148863586 | |||
| ec375da27a | |||
| c50e7c1029 | |||
| 5f4dbb2c71 | |||
| 328609269b | |||
| 056fdb2633 | |||
| 09d0a59e22 | |||
| 511555c8cb | |||
| 81699345cc | |||
| 130751ff66 | |||
| f3d18eb9de | |||
| 249bda4aef | |||
| aaa246f86f | |||
| c52f7a5b49 | |||
| 90a34f54c9 | |||
| bfb5080b71 | |||
| 641dfed37e | |||
| 4572e6be3f | |||
| 12e44050c9 | |||
| d5190990f5 | |||
| 82822b1f16 | |||
| 7f02889f76 | |||
| 9dc86869d8 | |||
| 02bb127007 | |||
| c26c4aba4f | |||
| e8d8ad60c2 | |||
| a7f645f7df | |||
| 73731d2a0d | |||
| 0f049c5ed7 | |||
| 8d5f95de04 | |||
| 88fca2c0df | |||
| 81d18e35dd | |||
| 309da8fc53 | |||
| 535e3f3af6 | |||
| 4c80dca479 | |||
| 7bef1f5117 | |||
| bb8c8355c2 | |||
| fab0641813 | |||
| ce3af4734a | |||
| e2dea4e9f8 | |||
| 0d9c1df75a | |||
| 6a979cf4b8 | |||
| c107d1fdf9 | |||
| bc89a51e00 | |||
| 9da9e755fa | |||
| fe42481d6f | |||
| b1ea6eb82a | |||
| 8c2e20c3aa | |||
| 65667709a8 | |||
| 51bc5fd61f | |||
| 3b277b2354 | |||
| 3e4c9bdd90 | |||
| 06b1b4f8ab | |||
| 7b4de6e6c2 | |||
| 1c266f4849 | |||
| b7a7281195 | |||
| b77732fb4f | |||
| a224bf648a | |||
| 642520f80c | |||
| 5cb75b00c7 | |||
| 7dd0d1137f | |||
| cb2fe29f06 | |||
| 3432f46d8b | |||
| afcf1a24aa | |||
| 140f813d77 | |||
| 7ad6f9595c | |||
| 1796c20b88 | |||
| 0da5b76916 | |||
| 4ac1efae6c | |||
| 523a066245 | |||
| 98df469d29 | |||
| f46287a711 | |||
| c260b5c6f3 | |||
| c9157f273f | |||
| 840acd6021 | |||
| c949a894c6 | |||
| 228f8f8533 | |||
| 8ee9eca74e | |||
| 748429fc92 | |||
| a9dfcd9a89 | |||
| 559fc9746c | |||
| 54169bc3ea | |||
| 142e923222 | |||
| 86efc86945 | |||
| ebaafa95d8 | |||
| b8ee144e67 | |||
| 722ae0e7d5 | |||
| f56e087208 | |||
| f55f01cc11 | |||
| 1fa398cfab | |||
| 8123cc413e | |||
| d4459cf9f3 | |||
| 4bb65494e9 | |||
| 2f2b3cdc6f | |||
| 1e9f9d9809 | |||
| 1b25379c02 | |||
| 38bbb4e390 | |||
| 0fa88f513f | |||
| cd54c5983a | |||
| 6084faeecd | |||
| d209c00a30 | |||
| 9a5d5feb9c | |||
| 0cda763f95 | |||
| cc7be46b7d | |||
| 589504dc33 | |||
| bf2f38051b | |||
| 2d2d0af6fb | |||
| 7f47dc78a1 | |||
| c3c9187ed5 | |||
| aebacb243e | |||
| 5a8d1f09e8 | |||
| 0e10b6d1ee | |||
| d649d6fc2d | |||
| bad487cc07 | |||
| 3b6056fb1a | |||
| 5cc738d6bd | |||
| c9fa445f54 | |||
| d273a2f58b | |||
| 4e7069d499 | |||
| 66f44e77af | |||
| 35f908b75c | |||
| 2f0089dfb9 | |||
| 2af6d5115a | |||
| ac25c5e1e7 | |||
| 90c0355d90 | |||
| 43230eb623 | |||
| f18dc8428d | |||
| ab53c8e0a4 | |||
| 6c33e236d7 | |||
| 85d36f1469 |
@ -4,7 +4,7 @@ INCDIR = @INCDIR@
|
||||
ETCDIR = @ETCDIR@
|
||||
MANDIR = @MANDIR@
|
||||
|
||||
all: executer-mcctrl executer-mcoverlayfs executer-user mckernel
|
||||
all: executer-mcctrl executer-mcoverlayfs executer-user mckernel mck-tools
|
||||
|
||||
executer-mcctrl:
|
||||
+@(cd executer/kernel/mcctrl; $(MAKE) modules)
|
||||
@ -26,6 +26,9 @@ mckernel:
|
||||
;; \
|
||||
esac
|
||||
|
||||
mck-tools:
|
||||
+@(cd tools/mcstat; $(MAKE))
|
||||
|
||||
install:
|
||||
@(cd executer/kernel/mcctrl; $(MAKE) install)
|
||||
@(cd executer/kernel/mcoverlayfs; $(MAKE) install)
|
||||
@ -60,6 +63,7 @@ install:
|
||||
exit 1 \
|
||||
;; \
|
||||
esac
|
||||
@(cd tools/mcstat/; $(MAKE) install)
|
||||
|
||||
clean:
|
||||
@(cd executer/kernel/mcctrl; $(MAKE) clean)
|
||||
@ -74,3 +78,4 @@ clean:
|
||||
exit 1 \
|
||||
;; \
|
||||
esac
|
||||
@(cd tools/mcstat; $(MAKE) clean)
|
||||
|
||||
@ -1172,8 +1172,6 @@ void arch_clone_thread(struct thread *othread, unsigned long pc,
|
||||
asm("mrs %0, tpidr_el0" : "=r" (tls));
|
||||
othread->tlsblock_base = nthread->tlsblock_base = tls;
|
||||
|
||||
/* copy fp_regs values from parent. */
|
||||
save_fp_regs(othread);
|
||||
if ((othread->fp_regs != NULL) && (check_and_allocate_fp_regs(nthread) == 0)) {
|
||||
memcpy(nthread->fp_regs, othread->fp_regs, sizeof(fp_regs_struct));
|
||||
}
|
||||
|
||||
@ -144,5 +144,3 @@ SYSCALL_HANDLED(1045, signalfd)
|
||||
SYSCALL_DELEGATED(1049, stat)
|
||||
SYSCALL_DELEGATED(1060, getpgrp)
|
||||
SYSCALL_DELEGATED(1062, time)
|
||||
SYSCALL_HANDLED(1071, vfork)
|
||||
SYSCALL_DELEGATED(1079, fork)
|
||||
|
||||
@ -1807,7 +1807,6 @@ static int clear_range_l1(void *args0, pte_t *ptep, uint64_t base,
|
||||
ihk_mc_free_pages_user(phys_to_virt(phys), npages);
|
||||
dkprintf("%s: freeing regular page at 0x%lx\n", __FUNCTION__, base);
|
||||
}
|
||||
args->vm->currss -= PTL1_SIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1887,7 +1886,6 @@ static int clear_range_middle(void *args0, pte_t *ptep, uint64_t base,
|
||||
ihk_mc_free_pages_user(phys_to_virt(phys), npages);
|
||||
dkprintf("%s(level=%d): freeing large page at 0x%lx\n", __FUNCTION__, level, base);
|
||||
}
|
||||
args->vm->currss -= tbl.pgsize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <hwcap.h>
|
||||
#include <prctl.h>
|
||||
#include <limits.h>
|
||||
#include <syscall.h>
|
||||
|
||||
extern void ptrace_report_signal(struct thread *thread, int sig);
|
||||
extern void clear_single_step(struct thread *thread);
|
||||
@ -1322,6 +1323,17 @@ interrupt_from_user(void *regs0)
|
||||
return((regs->pstate & PSR_MODE_MASK) == PSR_MODE_EL0t);
|
||||
}
|
||||
|
||||
void save_syscall_return_value(int num, unsigned long rc)
|
||||
{
|
||||
/*
|
||||
* Save syscall return value.
|
||||
*/
|
||||
if (cpu_local_var(current) && cpu_local_var(current)->uctx &&
|
||||
num != __NR_rt_sigsuspend) {
|
||||
ihk_mc_syscall_arg0(cpu_local_var(current)->uctx) = rc;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check_signal(unsigned long rc, void *regs0, int num)
|
||||
{
|
||||
@ -1346,16 +1358,6 @@ __check_signal(unsigned long rc, void *regs0, int num, int irq_disabled)
|
||||
return;
|
||||
thread = cpu_local_var(current);
|
||||
|
||||
/**
|
||||
* If check_signal is called from syscall(),
|
||||
* then save syscall return value.
|
||||
*/
|
||||
if((regs == NULL)&&(num != __NR_rt_sigsuspend)){ /* It's call from syscall! */
|
||||
// Get user context through current thread
|
||||
// and update syscall return.
|
||||
ihk_mc_syscall_arg0(thread->uctx) = rc;
|
||||
}
|
||||
|
||||
if(thread == NULL || thread->proc->pid == 0){
|
||||
struct thread *t;
|
||||
irqstate = ihk_mc_spinlock_lock(&(cpu_local_var(runq_lock)));
|
||||
@ -1799,8 +1801,9 @@ SYSCALL_DECLARE(mmap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((flags & MAP_FIXED) && ((addr < region->user_start)
|
||||
|| (region->user_end <= addr))) {
|
||||
if (addr < region->user_start
|
||||
|| region->user_end <= addr
|
||||
|| len > (region->user_end - region->user_start)) {
|
||||
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n",
|
||||
addr0, len0, prot, flags0, fd, off0);
|
||||
error = -ENOMEM;
|
||||
@ -2497,4 +2500,15 @@ out:
|
||||
return mpsr->phase_ret;
|
||||
}
|
||||
|
||||
time_t time(void) {
|
||||
struct timespec ats;
|
||||
|
||||
if (gettime_local_support) {
|
||||
calculate_time_from_tsc(&ats);
|
||||
return ats.tv_sec;
|
||||
}
|
||||
|
||||
return (time_t)0;
|
||||
}
|
||||
|
||||
/*** End of File ***/
|
||||
|
||||
@ -849,6 +849,7 @@ void setup_x86_ap(void (*next_func)(void))
|
||||
void arch_show_interrupt_context(const void *reg);
|
||||
void set_signal(int sig, void *regs, struct siginfo *info);
|
||||
void check_signal(unsigned long, void *, int);
|
||||
void check_sig_pending();
|
||||
extern void tlb_flush_handler(int vector);
|
||||
|
||||
void __show_stack(uintptr_t *sp) {
|
||||
@ -870,6 +871,19 @@ void show_context_stack(uintptr_t *rbp) {
|
||||
return;
|
||||
}
|
||||
|
||||
void interrupt_exit(struct x86_user_context *regs)
|
||||
{
|
||||
if (interrupt_from_user(regs)) {
|
||||
cpu_enable_interrupt();
|
||||
check_sig_pending();
|
||||
check_need_resched();
|
||||
check_signal(0, regs, 0);
|
||||
}
|
||||
else {
|
||||
check_sig_pending();
|
||||
}
|
||||
}
|
||||
|
||||
void handle_interrupt(int vector, struct x86_user_context *regs)
|
||||
{
|
||||
struct ihk_mc_interrupt_handler *h;
|
||||
@ -992,12 +1006,8 @@ void handle_interrupt(int vector, struct x86_user_context *regs)
|
||||
}
|
||||
}
|
||||
|
||||
if(interrupt_from_user(regs)){
|
||||
cpu_enable_interrupt();
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
}
|
||||
set_cputime(0);
|
||||
interrupt_exit(regs);
|
||||
set_cputime(interrupt_from_user(regs)? 0: 1);
|
||||
|
||||
--v->in_interrupt;
|
||||
}
|
||||
@ -1012,13 +1022,9 @@ void gpe_handler(struct x86_user_context *regs)
|
||||
panic("gpe_handler");
|
||||
}
|
||||
set_signal(SIGSEGV, regs, NULL);
|
||||
if(interrupt_from_user(regs)){
|
||||
cpu_enable_interrupt();
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
}
|
||||
set_cputime(0);
|
||||
// panic("GPF");
|
||||
interrupt_exit(regs);
|
||||
set_cputime(interrupt_from_user(regs)? 0: 1);
|
||||
panic("GPF");
|
||||
}
|
||||
|
||||
void debug_handler(struct x86_user_context *regs)
|
||||
@ -1045,12 +1051,8 @@ void debug_handler(struct x86_user_context *regs)
|
||||
memset(&info, '\0', sizeof info);
|
||||
info.si_code = si_code;
|
||||
set_signal(SIGTRAP, regs, &info);
|
||||
if(interrupt_from_user(regs)){
|
||||
cpu_enable_interrupt();
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
}
|
||||
set_cputime(0);
|
||||
interrupt_exit(regs);
|
||||
set_cputime(interrupt_from_user(regs)? 0: 1);
|
||||
}
|
||||
|
||||
void int3_handler(struct x86_user_context *regs)
|
||||
@ -1067,12 +1069,8 @@ void int3_handler(struct x86_user_context *regs)
|
||||
memset(&info, '\0', sizeof info);
|
||||
info.si_code = TRAP_BRKPT;
|
||||
set_signal(SIGTRAP, regs, &info);
|
||||
if(interrupt_from_user(regs)){
|
||||
cpu_enable_interrupt();
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
}
|
||||
set_cputime(0);
|
||||
interrupt_exit(regs);
|
||||
set_cputime(interrupt_from_user(regs)? 0: 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1582,6 +1580,8 @@ void arch_show_interrupt_context(const void *reg)
|
||||
__kprintf("%16lx %16lx %16lx %16lx\n",
|
||||
regs->cs, regs->ss, regs->rflags, regs->error);
|
||||
|
||||
kprintf_unlock(irqflags);
|
||||
return;
|
||||
arch_show_extended_context();
|
||||
|
||||
arch_print_pre_interrupt_stack(regs);
|
||||
|
||||
@ -64,7 +64,6 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
|
||||
return oldval;
|
||||
}
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_8 /* arch depend hide */
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
@ -128,7 +127,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* !POSTK_DEBUG_ARCH_DEP_8 */
|
||||
|
||||
static inline int get_futex_value_locked(uint32_t *dest, uint32_t *from)
|
||||
{
|
||||
|
||||
@ -134,6 +134,8 @@ typedef struct mcs_lock_node {
|
||||
unsigned long irqsave;
|
||||
} __attribute__((aligned(64))) mcs_lock_node_t;
|
||||
|
||||
typedef mcs_lock_node_t mcs_lock_t;
|
||||
|
||||
static void mcs_lock_init(struct mcs_lock_node *node)
|
||||
{
|
||||
node->locked = 0;
|
||||
|
||||
@ -18,6 +18,11 @@
|
||||
#define _NSIG_BPW 64
|
||||
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
|
||||
|
||||
static inline int valid_signal(unsigned long sig)
|
||||
{
|
||||
return sig <= _NSIG ? 1 : 0;
|
||||
}
|
||||
|
||||
typedef unsigned long int __sigset_t;
|
||||
#define __sigmask(sig) (((__sigset_t) 1) << ((sig) - 1))
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ SYSCALL_HANDLED(36, getitimer)
|
||||
SYSCALL_HANDLED(38, setitimer)
|
||||
SYSCALL_HANDLED(39, getpid)
|
||||
SYSCALL_HANDLED(56, clone)
|
||||
SYSCALL_DELEGATED(57, fork)
|
||||
SYSCALL_HANDLED(57, fork)
|
||||
SYSCALL_HANDLED(58, vfork)
|
||||
SYSCALL_HANDLED(59, execve)
|
||||
SYSCALL_HANDLED(60, exit)
|
||||
|
||||
@ -145,6 +145,8 @@ nmi:
|
||||
movq %rsp,%gs:PANIC_REGS+0x08
|
||||
|
||||
movl nmi_mode(%rip),%eax
|
||||
cmp $3,%rax
|
||||
je 4f
|
||||
cmp $1,%rax
|
||||
je 1f
|
||||
cmp $2,%rax
|
||||
@ -199,9 +201,9 @@ nmi:
|
||||
movl %eax,%gs:PANIC_REGS+0xA0
|
||||
movq $1,%gs:PANICED
|
||||
call ihk_mc_query_mem_areas
|
||||
1:
|
||||
4:
|
||||
hlt
|
||||
jmp 1b
|
||||
jmp 4b
|
||||
|
||||
.globl x86_syscall
|
||||
x86_syscall:
|
||||
|
||||
@ -493,7 +493,7 @@ uint64_t ihk_mc_pt_virt_to_pagemap(struct page_table *pt, unsigned long virt)
|
||||
|
||||
error = ihk_mc_pt_virt_to_phys(pt, (void *)virt, &phys);
|
||||
if (error) {
|
||||
return 0;
|
||||
return PM_PSHIFT(PAGE_SHIFT);
|
||||
}
|
||||
|
||||
pagemap = PM_PFRAME(phys >> PAGE_SHIFT);
|
||||
@ -1542,7 +1542,6 @@ static int clear_range_l1(void *args0, pte_t *ptep, uint64_t base,
|
||||
dkprintf("%lx-,%s: calling memory_stat_rss_sub(),phys=%lx,size=%ld,pgsize=%ld\n", pte_get_phys(&old), __FUNCTION__, pte_get_phys(&old), PTL1_SIZE, PTL1_SIZE);
|
||||
rusage_memory_stat_sub(args->memobj, PTL1_SIZE, PTL1_SIZE);
|
||||
}
|
||||
args->vm->currss -= PTL1_SIZE;
|
||||
} else {
|
||||
dkprintf("%s: !calling memory_stat_rss_sub(),virt=%lx,phys=%lx\n", __FUNCTION__, base, pte_get_phys(&old));
|
||||
}
|
||||
@ -1611,7 +1610,6 @@ static int clear_range_l2(void *args0, pte_t *ptep, uint64_t base,
|
||||
dkprintf("%lx-,%s: calling memory_stat_rss_sub(),phys=%lx,size=%ld,pgsize=%ld\n", pte_get_phys(&old), __FUNCTION__, pte_get_phys(&old), PTL2_SIZE, PTL2_SIZE);
|
||||
rusage_memory_stat_sub(args->memobj, PTL2_SIZE, PTL2_SIZE);
|
||||
}
|
||||
args->vm->currss -= PTL2_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1693,7 +1691,6 @@ static int clear_range_l3(void *args0, pte_t *ptep, uint64_t base,
|
||||
dkprintf("%lx-,%s: calling memory_stat_rss_sub(),phys=%lx,size=%ld,pgsize=%ld\n", pte_get_phys(&old), __FUNCTION__, pte_get_phys(&old), PTL3_SIZE, PTL3_SIZE);
|
||||
rusage_memory_stat_sub(args->memobj, PTL3_SIZE, PTL3_SIZE);
|
||||
}
|
||||
args->vm->currss -= PTL3_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,8 +30,9 @@
|
||||
#include <ihk/ikc.h>
|
||||
#include <page.h>
|
||||
#include <limits.h>
|
||||
#include <syscall.h>
|
||||
|
||||
void terminate(int, int);
|
||||
void terminate_mcexec(int, int);
|
||||
extern long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
||||
long syscall(int num, ihk_mc_user_context_t *ctx);
|
||||
void set_signal(int sig, void *regs0, siginfo_t *info);
|
||||
@ -142,8 +143,6 @@ SYSCALL_DECLARE(rt_sigaction)
|
||||
struct k_sigaction new_sa, old_sa;
|
||||
int rc;
|
||||
|
||||
if(sig == SIGKILL || sig == SIGSTOP || sig <= 0 || sig > 64)
|
||||
return -EINVAL;
|
||||
if (sigsetsize != sizeof(sigset_t))
|
||||
return -EINVAL;
|
||||
|
||||
@ -251,8 +250,8 @@ SYSCALL_DECLARE(rt_sigreturn)
|
||||
regs->gpr.rflags &= ~RFLAGS_TF;
|
||||
info.si_code = TRAP_TRACE;
|
||||
set_signal(SIGTRAP, regs, &info);
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
check_signal(0, regs, 0);
|
||||
}
|
||||
|
||||
if(ksigsp.fpregs && xsavesize){
|
||||
@ -279,6 +278,7 @@ SYSCALL_DECLARE(rt_sigreturn)
|
||||
extern struct cpu_local_var *clv;
|
||||
extern unsigned long do_kill(struct thread *thread, int pid, int tid, int sig, struct siginfo *info, int ptracecont);
|
||||
extern void interrupt_syscall(struct thread *, int sig);
|
||||
extern void terminate(int, int);
|
||||
extern int num_processors;
|
||||
|
||||
#define RFLAGS_MASK (RFLAGS_CF | RFLAGS_PF | RFLAGS_AF | RFLAGS_ZF | \
|
||||
@ -807,6 +807,11 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
||||
regs->gpr.rip = (unsigned long)k->sa.sa_handler;
|
||||
regs->gpr.rsp = (unsigned long)usp;
|
||||
|
||||
// check signal handler is ONESHOT
|
||||
if (k->sa.sa_flags & SA_RESETHAND) {
|
||||
k->sa.sa_handler = SIG_DFL;
|
||||
}
|
||||
|
||||
if(!(k->sa.sa_flags & SA_NODEFER))
|
||||
thread->sigmask.__val[0] |= pending->sigmask.__val[0];
|
||||
kfree(pending);
|
||||
@ -818,8 +823,8 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
||||
regs->gpr.rflags &= ~RFLAGS_TF;
|
||||
info.si_code = TRAP_TRACE;
|
||||
set_signal(SIGTRAP, regs, &info);
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
check_signal(0, regs, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1006,6 +1011,12 @@ interrupt_from_user(void *regs0)
|
||||
return !(regs->gpr.rsp & 0x8000000000000000);
|
||||
}
|
||||
|
||||
void save_syscall_return_value(int num, unsigned long rc)
|
||||
{
|
||||
/* Empty on x86 */
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
check_signal(unsigned long rc, void *regs0, int num)
|
||||
{
|
||||
@ -1053,6 +1064,110 @@ 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) ||
|
||||
(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 &&
|
||||
!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()
|
||||
{
|
||||
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->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)
|
||||
@ -1214,15 +1329,19 @@ done:
|
||||
mcs_rwlock_reader_lock_noirq(&tproc->update_lock, &updatelock);
|
||||
savelock = &tthread->sigpendinglock;
|
||||
head = &tthread->sigpending;
|
||||
if(sig == SIGKILL ||
|
||||
(tproc->status != PS_EXITED &&
|
||||
tproc->status != PS_ZOMBIE &&
|
||||
tthread->status != PS_EXITED)){
|
||||
hold_thread(tthread);
|
||||
mcs_rwlock_reader_lock_noirq(&tproc->threads_lock, &lock);
|
||||
if (tthread->status != PS_EXITED &&
|
||||
(sig == SIGKILL ||
|
||||
(tproc->status != PS_EXITED && tproc->status != PS_ZOMBIE))) {
|
||||
if ((rc = hold_thread(tthread))) {
|
||||
kprintf("%s: ERROR hold_thread returned %d,tid=%d\n", __FUNCTION__, rc, tthread->tid);
|
||||
tthread = NULL;
|
||||
}
|
||||
}
|
||||
else{
|
||||
tthread = NULL;
|
||||
}
|
||||
mcs_rwlock_reader_unlock_noirq(&tproc->threads_lock, &lock);
|
||||
mcs_rwlock_reader_unlock_noirq(&tproc->update_lock, &updatelock);
|
||||
mcs_rwlock_reader_unlock_noirq(&thash->lock[hash], &lock);
|
||||
}
|
||||
@ -1249,7 +1368,9 @@ done:
|
||||
}
|
||||
|
||||
if (tthread->thread_offloaded) {
|
||||
interrupt_syscall(tthread, sig);
|
||||
if (!tthread->proc->nohost) {
|
||||
interrupt_syscall(tthread, sig);
|
||||
}
|
||||
release_thread(tthread);
|
||||
return 0;
|
||||
}
|
||||
@ -1284,6 +1405,7 @@ done:
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
else{
|
||||
memset(pending, 0, sizeof(struct sig_pending));
|
||||
pending->sigmask.__val[0] = mask;
|
||||
memcpy(&pending->info, info, sizeof(siginfo_t));
|
||||
pending->ptracecont = ptracecont;
|
||||
@ -1307,9 +1429,6 @@ done:
|
||||
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tthread->cpu_id)->apic_id, 0xd0);
|
||||
}
|
||||
|
||||
if(!tthread->proc->nohost)
|
||||
interrupt_syscall(tthread, 0);
|
||||
|
||||
if (status != PS_RUNNING) {
|
||||
if(sig == SIGKILL){
|
||||
/* Wake up the target only when stopped by ptrace-reporting */
|
||||
@ -1451,8 +1570,9 @@ SYSCALL_DECLARE(mmap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((flags & MAP_FIXED) && ((addr < region->user_start)
|
||||
|| (region->user_end <= addr))) {
|
||||
if (addr < region->user_start
|
||||
|| region->user_end <= addr
|
||||
|| len > (region->user_end - region->user_start)) {
|
||||
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n",
|
||||
addr0, len0, prot, flags0, fd, off0);
|
||||
error = -ENOMEM;
|
||||
@ -1486,6 +1606,16 @@ SYSCALL_DECLARE(clone)
|
||||
ihk_mc_syscall_sp(ctx));
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(fork)
|
||||
{
|
||||
return do_fork(SIGCHLD, 0, 0, 0, 0, ihk_mc_syscall_pc(ctx), ihk_mc_syscall_sp(ctx));
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(vfork)
|
||||
{
|
||||
return do_fork(CLONE_VFORK|SIGCHLD, 0, 0, 0, 0, ihk_mc_syscall_pc(ctx), ihk_mc_syscall_sp(ctx));
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(shmget)
|
||||
{
|
||||
const key_t key = ihk_mc_syscall_arg0(ctx);
|
||||
@ -2540,4 +2670,14 @@ out:
|
||||
return mpsr->phase_ret;
|
||||
}
|
||||
|
||||
time_t time(void) {
|
||||
struct syscall_request sreq IHK_DMA_ALIGN;
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
time_t ret;
|
||||
sreq.number = __NR_time;
|
||||
sreq.args[0] = (uintptr_t)NULL;
|
||||
ret = (time_t)do_syscall(&sreq, ihk_mc_get_processor_id(), thread->proc->pid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*** End of File ***/
|
||||
|
||||
@ -35,7 +35,6 @@ error_exit() {
|
||||
;&
|
||||
tmp_mcos_created)
|
||||
if [ "$enable_mcoverlay" == "yes" ]; then
|
||||
umask $umask_old
|
||||
rm -rf /tmp/mcos
|
||||
fi
|
||||
;&
|
||||
@ -44,14 +43,11 @@ error_exit() {
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 1
|
||||
# Retun -EINVAL
|
||||
exit -22
|
||||
}
|
||||
fi
|
||||
|
||||
# Change umask for /proc and /sys files
|
||||
umask_dec=$(( 8#${umask_old} & 8#0002 ))
|
||||
umask 0`printf "%o" ${umask_dec}`
|
||||
|
||||
if [ ! -e /tmp/mcos ]; then
|
||||
mkdir -p /tmp/mcos;
|
||||
fi
|
||||
@ -150,6 +146,4 @@ for cpuid in `find /sys/bus/cpu/devices/* -maxdepth 0 -name "cpu[0123456789]*" -
|
||||
fi
|
||||
done
|
||||
|
||||
# Restore umask
|
||||
umask ${umask_old}
|
||||
|
||||
exit 0
|
||||
|
||||
@ -8,6 +8,9 @@ if grep mcoverlay /proc/modules &>/dev/null; then
|
||||
if [ -e /tmp/mcos ]; then rm -rf /tmp/mcos; fi
|
||||
if ! rmmod mcoverlay 2>/dev/null; then
|
||||
echo "error: removing mcoverlay" >&2
|
||||
exit 1
|
||||
# Return -EINVAL
|
||||
exit -22
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
# the same set of resources as it used previously.
|
||||
# Note that the script does not output anything unless an error occurs.
|
||||
|
||||
ret=1
|
||||
prefix="@prefix@"
|
||||
BINDIR="${prefix}/bin"
|
||||
SBINDIR="${prefix}/sbin"
|
||||
@ -19,6 +20,7 @@ ETCDIR=@ETCDIR@
|
||||
KMODDIR="${prefix}/kmod"
|
||||
KERNDIR="${prefix}/@TARGET@/kernel"
|
||||
ENABLE_MCOVERLAYFS="@ENABLE_MCOVERLAYFS@"
|
||||
MCK_BUILDID=@BUILDID@
|
||||
|
||||
mem="512M@0"
|
||||
cpus=""
|
||||
@ -44,8 +46,10 @@ fi
|
||||
turbo=""
|
||||
ihk_irq=""
|
||||
umask_old=`umask`
|
||||
idle_halt=""
|
||||
allow_oversubscribe=""
|
||||
|
||||
while getopts :tk:c:m:o:f:r:q:i:d:e: OPT
|
||||
while getopts :tk:c:m:o:f:r:q:i:d:e:hO OPT
|
||||
do
|
||||
case ${OPT} in
|
||||
f) facility=${OPTARG}
|
||||
@ -70,6 +74,10 @@ do
|
||||
;;
|
||||
i) mon_interval=${OPTARG}
|
||||
;;
|
||||
h) idle_halt="idle_halt"
|
||||
;;
|
||||
O) allow_oversubscribe="allow_oversubscribe"
|
||||
;;
|
||||
*) echo "invalid option -${OPT}" >&2
|
||||
exit 1
|
||||
esac
|
||||
@ -83,6 +91,16 @@ fi
|
||||
if [ "${redirect_kmsg}" != "0" -o "${mon_interval}" != "-1" ]; then
|
||||
${SBINDIR}/ihkmond -f ${facility} -k ${redirect_kmsg} -i ${mon_interval}
|
||||
fi
|
||||
|
||||
disable_irqbalance_mck() {
|
||||
if [ -f /etc/systemd/system/irqbalance_mck.service ]; then
|
||||
systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null
|
||||
|
||||
# Invalid .service file persists so remove it
|
||||
rm -f /etc/systemd/system/irqbalance_mck.service
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Revert any state that has been initialized before the error occured.
|
||||
#
|
||||
@ -90,6 +108,16 @@ error_exit() {
|
||||
local status=$1
|
||||
|
||||
case $status in
|
||||
irqbalance_mck_started)
|
||||
if [ "${irqbalance_used}" == "yes" ]; then
|
||||
if [ "`systemctl status irqbalance_mck.service 2> /dev/null |grep -E 'Active: active'`" != "" ]; then
|
||||
if ! systemctl stop irqbalance_mck.service 2>/dev/null; then
|
||||
echo "warning: failed to stop irqbalance_mck" >&2
|
||||
fi
|
||||
disable_irqbalance_mck
|
||||
fi
|
||||
fi
|
||||
;&
|
||||
mcos_sys_mounted)
|
||||
if [ "$enable_mcoverlay" == "yes" ]; then
|
||||
umount /tmp/mcos/mcos0_sys
|
||||
@ -117,7 +145,6 @@ error_exit() {
|
||||
;&
|
||||
tmp_mcos_created)
|
||||
if [ "$enable_mcoverlay" == "yes" ]; then
|
||||
umask $umask_old
|
||||
rm -rf /tmp/mcos
|
||||
fi
|
||||
;&
|
||||
@ -157,20 +184,20 @@ error_exit() {
|
||||
ihk_loaded)
|
||||
rmmod ihk 2>/dev/null || echo "warning: failed to remove ihk" >&2
|
||||
;&
|
||||
smp_affinity_modified)
|
||||
umask $umask_old
|
||||
if [ "${irqbalance_used}" == "yes" ]; then
|
||||
if ! perl -e '$tmpdir="/tmp/mcreboot"; @files = grep { -f } glob "$tmpdir/proc/irq/*/smp_affinity"; foreach $file (@files) { $dest = substr($file, length($tmpdir)); if (0) {print "cp $file $dest\n";} system("cp $file $dest 2>/dev/null"); }'; then
|
||||
echo "warning: failed to restore /proc/irq/*/smp_affinity" >&2
|
||||
fi
|
||||
if [ -e /tmp/mcreboot ]; then rm -rf /tmp/mcreboot; fi
|
||||
fi
|
||||
;&
|
||||
irqbalance_stopped)
|
||||
if [ "`systemctl status irqbalance_mck.service 2> /dev/null |grep -E 'Active: active'`" != "" ]; then
|
||||
if ! systemctl stop irqbalance_mck.service 2>/dev/null; then
|
||||
echo "warning: failed to stop irqbalance_mck" >&2
|
||||
fi
|
||||
if ! systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null; then
|
||||
echo "warning: failed to disable irqbalance_mck" >&2
|
||||
fi
|
||||
if ! etcdir=@ETCDIR@ perl -e '$etcdir=$ENV{'etcdir'}; @files = grep { -f } glob "$etcdir/proc/irq/*/smp_affinity"; foreach $file (@files) { $dest = substr($file, length($etcdir)); if(0) {print "cp $file $dest\n";} system("cp $file $dest 2>/dev/null"); }'; then
|
||||
echo "warning: failed to restore /proc/irq/*/smp_affinity" >&2
|
||||
fi
|
||||
if ! systemctl start irqbalance.service; then
|
||||
echo "warning: failed to start irqbalance" >&2;
|
||||
fi
|
||||
if [ "${irqbalance_used}" == "yes" ]; then
|
||||
if ! systemctl start irqbalance.service; then
|
||||
echo "warning: failed to start irqbalance" >&2;
|
||||
fi
|
||||
fi
|
||||
;&
|
||||
initial)
|
||||
@ -178,7 +205,8 @@ error_exit() {
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 1
|
||||
# Propagate exit status if any
|
||||
exit $ret
|
||||
}
|
||||
|
||||
ihk_ikc_irq_core=0
|
||||
@ -229,7 +257,11 @@ fi
|
||||
|
||||
# Remove mcoverlay if loaded
|
||||
if [ "$enable_mcoverlay" == "yes" ]; then
|
||||
. ${SBINDIR}/mcoverlay-destroy.sh
|
||||
${SBINDIR}/mcoverlay-destroy.sh
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
error_exit "initial"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Stop irqbalance
|
||||
@ -240,9 +272,9 @@ if [ "${irqbalance_used}" == "yes" ]; then
|
||||
exit 1
|
||||
fi;
|
||||
|
||||
if ! etcdir=@ETCDIR@ perl -e 'use File::Copy qw(copy); $etcdir=$ENV{'etcdir'}; @files = grep { -f } glob "/proc/irq/*/smp_affinity"; foreach $file (@files) { $rel = substr($file, 1); $dir=substr($rel, 0, length($rel)-length("/smp_affinity")); if(0) { print "cp $file $etcdir/$rel\n";} if(system("mkdir -p $etcdir/$dir")){ exit 1;} if(!copy($file,"$etcdir/$rel")){ exit 1;} }'; then
|
||||
if ! perl -e 'use File::Copy qw(copy); $tmpdir="/tmp/mcreboot"; @files = grep { -f } glob "/proc/irq/*/smp_affinity"; foreach $file (@files) { $rel = substr($file, 1); $dir = substr($rel, 0, length($rel) - length("/smp_affinity")); if (system("mkdir -p $tmpdir/$dir")) { exit 1; } if (0) { print "cp $file $tmpdir/$rel\n"; } if (!copy($file,"$tmpdir/$rel")) { exit 1; } }'; then
|
||||
echo "error: saving /proc/irq/*/smp_affinity" >&2
|
||||
error_exit "mcos_sys_mounted"
|
||||
error_exit "irqbalance_stopped"
|
||||
fi;
|
||||
|
||||
# Prevent /proc/irq/*/smp_affinity from getting zero after offlining
|
||||
@ -256,16 +288,20 @@ if [ "${irqbalance_used}" == "yes" ]; then
|
||||
|
||||
if ! ncpus=$ncpus smp_affinity_mask=$smp_affinity_mask perl -e '@dirs = grep { -d } glob "/proc/irq/*"; foreach $dir (@dirs) { $hit = 0; $affinity_str = `cat $dir/smp_affinity`; chomp $affinity_str; @int32strs = split /,/, $affinity_str; @int32strs_mask=split /,/, $ENV{'smp_affinity_mask'}; for($i=0;$i <= $#int32strs_mask; $i++) { $int32strs_inv[$i] = sprintf("%08x",hex($int32strs_mask[$i])^0xffffffff); if($i == 0) { $len = int((($ENV{'ncpus'}%32)+3)/4); if($len != 0) { $int32strs_inv[$i] = substr($int32strs_inv[$i], -$len, $len); } } } $inv = join(",", @int32strs_inv); $nint32s = int(($ENV{'ncpus'}+31)/32); for($j = $nint32s - 1; $j >= 0; $j--) { if(hex($int32strs[$nint32s - 1 - $j]) & hex($int32strs_mask[$nint32s - 1 - $j])) { $hit = 1; }} if($hit == 1) { $cmd = "echo $inv > $dir/smp_affinity 2>/dev/null"; system $cmd;}}'; then
|
||||
echo "error: modifying /proc/irq/*/smp_affinity" >&2
|
||||
error_exit "mcos_sys_mounted"
|
||||
error_exit "irqbalance_stopped"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Set umask so that proc/sys files/directories created by
|
||||
# mcctrl.ko and mcreboot.sh have appropriate permission bits
|
||||
umask_dec=$(( 8#${umask_old} & 8#0002 ))
|
||||
umask 0`printf "%o" ${umask_dec}`
|
||||
|
||||
# Load IHK if not loaded
|
||||
if ! grep -E 'ihk\s' /proc/modules &>/dev/null; then
|
||||
if ! taskset -c 0 insmod ${KMODDIR}/ihk.ko 2>/dev/null; then
|
||||
echo "error: loading ihk" >&2
|
||||
error_exit "irqbalance_stopped"
|
||||
error_exit "smp_affinity_modified"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -299,7 +335,7 @@ if ! grep ihk_smp_@ARCH@ /proc/modules &>/dev/null; then
|
||||
error_exit "ihk_loaded"
|
||||
fi
|
||||
|
||||
# Offline-reonline RAM (special case for OFP SNC-4 mode)
|
||||
# Offline-reonline RAM (special case for OFP SNC-4 flat mode)
|
||||
if [ "`hostname | grep "c[0-9][0-9][0-9][0-9].ofp"`" != "" ] && [ "`cat /sys/devices/system/node/online`" == "0-7" ]; then
|
||||
for i in 0 1 2 3; do
|
||||
find /sys/devices/system/node/node$i/memory*/ -name "online" | while read f; do
|
||||
@ -313,6 +349,22 @@ if ! grep ihk_smp_@ARCH@ /proc/modules &>/dev/null; then
|
||||
find /sys/devices/system/node/node$i/memory*/ -name "online" | while read f; do
|
||||
echo 0 > $f 2>&1 > /dev/null;
|
||||
done
|
||||
done
|
||||
for i in 4 5 6 7; do
|
||||
find /sys/devices/system/node/node$i/memory*/ -name "online" | while read f; do
|
||||
echo 1 > $f 2>&1 > /dev/null;
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# Offline-reonline RAM (special case for OFP Quadrant flat mode)
|
||||
if [ "`hostname | grep "c[0-9][0-9][0-9][0-9].ofp"`" != "" ] && [ "`cat /sys/devices/system/node/online`" == "0-1" ]; then
|
||||
for i in 1; do
|
||||
find /sys/devices/system/node/node$i/memory*/ -name "online" | while read f; do
|
||||
echo 0 > $f 2>&1 > /dev/null;
|
||||
done
|
||||
done
|
||||
for i in 1; do
|
||||
find /sys/devices/system/node/node$i/memory*/ -name "online" | while read f; do
|
||||
echo 1 > $f 2>&1 > /dev/null;
|
||||
done
|
||||
@ -337,6 +389,13 @@ if ! grep mcctrl /proc/modules &>/dev/null; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check that different versions of binaries/scripts are not mixed
|
||||
IHK_BUILDID=`${SBINDIR}/ihkconfig 0 get buildid`
|
||||
if [ "${IHK_BUILDID}" != "${MCK_BUILDID}" ]; then
|
||||
echo "IHK build-id (${IHK_BUILDID}) didn't match McKernel build-id (${MCK_BUILDID})." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Destroy all LWK instances
|
||||
if ls /dev/mcos* 1>/dev/null 2>&1; then
|
||||
for i in /dev/mcos*; do
|
||||
@ -387,7 +446,7 @@ if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then
|
||||
fi
|
||||
|
||||
# Set kernel arguments
|
||||
if ! ${SBINDIR}/ihkosctl 0 kargs "hidos $turbo dump_level=${DUMP_LEVEL} $extra_kopts"; then
|
||||
if ! ${SBINDIR}/ihkosctl 0 kargs "hidos $turbo $idle_halt dump_level=${DUMP_LEVEL} $extra_kopts $allow_oversubscribe"; then
|
||||
echo "error: setting kernel arguments" >&2
|
||||
error_exit "os_created"
|
||||
fi
|
||||
@ -405,7 +464,11 @@ fi
|
||||
|
||||
# Overlay /proc, /sys with McKernel specific contents
|
||||
if [ "$enable_mcoverlay" == "yes" ]; then
|
||||
. ${SBINDIR}/mcoverlay-create.sh
|
||||
${SBINDIR}/mcoverlay-create.sh
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
error_exit "os_created"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start irqbalance with CPUs and IRQ for McKernel banned
|
||||
@ -413,7 +476,9 @@ if [ "${irqbalance_used}" == "yes" ]; then
|
||||
banirq=`cat /proc/interrupts| perl -e 'while(<>) { if(/^\s*(\d+).*IHK\-SMP\s*$/) {print $1;}}'`
|
||||
|
||||
sed "s/%mask%/$smp_affinity_mask/g" $ETCDIR/irqbalance_mck.in | sed "s/%banirq%/$banirq/g" > /tmp/irqbalance_mck
|
||||
systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null
|
||||
|
||||
disable_irqbalance_mck
|
||||
|
||||
if ! systemctl link $ETCDIR/irqbalance_mck.service >/dev/null 2>/dev/null; then
|
||||
echo "error: linking irqbalance_mck" >&2
|
||||
error_exit "mcos_sys_mounted"
|
||||
@ -426,4 +491,7 @@ if [ "${irqbalance_used}" == "yes" ]; then
|
||||
# echo cpus=$cpus ncpus=$ncpus banirq=$banirq
|
||||
fi
|
||||
|
||||
# Restore umask
|
||||
umask ${umask_old}
|
||||
|
||||
exit 0
|
||||
|
||||
@ -18,6 +18,15 @@ mem=""
|
||||
cpus=""
|
||||
irqbalance_used=""
|
||||
|
||||
disable_irqbalance_mck() {
|
||||
if [ -f /etc/systemd/system/irqbalance_mck.service ]; then
|
||||
systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null
|
||||
|
||||
# Invalid .service file persists so remove it
|
||||
rm -f /etc/systemd/system/irqbalance_mck.service
|
||||
fi
|
||||
}
|
||||
|
||||
# No SMP module? Exit.
|
||||
if ! grep ihk_smp_@ARCH@ /proc/modules &>/dev/null; then exit 0; fi
|
||||
|
||||
@ -26,9 +35,7 @@ if [ "`systemctl status irqbalance_mck.service 2> /dev/null |grep -E 'Active: ac
|
||||
if ! systemctl stop irqbalance_mck.service 2>/dev/null; then
|
||||
echo "warning: failed to stop irqbalance_mck" >&2
|
||||
fi
|
||||
if ! systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null; then
|
||||
echo "warning: failed to disable irqbalance_mck" >&2
|
||||
fi
|
||||
disable_irqbalance_mck
|
||||
fi
|
||||
|
||||
# Destroy all LWK instances
|
||||
@ -48,6 +55,9 @@ if ls /dev/mcos* 1>/dev/null 2>&1; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Allow ihkmond to flush kmsg buffer
|
||||
sleep 2.0
|
||||
|
||||
# Query IHK-SMP resources and release them
|
||||
if ! ${SBINDIR}/ihkconfig 0 query cpu > /dev/null; then
|
||||
echo "error: querying cpus" >&2
|
||||
@ -62,17 +72,23 @@ if [ "${cpus}" != "" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! ${SBINDIR}/ihkconfig 0 query mem > /dev/null; then
|
||||
echo "error: querying memory" >&2
|
||||
exit 1
|
||||
fi
|
||||
#if ! ${SBINDIR}/ihkconfig 0 query mem > /dev/null; then
|
||||
# echo "error: querying memory" >&2
|
||||
# exit 1
|
||||
#fi
|
||||
#
|
||||
#mem=`${SBINDIR}/ihkconfig 0 query mem`
|
||||
#if [ "${mem}" != "" ]; then
|
||||
# if ! ${SBINDIR}/ihkconfig 0 release mem $mem > /dev/null; then
|
||||
# echo "error: releasing memory" >&2
|
||||
# exit 1
|
||||
# fi
|
||||
#fi
|
||||
|
||||
mem=`${SBINDIR}/ihkconfig 0 query mem`
|
||||
if [ "${mem}" != "" ]; then
|
||||
if ! ${SBINDIR}/ihkconfig 0 release mem $mem > /dev/null; then
|
||||
echo "error: releasing memory" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Release all memory
|
||||
if ! ${SBINDIR}/ihkconfig 0 release mem "all" > /dev/null; then
|
||||
echo "error: releasing memory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove delegator if loaded
|
||||
@ -84,7 +100,13 @@ if grep mcctrl /proc/modules &>/dev/null; then
|
||||
fi
|
||||
|
||||
# Remove mcoverlay if loaded
|
||||
. ${SBINDIR}/mcoverlay-destroy.sh
|
||||
${SBINDIR}/mcoverlay-destroy.sh
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo "error: mcoverlay-destroy.sh" >&2
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
|
||||
# Remove SMP module
|
||||
if grep ihk_smp_@ARCH@ /proc/modules &>/dev/null; then
|
||||
@ -110,9 +132,10 @@ fi
|
||||
|
||||
# Start irqbalance with the original settings
|
||||
if [ "${irqbalance_used}" != "" ]; then
|
||||
if ! etcdir=@ETCDIR@ perl -e '$etcdir=$ENV{'etcdir'}; @files = grep { -f } glob "$etcdir/proc/irq/*/smp_affinity"; foreach $file (@files) { $dest = substr($file, length($etcdir)); if(0) {print "cp $file $dest\n";} system("cp $file $dest 2>/dev/null"); }'; then
|
||||
if ! perl -e '$tmpdir="/tmp/mcreboot"; @files = grep { -f } glob "$tmpdir/proc/irq/*/smp_affinity"; foreach $file (@files) { $dest = substr($file, length($tmpdir)); if (0) {print "cp $file $dest\n";} system("cp $file $dest 2>/dev/null"); }'; then
|
||||
echo "warning: failed to restore /proc/irq/*/smp_affinity" >&2
|
||||
fi
|
||||
if [ -e /tmp/mcreboot ]; then rm -rf /tmp/mcreboot; fi
|
||||
if ! systemctl start irqbalance.service; then
|
||||
echo "warning: failed to start irqbalance" >&2;
|
||||
fi
|
||||
|
||||
@ -3,21 +3,24 @@
|
||||
/* Path of install directory for binary */
|
||||
#undef BINDIR
|
||||
|
||||
/* IHK build-id to confirm IHK and McKernel built at the same time are used */
|
||||
#undef BUILDID
|
||||
|
||||
/* whether mcoverlayfs is enabled */
|
||||
#undef ENABLE_MCOVERLAYFS
|
||||
|
||||
/* whether memdump feature is enabled */
|
||||
#undef ENABLE_MEMDUMP
|
||||
|
||||
/* whether perf is enabled */
|
||||
#undef ENABLE_PERF
|
||||
|
||||
/* whether qlmpi is enabled */
|
||||
#undef ENABLE_QLMPI
|
||||
|
||||
/* whether rusage is enabled */
|
||||
#undef ENABLE_RUSAGE
|
||||
|
||||
/* whether perf is enabled */
|
||||
#undef ENABLE_PERF
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
|
||||
58
configure
vendored
58
configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for mckernel 0.9.0.
|
||||
# Generated by GNU Autoconf 2.69 for mckernel 1.5.1.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@ -577,8 +577,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='mckernel'
|
||||
PACKAGE_TARNAME='mckernel'
|
||||
PACKAGE_VERSION='0.9.0'
|
||||
PACKAGE_STRING='mckernel 0.9.0'
|
||||
PACKAGE_VERSION='1.5.1'
|
||||
PACKAGE_STRING='mckernel 1.5.1'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -645,6 +645,7 @@ TARGET
|
||||
UNAME_R
|
||||
KDIR
|
||||
ARCH
|
||||
BUILDID
|
||||
XCC
|
||||
FGREP
|
||||
EGREP
|
||||
@ -1261,7 +1262,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures mckernel 0.9.0 to adapt to many kinds of systems.
|
||||
\`configure' configures mckernel 1.5.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1322,7 +1323,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of mckernel 0.9.0:";;
|
||||
short | recursive ) echo "Configuration of mckernel 1.5.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1430,7 +1431,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
mckernel configure 0.9.0
|
||||
mckernel configure 1.5.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -1728,7 +1729,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by mckernel $as_me 0.9.0, which was
|
||||
It was created by mckernel $as_me 1.5.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -2081,12 +2082,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
|
||||
IHK_VERSION=0.9.0
|
||||
MCKERNEL_VERSION=0.9.0
|
||||
DCFA_VERSION=0.9.0
|
||||
IHK_RELEASE_DATE=2013-11-18
|
||||
MCKERNEL_RELEASE_DATE=2013-11-18
|
||||
DCFA_RELEASE_DATE=2013-11-18
|
||||
IHK_VERSION=1.5.1
|
||||
MCKERNEL_VERSION=1.5.1
|
||||
DCFA_VERSION=DCFA_VERSION_m4
|
||||
IHK_RELEASE_DATE=2018-07-09
|
||||
MCKERNEL_RELEASE_DATE=2018-07-09
|
||||
DCFA_RELEASE_DATE=DCFA_RELEASE_DATE_m4
|
||||
|
||||
|
||||
|
||||
@ -4285,7 +4286,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
builtin-mic)
|
||||
@ -4302,7 +4303,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/attached/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/attached/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
builtin-x86)
|
||||
@ -4319,7 +4320,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/attached/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
smp-x86)
|
||||
@ -4351,7 +4352,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/smp-x86/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
smp-arm64)
|
||||
@ -4383,7 +4384,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/smp-arm64/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
@ -5012,6 +5013,20 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
ABS_SRCDIR=$( cd $( dirname $0 ); pwd )
|
||||
IHK_ABS_SRCDIR=${ABS_SRCDIR}/../ihk
|
||||
BUILDID=$( cd $IHK_ABS_SRCDIR; if [ ! -d .git ]; then echo $IHK_VERSION; else bash -c 'git rev-list -1 HEAD | cut -c1-8'; fi )
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: BUILDID=$BUILDID" >&5
|
||||
$as_echo "$as_me: BUILDID=$BUILDID" >&6;}
|
||||
if test "x$BUILDID" != "x" ; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define BUILDID "$BUILDID"
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -5045,7 +5060,7 @@ ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
# POSTK_DEBUG_ARCH_DEP_37
|
||||
# AC_CONFIG_FILES arch dependfiles separate
|
||||
ac_config_files="$ac_config_files Makefile executer/user/Makefile executer/user/mcexec.1:executer/user/mcexec.1in executer/user/vmcore2mckdump executer/user/arch/$ARCH/Makefile executer/user/arch/x86_64/Makefile executer/kernel/mcctrl/Makefile executer/kernel/mcctrl/arch/$ARCH/Makefile executer/kernel/mcoverlayfs/Makefile executer/kernel/mcoverlayfs/linux-3.10.0-327.36.1.el7/Makefile executer/kernel/mcoverlayfs/linux-4.0.9/Makefile executer/kernel/mcoverlayfs/linux-4.6.7/Makefile executer/include/qlmpilib.h kernel/Makefile kernel/Makefile.build kernel/include/swapfmt.h arch/x86_64/tools/mcreboot-attached-mic.sh arch/x86_64/tools/mcshutdown-attached-mic.sh arch/x86_64/tools/mcreboot-builtin-x86.sh arch/x86_64/tools/mcreboot-smp-x86.sh arch/x86_64/tools/mcstop+release-smp-x86.sh arch/x86_64/tools/mcoverlay-destroy-smp-x86.sh arch/x86_64/tools/mcoverlay-create-smp-x86.sh arch/x86_64/tools/eclair-dump-backtrace.exp arch/x86_64/tools/mcshutdown-builtin-x86.sh arch/x86_64/tools/mcreboot.1:arch/x86_64/tools/mcreboot.1in arch/x86_64/tools/irqbalance_mck.service arch/x86_64/tools/irqbalance_mck.in"
|
||||
ac_config_files="$ac_config_files Makefile executer/user/Makefile executer/user/mcexec.1:executer/user/mcexec.1in executer/user/vmcore2mckdump executer/user/arch/$ARCH/Makefile executer/user/arch/x86_64/Makefile executer/kernel/mcctrl/Makefile executer/kernel/mcctrl/arch/$ARCH/Makefile executer/kernel/mcoverlayfs/Makefile executer/kernel/mcoverlayfs/linux-3.10.0-327.36.1.el7/Makefile executer/kernel/mcoverlayfs/linux-4.0.9/Makefile executer/kernel/mcoverlayfs/linux-4.6.7/Makefile executer/include/qlmpilib.h kernel/Makefile kernel/Makefile.build kernel/include/swapfmt.h arch/x86_64/tools/mcreboot-attached-mic.sh arch/x86_64/tools/mcshutdown-attached-mic.sh arch/x86_64/tools/mcreboot-builtin-x86.sh arch/x86_64/tools/mcreboot-smp-x86.sh arch/x86_64/tools/mcstop+release-smp-x86.sh arch/x86_64/tools/mcoverlay-destroy-smp-x86.sh arch/x86_64/tools/mcoverlay-create-smp-x86.sh arch/x86_64/tools/eclair-dump-backtrace.exp arch/x86_64/tools/mcshutdown-builtin-x86.sh arch/x86_64/tools/mcreboot.1:arch/x86_64/tools/mcreboot.1in arch/x86_64/tools/irqbalance_mck.service arch/x86_64/tools/irqbalance_mck.in tools/mcstat/Makefile"
|
||||
|
||||
|
||||
if test "$TARGET" = "smp-x86"; then
|
||||
@ -5570,7 +5585,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by mckernel $as_me 0.9.0, which was
|
||||
This file was extended by mckernel $as_me 1.5.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -5632,7 +5647,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
mckernel config.status 0.9.0
|
||||
mckernel config.status 1.5.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@ -5782,6 +5797,7 @@ do
|
||||
"arch/x86_64/tools/mcreboot.1") CONFIG_FILES="$CONFIG_FILES arch/x86_64/tools/mcreboot.1:arch/x86_64/tools/mcreboot.1in" ;;
|
||||
"arch/x86_64/tools/irqbalance_mck.service") CONFIG_FILES="$CONFIG_FILES arch/x86_64/tools/irqbalance_mck.service" ;;
|
||||
"arch/x86_64/tools/irqbalance_mck.in") CONFIG_FILES="$CONFIG_FILES arch/x86_64/tools/irqbalance_mck.in" ;;
|
||||
"tools/mcstat/Makefile") CONFIG_FILES="$CONFIG_FILES tools/mcstat/Makefile" ;;
|
||||
"arch/x86_64/kernel/Makefile.arch") CONFIG_FILES="$CONFIG_FILES arch/x86_64/kernel/Makefile.arch" ;;
|
||||
"kernel/config/config.smp-arm64") CONFIG_FILES="$CONFIG_FILES kernel/config/config.smp-arm64" ;;
|
||||
"arch/arm64/kernel/vdso/Makefile") CONFIG_FILES="$CONFIG_FILES arch/arm64/kernel/vdso/Makefile" ;;
|
||||
|
||||
30
configure.ac
30
configure.ac
@ -1,11 +1,9 @@
|
||||
# configure.ac COPYRIGHT FUJITSU LIMITED 2015-2016
|
||||
AC_PREREQ(2.63)
|
||||
m4_define([IHK_VERSION_m4],[0.9.0])dnl
|
||||
m4_define([MCKERNEL_VERSION_m4],[0.9.0])dnl
|
||||
m4_define([DCFA_VERSION_m4],[0.9.0])dnl
|
||||
m4_define([IHK_RELEASE_DATE_m4],[2013-11-18])dnl
|
||||
m4_define([MCKERNEL_RELEASE_DATE_m4],[2013-11-18])dnl
|
||||
m4_define([DCFA_RELEASE_DATE_m4],[2013-11-18])dnl
|
||||
m4_define([IHK_VERSION_m4],[1.5.1])dnl
|
||||
m4_define([MCKERNEL_VERSION_m4],[1.5.1])dnl
|
||||
m4_define([IHK_RELEASE_DATE_m4],[2018-07-09])dnl
|
||||
m4_define([MCKERNEL_RELEASE_DATE_m4],[2018-07-09])dnl
|
||||
|
||||
AC_INIT([mckernel], MCKERNEL_VERSION_m4)
|
||||
|
||||
@ -231,7 +229,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
builtin-mic)
|
||||
@ -248,7 +246,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/attached/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/attached/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
builtin-x86)
|
||||
@ -265,7 +263,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/attached/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
smp-x86)
|
||||
@ -297,7 +295,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/smp-x86/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
smp-arm64)
|
||||
@ -329,7 +327,7 @@ case $WITH_TARGET in
|
||||
KMODDIR="$prefix/kmod"
|
||||
fi
|
||||
if test "X$MANDIR" = X; then
|
||||
MANDIR="$prefix/smp-arm64/man"
|
||||
MANDIR="$prefix/share/man"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
@ -502,6 +500,15 @@ fi
|
||||
AC_DEFINE_UNQUOTED(BINDIR,"$BINDIR",[Path of install directory for binary])
|
||||
AC_DEFINE_UNQUOTED(SBINDIR,"$SBINDIR",[Path of install directory for system binary])
|
||||
|
||||
ABS_SRCDIR=$( cd $( dirname $0 ); pwd )
|
||||
IHK_ABS_SRCDIR=${ABS_SRCDIR}/../ihk
|
||||
BUILDID=$( cd $IHK_ABS_SRCDIR; if @<:@ ! -d .git @:>@; then echo $IHK_VERSION; else bash -c 'git rev-list -1 HEAD | cut -c1-8'; fi )
|
||||
AC_MSG_NOTICE([BUILDID=$BUILDID])
|
||||
if test "x$BUILDID" != "x" ; then
|
||||
AC_DEFINE_UNQUOTED(BUILDID,"$BUILDID",[IHK build-id to confirm IHK and McKernel built at the same time are used])
|
||||
fi
|
||||
AC_SUBST(BUILDID)
|
||||
|
||||
AC_SUBST(CC)
|
||||
AC_SUBST(XCC)
|
||||
AC_SUBST(ARCH)
|
||||
@ -563,6 +570,7 @@ AC_CONFIG_FILES([
|
||||
arch/x86_64/tools/mcreboot.1:arch/x86_64/tools/mcreboot.1in
|
||||
arch/x86_64/tools/irqbalance_mck.service
|
||||
arch/x86_64/tools/irqbalance_mck.in
|
||||
tools/mcstat/Makefile
|
||||
])
|
||||
|
||||
if test "$TARGET" = "smp-x86"; then
|
||||
|
||||
@ -111,10 +111,8 @@ typedef unsigned long __cpu_set_unit;
|
||||
|
||||
struct program_load_desc {
|
||||
int num_sections;
|
||||
int status;
|
||||
int cpu;
|
||||
int pid;
|
||||
int err;
|
||||
int stack_prot;
|
||||
int pgid;
|
||||
int cred[8];
|
||||
@ -253,7 +251,6 @@ enum perf_ctrl_type {
|
||||
|
||||
struct perf_ctrl_desc {
|
||||
enum perf_ctrl_type ctrl_type;
|
||||
int status;
|
||||
union {
|
||||
/* for SET, GET */
|
||||
struct {
|
||||
|
||||
@ -9,7 +9,6 @@ IHK_BASE=$(src)/../../../../ihk
|
||||
|
||||
obj-m += mcctrl.o
|
||||
|
||||
# POSTK_DEBUG_ARCH_DEP_1, arch depend "-mcmodel"
|
||||
# POSTK_DEBUG_ARCH_DEP_83, arch depend translate_rva_to_rpa() move
|
||||
ccflags-y := -I$(IHK_BASE)/linux/include \
|
||||
-I$(IHK_BASE)/linux/include/ihk/arch/$(ARCH) \
|
||||
@ -24,9 +23,8 @@ ccflags-y := -I$(IHK_BASE)/linux/include \
|
||||
-I$(src)/../../../kernel/include \
|
||||
-DMCEXEC_PATH=\"$(BINDIR)/mcexec\"
|
||||
|
||||
ifneq ($(ARCH), arm64)
|
||||
ccflags-y += -mno-red-zone -mcmodel=kernel
|
||||
endif
|
||||
# depending arch
|
||||
include @abs_builddir@/arch/$(ARCH)/Makefile
|
||||
|
||||
mcctrl-y := driver.o control.o ikc.o syscall.o procfs.o binfmt_mcexec.o
|
||||
mcctrl-y += sysfs.o sysfs_files.o arch/$(ARCH)/archdeps.o
|
||||
|
||||
@ -1 +1 @@
|
||||
# dummy file
|
||||
ccflags-y += -mno-red-zone -mcmodel=kernel
|
||||
|
||||
@ -327,6 +327,14 @@ int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
|
||||
pgsize = 1UL << offsh;
|
||||
rpa = pt[ix] & ((1UL << 52) - 1) & ~(pgsize - 1);
|
||||
rpa |= rva & (pgsize - 1);
|
||||
|
||||
/* For GB pages, just report regular 2MB page */
|
||||
if (offsh == 30) {
|
||||
pgsize = 1UL << 21;
|
||||
dprintk("%s: GB page translated 0x%lx -> 0x%lx, pgsize: %lu\n",
|
||||
__FUNCTION__, rva, rpa, pgsize);
|
||||
}
|
||||
|
||||
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
|
||||
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
|
||||
error = 0;
|
||||
|
||||
@ -107,6 +107,7 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_per_proc_data *ppd = NULL;
|
||||
int num_sections;
|
||||
int free_ikc_pointers = 1;
|
||||
|
||||
desc = kmalloc(sizeof(*desc), GFP_KERNEL);
|
||||
if (!desc) {
|
||||
@ -140,9 +141,9 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
pdesc = kmalloc(sizeof(struct program_load_desc) +
|
||||
sizeof(struct program_image_section)
|
||||
* num_sections, GFP_KERNEL);
|
||||
pdesc = kmalloc(sizeof(struct program_load_desc) +
|
||||
sizeof(struct program_image_section) * num_sections,
|
||||
GFP_KERNEL);
|
||||
memcpy(pdesc, desc, sizeof(struct program_load_desc));
|
||||
|
||||
if (copy_from_user(pdesc->sections, udesc->sections,
|
||||
@ -167,10 +168,10 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
ret = -EFAULT;
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
|
||||
envs = kmalloc(pdesc->envs_len, GFP_KERNEL);
|
||||
if (copy_from_user(envs, pdesc->envs, pdesc->envs_len)) {
|
||||
ret = -EFAULT;
|
||||
ret = -EFAULT;
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
@ -187,36 +188,24 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
|
||||
dprintk("# of sections: %d\n", pdesc->num_sections);
|
||||
dprintk("%p (%lx)\n", pdesc, isp.arg);
|
||||
|
||||
pdesc->status = 0;
|
||||
mb();
|
||||
ret = mcctrl_ikc_send(os, pdesc->cpu, &isp);
|
||||
if(ret < 0) {
|
||||
printk("%s: ERROR mcctrl_ikc_send: %d\n", __FUNCTION__, ret);
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(ppd->wq_prepare, pdesc->status);
|
||||
ret = mcctrl_ikc_send_wait(os, pdesc->cpu, &isp, 0, NULL,
|
||||
&free_ikc_pointers, 3, pdesc, args, envs);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
if (pdesc->err < 0) {
|
||||
ret = pdesc->err;
|
||||
/* either send or remote prepare_process failed */
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
/* Update rpgtable */
|
||||
ppd->rpgtable = pdesc->rpgtable;
|
||||
|
||||
if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) +
|
||||
|
||||
if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) +
|
||||
sizeof(struct program_image_section) * num_sections)) {
|
||||
ret = -EFAULT;
|
||||
ret = -EFAULT;
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
dprintk("%s: pid %d, rpgtable: 0x%lx added\n",
|
||||
dprintk("%s: pid %d, rpgtable: 0x%lx added\n",
|
||||
__FUNCTION__, ppd->pid, ppd->rpgtable);
|
||||
|
||||
ret = 0;
|
||||
@ -224,10 +213,12 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
put_and_free_out:
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
free_out:
|
||||
kfree(args);
|
||||
kfree(pdesc);
|
||||
kfree(envs);
|
||||
kfree(desc);
|
||||
if (free_ikc_pointers) {
|
||||
kfree(args);
|
||||
kfree(pdesc);
|
||||
kfree(envs);
|
||||
kfree(desc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -367,7 +358,7 @@ static long mcexec_debug_log(ihk_os_t os, unsigned long arg)
|
||||
}
|
||||
|
||||
int mcexec_close_exec(ihk_os_t os);
|
||||
int mcexec_destroy_per_process_data(ihk_os_t os);
|
||||
int mcexec_destroy_per_process_data(ihk_os_t os, int pid);
|
||||
|
||||
static void release_handler(ihk_os_t os, void *param)
|
||||
{
|
||||
@ -387,7 +378,7 @@ static void release_handler(ihk_os_t os, void *param)
|
||||
|
||||
mcexec_close_exec(os);
|
||||
|
||||
mcexec_destroy_per_process_data(os);
|
||||
mcexec_destroy_per_process_data(os, info->pid);
|
||||
|
||||
memset(&isp, '\0', sizeof isp);
|
||||
isp.msg = SCD_MSG_CLEANUP_PROCESS;
|
||||
@ -435,6 +426,7 @@ static long mcexec_start_image(ihk_os_t os,
|
||||
struct mcctrl_channel *c;
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcos_handler_info *info;
|
||||
int ret = 0;
|
||||
|
||||
desc = kmalloc(sizeof(*desc), GFP_KERNEL);
|
||||
if (!desc) {
|
||||
@ -445,17 +437,18 @@ static long mcexec_start_image(ihk_os_t os,
|
||||
|
||||
if (copy_from_user(desc, udesc,
|
||||
sizeof(struct program_load_desc))) {
|
||||
kfree(desc);
|
||||
return -EFAULT;
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
info = new_mcos_handler_info(os, file);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_64 /* host process is SIGKILLed fix. */
|
||||
if (info == NULL) {
|
||||
kfree(desc);
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_64 */
|
||||
|
||||
info->pid = desc->pid;
|
||||
info->cpu = desc->cpu;
|
||||
ihk_os_register_release_handler(file, release_handler, info);
|
||||
@ -471,33 +464,45 @@ static long mcexec_start_image(ihk_os_t os,
|
||||
isp.ref = desc->cpu;
|
||||
isp.arg = desc->rprocess;
|
||||
|
||||
mcctrl_ikc_send(os, desc->cpu, &isp);
|
||||
ret = mcctrl_ikc_send(os, desc->cpu, &isp);
|
||||
if (ret < 0) {
|
||||
printk("%s: error: sending IKC msg\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(desc);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(signalq);
|
||||
|
||||
struct mcctrl_signal_desc {
|
||||
struct mcctrl_signal msig;
|
||||
struct mcctrl_wakeup_desc wakeup;
|
||||
void *addrs[1];
|
||||
};
|
||||
|
||||
static long mcexec_send_signal(ihk_os_t os, struct signal_desc *sigparam)
|
||||
{
|
||||
struct ikc_scd_packet isp;
|
||||
struct mcctrl_channel *c;
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct signal_desc sig;
|
||||
struct mcctrl_signal msig[2];
|
||||
struct mcctrl_signal_desc *desc;
|
||||
struct mcctrl_signal *msigp;
|
||||
int rc;
|
||||
int rc, do_free;
|
||||
|
||||
if (copy_from_user(&sig, sigparam, sizeof(struct signal_desc))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
msigp = msig;
|
||||
if(((unsigned long)msig & 0xfffffffffffff000L) !=
|
||||
((unsigned long)(msig + 1) & 0xfffffffffffff000L))
|
||||
msigp++;
|
||||
memset(msigp, '\0', sizeof msig);
|
||||
desc = kmalloc(sizeof(*desc), GFP_KERNEL);
|
||||
if (!desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
msigp = &desc->msig;
|
||||
memset(msigp, '\0', sizeof(*msigp));
|
||||
msigp->sig = sig.sig;
|
||||
msigp->pid = sig.pid;
|
||||
msigp->tid = sig.tid;
|
||||
@ -509,25 +514,19 @@ static long mcexec_send_signal(ihk_os_t os, struct signal_desc *sigparam)
|
||||
isp.pid = sig.pid;
|
||||
isp.arg = virt_to_phys(msigp);
|
||||
|
||||
if ((rc = mcctrl_ikc_send(os, sig.cpu, &isp)) < 0) {
|
||||
rc = mcctrl_ikc_send_wait(os, sig.cpu, &isp, 0, &desc->wakeup,
|
||||
&do_free, 1, desc);
|
||||
if (rc < 0) {
|
||||
printk("mcexec_send_signal: mcctrl_ikc_send ret=%d\n", rc);
|
||||
if (do_free)
|
||||
kfree(desc);
|
||||
return rc;
|
||||
}
|
||||
wait_event_interruptible(signalq, msigp->cond != 0);
|
||||
|
||||
kfree(desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sig_done(unsigned long arg, int err)
|
||||
{
|
||||
struct mcctrl_signal *msigp;
|
||||
|
||||
msigp = phys_to_virt(arg);
|
||||
msigp->cond = 1;
|
||||
wake_up_interruptible(&signalq);
|
||||
}
|
||||
|
||||
static long mcexec_get_cpu(ihk_os_t os)
|
||||
{
|
||||
struct ihk_cpu_info *info;
|
||||
@ -632,6 +631,7 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
|
||||
|
||||
pli->task = current;
|
||||
pli->ready = 0;
|
||||
pli->timeout = 0;
|
||||
init_waitqueue_head(&pli->pli_wq);
|
||||
|
||||
pli_next = NULL;
|
||||
@ -693,11 +693,50 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
|
||||
dprintk("%s: pid: %d, waiting in list\n",
|
||||
__FUNCTION__, task_tgid_vnr(current));
|
||||
mutex_unlock(&pe->lock);
|
||||
ret = wait_event_interruptible(pli->pli_wq, pli->ready);
|
||||
/* Timeout period: 10 secs + (#procs * 0.1sec) */
|
||||
ret = wait_event_interruptible_timeout(pli->pli_wq,
|
||||
pli->ready,
|
||||
msecs_to_jiffies(10000 + req.nr_processes * 100));
|
||||
mutex_lock(&pe->lock);
|
||||
if (ret != 0) {
|
||||
|
||||
/* First timeout task? Wake up everyone else,
|
||||
* but tell them we timed out */
|
||||
if (ret == 0) {
|
||||
printk("%s: error: pid: %d, timed out, waking everyone\n",
|
||||
__FUNCTION__, task_tgid_vnr(current));
|
||||
while (!list_empty(&pe->pli_list)) {
|
||||
pli_next = list_first_entry(&pe->pli_list,
|
||||
struct process_list_item, list);
|
||||
list_del(&pli_next->list);
|
||||
pli_next->ready = 1;
|
||||
pli_next->timeout = 1;
|
||||
wake_up_interruptible(&pli_next->pli_wq);
|
||||
}
|
||||
|
||||
/* Reset process counter to start state */
|
||||
pe->nr_processes = -1;
|
||||
ret = -ETIMEDOUT;
|
||||
goto put_and_unlock_out;
|
||||
}
|
||||
|
||||
/* Interrupted or woken up by someone else due to time out? */
|
||||
if (ret < 0 || pli->timeout) {
|
||||
if (ret > 0) {
|
||||
printk("%s: error: pid: %d, job startup timed out\n",
|
||||
__FUNCTION__, task_tgid_vnr(current));
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
goto put_and_unlock_out;
|
||||
}
|
||||
|
||||
/* Incorrect wakeup state? */
|
||||
if (!pli->ready) {
|
||||
printk("%s: error: pid: %d, not ready but woken?\n",
|
||||
__FUNCTION__, task_tgid_vnr(current));
|
||||
ret = -EINVAL;
|
||||
goto put_and_unlock_out;
|
||||
}
|
||||
|
||||
dprintk("%s: pid: %d, woken up\n",
|
||||
__FUNCTION__, task_tgid_vnr(current));
|
||||
}
|
||||
@ -1201,8 +1240,8 @@ retry_alloc:
|
||||
|
||||
wqhln->packet = packet;
|
||||
wqhln->req = 1;
|
||||
ihk_ikc_spinlock_unlock(&ppd->wq_list_lock, flags);
|
||||
wake_up(&wqhln->wq_syscall);
|
||||
ihk_ikc_spinlock_unlock(&ppd->wq_list_lock, flags);
|
||||
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
|
||||
@ -1344,7 +1383,6 @@ retry_alloc:
|
||||
goto put_ppd_out;
|
||||
}
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_46 /* user area direct access fix. */
|
||||
if (copy_to_user(&req->cpu, &packet->ref, sizeof(req->cpu))) {
|
||||
if (mcctrl_delete_per_thread_data(ppd, current) < 0) {
|
||||
kprintf("%s: error deleting per-thread data\n", __FUNCTION__);
|
||||
@ -1352,9 +1390,6 @@ retry_alloc:
|
||||
ret = -EINVAL;
|
||||
goto put_ppd_out;
|
||||
}
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_46 */
|
||||
req->cpu = packet->ref;
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_46 */
|
||||
|
||||
ret = 0;
|
||||
goto put_ppd_out;
|
||||
@ -1649,7 +1684,6 @@ int mcexec_create_per_process_data(ihk_os_t os)
|
||||
INIT_LIST_HEAD(&ppd->wq_list);
|
||||
INIT_LIST_HEAD(&ppd->wq_req_list);
|
||||
INIT_LIST_HEAD(&ppd->wq_list_exact);
|
||||
init_waitqueue_head(&ppd->wq_prepare);
|
||||
init_waitqueue_head(&ppd->wq_procfs);
|
||||
spin_lock_init(&ppd->wq_list_lock);
|
||||
memset(&ppd->cpu_set, 0, sizeof(cpumask_t));
|
||||
@ -1680,12 +1714,12 @@ int mcexec_create_per_process_data(ihk_os_t os)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mcexec_destroy_per_process_data(ihk_os_t os)
|
||||
int mcexec_destroy_per_process_data(ihk_os_t os, int pid)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_per_proc_data *ppd = NULL;
|
||||
|
||||
ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(current));
|
||||
ppd = mcctrl_get_per_proc_data(usrdata, pid);
|
||||
|
||||
if (ppd) {
|
||||
/* One for the reference and one for deallocation.
|
||||
@ -1977,58 +2011,65 @@ long mcctrl_perf_num(ihk_os_t os, unsigned long arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mcctrl_perf_ctrl_desc {
|
||||
struct perf_ctrl_desc desc;
|
||||
struct mcctrl_wakeup_desc wakeup;
|
||||
void *addrs[1];
|
||||
};
|
||||
#define wakeup_desc_of_perf_desc(_desc) \
|
||||
(&container_of((_desc), struct mcctrl_perf_ctrl_desc, desc)->wakeup)
|
||||
|
||||
long mcctrl_perf_set(ihk_os_t os, struct ihk_perf_event_attr *__user arg)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct perf_ctrl_desc *perf_desc = NULL;
|
||||
struct perf_ctrl_desc *perf_desc;
|
||||
struct ihk_perf_event_attr attr;
|
||||
struct ihk_cpu_info *info = ihk_os_get_cpu_info(os);
|
||||
int ret = 0;
|
||||
int i = 0, j = 0;
|
||||
int need_free;
|
||||
|
||||
for (i = 0; i < usrdata->perf_event_num; i++) {
|
||||
if (copy_from_user(&attr, &arg[i], sizeof(struct ihk_perf_event_attr))) {
|
||||
printk("%s: error: copying ihk_perf_event_attr from user\n",
|
||||
__FUNCTION__);
|
||||
ret = copy_from_user(&attr, &arg[i],
|
||||
sizeof(struct ihk_perf_event_attr));
|
||||
if (ret) {
|
||||
pr_err("%s: error: copying ihk_perf_event_attr from user\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
printk("%s: error: allocating perf_ctrl_desc\n",
|
||||
__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_SET;
|
||||
perf_desc->status = 0;
|
||||
perf_desc->target_cntr = i;
|
||||
perf_desc->config = attr.config;
|
||||
perf_desc->exclude_kernel = attr.exclude_kernel;
|
||||
perf_desc->exclude_user = attr.exclude_user;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) {
|
||||
printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(perfctrlq, perf_desc->status);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kfree(perf_desc);
|
||||
perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc),
|
||||
GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_SET;
|
||||
perf_desc->target_cntr = i;
|
||||
perf_desc->config = attr.config;
|
||||
perf_desc->exclude_kernel = attr.exclude_kernel;
|
||||
perf_desc->exclude_user = attr.exclude_user;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
ret = mcctrl_ikc_send_wait(os, j, &isp, 0,
|
||||
wakeup_desc_of_perf_desc(perf_desc),
|
||||
&need_free, 1, perf_desc);
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n",
|
||||
__func__, ret);
|
||||
if (need_free)
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(perf_desc);
|
||||
}
|
||||
|
||||
return usrdata->perf_event_num;
|
||||
@ -2038,48 +2079,46 @@ long mcctrl_perf_get(ihk_os_t os, unsigned long *__user arg)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct perf_ctrl_desc *perf_desc = NULL;
|
||||
struct perf_ctrl_desc *perf_desc;
|
||||
struct ihk_cpu_info *info = ihk_os_get_cpu_info(os);
|
||||
unsigned long value_sum = 0;
|
||||
int ret = 0;
|
||||
int i = 0, j = 0;
|
||||
int need_free;
|
||||
|
||||
for (i = 0; i < usrdata->perf_event_num; i++) {
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
printk("%s: error: allocating perf_ctrl_desc\n",
|
||||
__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_GET;
|
||||
perf_desc->status = 0;
|
||||
perf_desc->target_cntr = i;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) {
|
||||
printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(perfctrlq, perf_desc->status);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
value_sum += perf_desc->read_value;
|
||||
kfree(perf_desc);
|
||||
perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc),
|
||||
GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_GET;
|
||||
perf_desc->target_cntr = i;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
ret = mcctrl_ikc_send_wait(os, j, &isp, 0,
|
||||
wakeup_desc_of_perf_desc(perf_desc),
|
||||
&need_free, 1, perf_desc);
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n",
|
||||
__func__, ret);
|
||||
if (need_free)
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
value_sum += perf_desc->read_value;
|
||||
}
|
||||
kfree(perf_desc);
|
||||
if (copy_to_user(&arg[i], &value_sum, sizeof(unsigned long))) {
|
||||
printk("%s: error: copying read_value to user\n",
|
||||
__FUNCTION__);
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
value_sum = 0;
|
||||
@ -2092,46 +2131,44 @@ long mcctrl_perf_enable(ihk_os_t os)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct perf_ctrl_desc *perf_desc = NULL;
|
||||
struct perf_ctrl_desc *perf_desc;
|
||||
struct ihk_cpu_info *info = ihk_os_get_cpu_info(os);
|
||||
unsigned int cntr_mask = 0;
|
||||
int ret = 0;
|
||||
int i = 0, j = 0;
|
||||
int need_free;
|
||||
|
||||
for (i = 0; i < usrdata->perf_event_num; i++) {
|
||||
cntr_mask |= 1 << i;
|
||||
}
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
printk("%s: error: allocating perf_ctrl_desc\n",
|
||||
__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_ENABLE;
|
||||
perf_desc->status = 0;
|
||||
perf_desc->target_cntr_mask = cntr_mask;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) {
|
||||
printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(perfctrlq, perf_desc->status);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
kfree(perf_desc);
|
||||
perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_ENABLE;
|
||||
perf_desc->target_cntr_mask = cntr_mask;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
ret = mcctrl_ikc_send_wait(os, j, &isp, 0,
|
||||
wakeup_desc_of_perf_desc(perf_desc),
|
||||
&need_free, 1, perf_desc);
|
||||
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n",
|
||||
__func__, ret);
|
||||
if (need_free)
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
}
|
||||
kfree(perf_desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2140,46 +2177,43 @@ long mcctrl_perf_disable(ihk_os_t os)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct perf_ctrl_desc *perf_desc = NULL;
|
||||
struct perf_ctrl_desc *perf_desc;
|
||||
struct ihk_cpu_info *info = ihk_os_get_cpu_info(os);
|
||||
unsigned int cntr_mask = 0;
|
||||
int ret = 0;
|
||||
int i = 0, j = 0;
|
||||
int need_free;
|
||||
|
||||
for (i = 0; i < usrdata->perf_event_num; i++) {
|
||||
cntr_mask |= 1 << i;
|
||||
}
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
printk("%s: error: allocating perf_ctrl_desc\n",
|
||||
__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_DISABLE;
|
||||
perf_desc->status = 0;
|
||||
perf_desc->target_cntr_mask = cntr_mask;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) {
|
||||
printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(perfctrlq, perf_desc->status);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
kfree(perf_desc);
|
||||
perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_DISABLE;
|
||||
perf_desc->target_cntr_mask = cntr_mask;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
ret = mcctrl_ikc_send_wait(os, j, &isp, 0,
|
||||
wakeup_desc_of_perf_desc(perf_desc),
|
||||
&need_free, 1, perf_desc);
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n",
|
||||
__func__, ret);
|
||||
if (need_free)
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
}
|
||||
kfree(perf_desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2191,15 +2225,6 @@ long mcctrl_perf_destroy(ihk_os_t os)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mcctrl_perf_ack(ihk_os_t os, struct ikc_scd_packet *packet)
|
||||
{
|
||||
struct perf_ctrl_desc *perf_desc = phys_to_virt(packet->arg);
|
||||
|
||||
perf_desc->status = 1;
|
||||
wake_up_interruptible(&perfctrlq);
|
||||
|
||||
}
|
||||
|
||||
/* Compose LWK-specific rusage structure */
|
||||
long mcctrl_getrusage(ihk_os_t ihk_os, struct mcctrl_ioctl_getrusage_desc *__user _desc)
|
||||
{
|
||||
@ -2431,7 +2456,9 @@ mcexec_terminate_thread(ihk_os_t os, unsigned long *param, struct file *file)
|
||||
mcctrl_delete_per_thread_data(ppd, tsk);
|
||||
__return_syscall(usrdata->os, packet, param[2], tid);
|
||||
ihk_ikc_release_packet((struct ihk_ikc_free_packet *)packet,
|
||||
(usrdata->channels + packet->ref)->c);
|
||||
(usrdata->ikc2linux[smp_processor_id()] ?
|
||||
usrdata->ikc2linux[smp_processor_id()] :
|
||||
usrdata->ikc2linux[0]));
|
||||
err:
|
||||
if(ppd)
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
@ -2881,28 +2908,6 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void mcexec_prepare_ack(ihk_os_t os, unsigned long arg, int err)
|
||||
{
|
||||
struct program_load_desc *desc = phys_to_virt(arg);
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_per_proc_data *ppd = NULL;
|
||||
|
||||
ppd = mcctrl_get_per_proc_data(usrdata, desc->pid);
|
||||
if (!ppd) {
|
||||
printk("%s: ERROR: no per process data for PID %d\n",
|
||||
__FUNCTION__, desc->pid);
|
||||
return;
|
||||
}
|
||||
|
||||
desc->err = err;
|
||||
desc->status = 1;
|
||||
mb();
|
||||
|
||||
wake_up_all(&ppd->wq_prepare);
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
}
|
||||
|
||||
|
||||
/* Per-CPU register manipulation functions */
|
||||
struct mcctrl_os_cpu_response {
|
||||
int done;
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
#include "mcctrl.h"
|
||||
#include <ihk/ihk_host_user.h>
|
||||
|
||||
@ -169,6 +170,14 @@ error_cleanup_channels:
|
||||
int mcctrl_os_shutdown_notifier(int os_index)
|
||||
{
|
||||
if (os[os_index]) {
|
||||
/* Wait for os running */
|
||||
if (ihk_os_wait_for_status(os[os_index], IHK_OS_STATUS_RUNNING, 0, 200) != 0) {
|
||||
printk("IHK: OS does not become RUNNING in shutdown. Force shutdown.\n");
|
||||
/* send nmi to force shutdown */
|
||||
ihk_os_send_nmi(os[os_index], 3);
|
||||
mdelay(200);
|
||||
}
|
||||
|
||||
sysfsm_cleanup(os[os_index]);
|
||||
free_topology_info(os[os_index]);
|
||||
ihk_os_unregister_user_call_handlers(os[os_index], mcctrl_uc + os_index);
|
||||
|
||||
@ -49,15 +49,123 @@
|
||||
|
||||
//struct mcctrl_channel *channels;
|
||||
|
||||
void mcexec_prepare_ack(ihk_os_t os, unsigned long arg, int err);
|
||||
static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys, struct ihk_ikc_channel_desc *c);
|
||||
int mcexec_syscall(struct mcctrl_usrdata *ud, struct ikc_scd_packet *packet);
|
||||
void sig_done(unsigned long arg, int err);
|
||||
void mcctrl_perf_ack(ihk_os_t os, struct ikc_scd_packet *packet);
|
||||
void mcctrl_os_read_write_cpu_response(ihk_os_t os,
|
||||
struct ikc_scd_packet *pisp);
|
||||
void mcctrl_eventfd(ihk_os_t os, struct ikc_scd_packet *pisp);
|
||||
|
||||
/* Assumes usrdata->wakeup_descs_lock taken */
|
||||
static void mcctrl_wakeup_desc_cleanup(ihk_os_t os,
|
||||
struct mcctrl_wakeup_desc *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
list_del(&desc->chain);
|
||||
|
||||
for (i = 0; i < desc->free_addrs_count; i++) {
|
||||
kfree(desc->free_addrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void mcctrl_wakeup_cb(ihk_os_t os, struct ikc_scd_packet *packet)
|
||||
{
|
||||
struct mcctrl_wakeup_desc *desc = packet->reply;
|
||||
|
||||
|
||||
WRITE_ONCE(desc->err, packet->err);
|
||||
|
||||
/*
|
||||
* Check if the other side is still waiting, and signal it we're done.
|
||||
*
|
||||
* Setting status needs to be done last because the other side could
|
||||
* wake up opportunistically between this set and the wake_up call.
|
||||
*
|
||||
* If the other side is no longer waiting, free the memory that was
|
||||
* left for us.
|
||||
*/
|
||||
if (cmpxchg(&desc->status, 0, 1)) {
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&usrdata->wakeup_descs_lock, flags);
|
||||
mcctrl_wakeup_desc_cleanup(os, desc);
|
||||
spin_unlock_irqrestore(&usrdata->wakeup_descs_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
wake_up_interruptible(&desc->wq);
|
||||
}
|
||||
|
||||
int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp,
|
||||
long int timeout, struct mcctrl_wakeup_desc *desc,
|
||||
int *do_frees, int free_addrs_count, ...)
|
||||
{
|
||||
int ret, i;
|
||||
int alloc_desc = (desc == NULL);
|
||||
va_list ap;
|
||||
|
||||
if (free_addrs_count)
|
||||
*do_frees = 1;
|
||||
if (alloc_desc)
|
||||
desc = kmalloc(sizeof(struct mcctrl_wakeup_desc) +
|
||||
(free_addrs_count + 1) * sizeof(void *),
|
||||
GFP_KERNEL);
|
||||
if (!desc) {
|
||||
pr_warn("%s: Could not allocate wakeup descriptor", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
pisp->reply = desc;
|
||||
va_start(ap, free_addrs_count);
|
||||
for (i = 0; i < free_addrs_count; i++) {
|
||||
desc->free_addrs[i] = va_arg(ap, void*);
|
||||
}
|
||||
va_end(ap);
|
||||
if (alloc_desc)
|
||||
desc->free_addrs[free_addrs_count++] = desc;
|
||||
desc->free_addrs_count = free_addrs_count;
|
||||
init_waitqueue_head(&desc->wq);
|
||||
WRITE_ONCE(desc->err, 0);
|
||||
WRITE_ONCE(desc->status, 0);
|
||||
|
||||
ret = mcctrl_ikc_send(os, cpu, pisp);
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send failed: %d\n", __func__, ret);
|
||||
kfree(desc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
ret = wait_event_interruptible_timeout(desc->wq,
|
||||
desc->status, timeout);
|
||||
} else {
|
||||
ret = wait_event_interruptible(desc->wq, desc->status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if wait aborted (signal..) or timed out, and notify
|
||||
* the callback it will need to free things for us
|
||||
*/
|
||||
if (!cmpxchg(&desc->status, 0, 1)) {
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&usrdata->wakeup_descs_lock, flags);
|
||||
list_add(&desc->chain, &usrdata->wakeup_descs_list);
|
||||
spin_unlock_irqrestore(&usrdata->wakeup_descs_lock, flags);
|
||||
if (free_addrs_count)
|
||||
*do_frees = 0;
|
||||
return ret < 0 ? ret : -ETIME;
|
||||
}
|
||||
|
||||
ret = READ_ONCE(desc->err);
|
||||
if (alloc_desc)
|
||||
kfree(desc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* XXX: this runs in atomic context! */
|
||||
static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
void *__packet, void *__os)
|
||||
@ -72,11 +180,9 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
break;
|
||||
|
||||
case SCD_MSG_PREPARE_PROCESS_ACKED:
|
||||
mcexec_prepare_ack(__os, pisp->arg, 0);
|
||||
break;
|
||||
|
||||
case SCD_MSG_PREPARE_PROCESS_NACKED:
|
||||
mcexec_prepare_ack(__os, pisp->arg, pisp->err);
|
||||
case SCD_MSG_PERF_ACK:
|
||||
case SCD_MSG_SEND_SIGNAL_ACK:
|
||||
mcctrl_wakeup_cb(__os, pisp);
|
||||
break;
|
||||
|
||||
case SCD_MSG_SYSCALL_ONESIDE:
|
||||
@ -87,9 +193,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
procfs_answer(usrdata, pisp->pid);
|
||||
break;
|
||||
|
||||
case SCD_MSG_SEND_SIGNAL:
|
||||
sig_done(pisp->arg, pisp->err);
|
||||
break;
|
||||
|
||||
case SCD_MSG_SYSFS_REQ_CREATE:
|
||||
case SCD_MSG_SYSFS_REQ_MKDIR:
|
||||
@ -113,10 +216,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
get_vdso_info(__os, pisp->arg);
|
||||
break;
|
||||
|
||||
case SCD_MSG_PERF_ACK:
|
||||
mcctrl_perf_ack(__os, pisp);
|
||||
break;
|
||||
|
||||
case SCD_MSG_CPU_RW_REG_RESP:
|
||||
mcctrl_os_read_write_cpu_response(__os, pisp);
|
||||
break;
|
||||
@ -157,10 +256,15 @@ static int dummy_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
|
||||
int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_usrdata *usrdata;
|
||||
|
||||
if (cpu < 0 || os == NULL || usrdata == NULL ||
|
||||
cpu >= usrdata->num_channels || !usrdata->channels[cpu].c) {
|
||||
if (cpu < 0 || os == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
usrdata = ihk_host_os_get_usrdata(os);
|
||||
if (usrdata == NULL || cpu >= usrdata->num_channels ||
|
||||
!usrdata->channels[cpu].c) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return ihk_ikc_send(usrdata->channels[cpu].c, pisp, 0);
|
||||
@ -354,6 +458,8 @@ int prepare_ikc_channels(ihk_os_t os)
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -375,7 +481,9 @@ void __destroy_ikc_channel(ihk_os_t os, struct mcctrl_channel *pmc)
|
||||
void destroy_ikc_channels(ihk_os_t os)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_wakeup_desc *mwd_entry, *mwd_next;
|
||||
|
||||
if (!usrdata) {
|
||||
printk("%s: WARNING: no mcctrl_usrdata found\n", __FUNCTION__);
|
||||
@ -395,6 +503,12 @@ void destroy_ikc_channels(ihk_os_t os)
|
||||
ihk_ikc_destroy_channel(usrdata->ikc2linux[i]);
|
||||
}
|
||||
}
|
||||
spin_lock_irqsave(&usrdata->wakeup_descs_lock, flags);
|
||||
list_for_each_entry_safe(mwd_entry, mwd_next,
|
||||
&usrdata->wakeup_descs_list, chain) {
|
||||
mcctrl_wakeup_desc_cleanup(os, mwd_entry);
|
||||
}
|
||||
spin_unlock_irqrestore(&usrdata->wakeup_descs_lock, flags);
|
||||
|
||||
kfree(usrdata->channels);
|
||||
kfree(usrdata->ikc2linux);
|
||||
|
||||
@ -48,7 +48,6 @@
|
||||
|
||||
#define SCD_MSG_PREPARE_PROCESS 0x1
|
||||
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
||||
#define SCD_MSG_PREPARE_PROCESS_NACKED 0x7
|
||||
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
||||
#define SCD_MSG_WAKE_UP_SYSCALL_THREAD 0x14
|
||||
|
||||
@ -56,7 +55,8 @@
|
||||
#define SCD_MSG_INIT_CHANNEL_ACKED 0x6
|
||||
|
||||
#define SCD_MSG_SYSCALL_ONESIDE 0x4
|
||||
#define SCD_MSG_SEND_SIGNAL 0x8
|
||||
#define SCD_MSG_SEND_SIGNAL 0x7
|
||||
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
|
||||
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
||||
#define SCD_MSG_GET_VDSO_INFO 0xa
|
||||
|
||||
@ -128,6 +128,7 @@ enum mcctrl_os_cpu_operation {
|
||||
struct ikc_scd_packet {
|
||||
int msg;
|
||||
int err;
|
||||
void *reply;
|
||||
union {
|
||||
/* for traditional SCD_MSG_* */
|
||||
struct {
|
||||
@ -163,9 +164,10 @@ struct ikc_scd_packet {
|
||||
int eventfd_type;
|
||||
};
|
||||
};
|
||||
char padding[12];
|
||||
char padding[8];
|
||||
};
|
||||
|
||||
|
||||
struct mcctrl_priv {
|
||||
ihk_os_t os;
|
||||
struct program_load_desc *desc;
|
||||
@ -231,7 +233,6 @@ struct mcctrl_per_proc_data {
|
||||
struct list_head wq_list_exact; /* These requests come from IKC IRQ handler targeting a particular thread */
|
||||
|
||||
ihk_spinlock_t wq_list_lock;
|
||||
wait_queue_head_t wq_prepare;
|
||||
wait_queue_head_t wq_procfs;
|
||||
|
||||
struct list_head per_thread_data_hash[MCCTRL_PER_THREAD_DATA_HASH_SIZE];
|
||||
@ -304,6 +305,7 @@ struct node_topology {
|
||||
|
||||
struct process_list_item {
|
||||
int ready;
|
||||
int timeout;
|
||||
struct task_struct *task;
|
||||
struct list_head list;
|
||||
wait_queue_head_t pli_wq;
|
||||
@ -341,6 +343,8 @@ struct mcctrl_usrdata {
|
||||
wait_queue_head_t wq_procfs;
|
||||
struct list_head per_proc_data_hash[MCCTRL_PER_PROC_DATA_HASH_SIZE];
|
||||
rwlock_t per_proc_data_hash_lock[MCCTRL_PER_PROC_DATA_HASH_SIZE];
|
||||
struct list_head wakeup_descs_list;
|
||||
spinlock_t wakeup_descs_lock;
|
||||
|
||||
void **keys;
|
||||
struct sysfsm_data sysfsm_data;
|
||||
@ -366,6 +370,34 @@ int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp);
|
||||
int mcctrl_ikc_send_msg(ihk_os_t os, int cpu, int msg, int ref, unsigned long arg);
|
||||
int mcctrl_ikc_is_valid_thread(ihk_os_t os, int cpu);
|
||||
|
||||
struct mcctrl_wakeup_desc {
|
||||
int status;
|
||||
int err;
|
||||
wait_queue_head_t wq;
|
||||
struct list_head chain;
|
||||
int free_addrs_count;
|
||||
void *free_addrs[];
|
||||
};
|
||||
|
||||
/* ikc query-and-wait helper
|
||||
*
|
||||
* Arguments:
|
||||
* - os, cpu and pisp as per mcctl_ikc_send()
|
||||
* - timeout: time to wait for reply in ms
|
||||
* - desc: if set, memory area to be used for desc.
|
||||
* Care must be taken to leave room for variable-length array.
|
||||
* - do_free: returns bool that specify if the caller should free
|
||||
* its memory on error (e.g. if ikc_send failed in the first place,
|
||||
* the reply has no chance of coming and memory should be free)
|
||||
* Always true on success.
|
||||
* - free_addrs_count & ...: addresses to kmalloc'd pointers that
|
||||
* are referenced in the message and must be left intact if we
|
||||
* abort to timeout/signal.
|
||||
*/
|
||||
int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp,
|
||||
long int timeout, struct mcctrl_wakeup_desc *desc,
|
||||
int *do_frees, int free_addrs_count, ...);
|
||||
|
||||
ihk_os_t osnum_to_os(int n);
|
||||
|
||||
/* syscall.c */
|
||||
|
||||
@ -1019,7 +1019,8 @@ static const struct procfs_entry tid_entry_stuff[] = {
|
||||
|
||||
static const struct procfs_entry pid_entry_stuff[] = {
|
||||
PROC_REG("auxv", S_IRUSR, NULL),
|
||||
PROC_REG("cgroup", S_IXUSR, NULL),
|
||||
/* Support the case where McKernel process retrieves its job-id under the Fujitsu TCS suite. */
|
||||
// PROC_REG("cgroup", S_IXUSR, NULL),
|
||||
// PROC_REG("clear_refs", S_IWUSR, NULL),
|
||||
PROC_REG("cmdline", S_IRUGO, NULL),
|
||||
// PROC_REG("comm", S_IRUGO|S_IWUSR, NULL),
|
||||
|
||||
@ -222,6 +222,14 @@ int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
|
||||
pgsize = 1UL << offsh;
|
||||
rpa = pt[ix] & ((1UL << 52) - 1) & ~(pgsize - 1);
|
||||
rpa |= rva & (pgsize - 1);
|
||||
|
||||
/* For GB pages, just report regular 2MB page */
|
||||
if (offsh == 30) {
|
||||
pgsize = 1UL << 21;
|
||||
dprintk("%s: GB page translated 0x%lx -> 0x%lx, pgsize: %lu\n",
|
||||
__FUNCTION__, rva, rpa, pgsize);
|
||||
}
|
||||
|
||||
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
|
||||
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
|
||||
error = 0;
|
||||
@ -799,7 +807,7 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
|
||||
packet = (struct ikc_scd_packet *)mcctrl_get_per_thread_data(ppd, current);
|
||||
if (!packet) {
|
||||
error = -ENOENT;
|
||||
ret = VM_FAULT_SIGBUS;
|
||||
printk("%s: no packet registered for TID %d\n",
|
||||
__FUNCTION__, task_pid_vnr(current));
|
||||
goto put_and_out;
|
||||
@ -1174,6 +1182,7 @@ struct pager_create_result {
|
||||
int maxprot;
|
||||
uint32_t flags;
|
||||
size_t size;
|
||||
char path[PATH_MAX];
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -1192,6 +1201,33 @@ enum {
|
||||
MF_END
|
||||
};
|
||||
|
||||
static int pager_get_path(struct file *file, char *path) {
|
||||
int error = 0;
|
||||
char *pathbuf, *fullpath;
|
||||
|
||||
pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
|
||||
if (!pathbuf) {
|
||||
printk("%s: ERROR: allocating path\n", __FUNCTION__);
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fullpath = d_path(&file->f_path, pathbuf, PATH_MAX);
|
||||
if (!IS_ERR(fullpath)) {
|
||||
memcpy(path, fullpath, strlen(fullpath));
|
||||
}
|
||||
else {
|
||||
path[0] = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
if (pathbuf) {
|
||||
kfree(pathbuf);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa)
|
||||
{
|
||||
ihk_device_t dev = ihk_os_to_dev(os);
|
||||
@ -1286,7 +1322,10 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa)
|
||||
dprintk("%s: filename: %s, premap & zerofill\n",
|
||||
__FUNCTION__, fullpath);
|
||||
}
|
||||
else if (strstr(fullpath, "libmpi") != NULL) {
|
||||
else if (strstr(fullpath, "libmpi") ||
|
||||
strstr(fullpath, "libiomp") ||
|
||||
strstr(fullpath, "libpthread") ||
|
||||
strstr(fullpath, "libc.so")) {
|
||||
mf_flags = MF_PREFETCH;
|
||||
dprintk("%s: filename: %s, prefetch\n",
|
||||
__FUNCTION__, fullpath);
|
||||
@ -1325,6 +1364,7 @@ found:
|
||||
phys = ihk_device_map_memory(dev, result_pa, sizeof(*resp));
|
||||
resp = ihk_device_map_virtual(dev, phys, sizeof(*resp), NULL, 0);
|
||||
if (!resp) {
|
||||
ihk_device_unmap_memory(dev, phys, sizeof(*resp));
|
||||
printk("%s: ERROR: invalid response structure address\n",
|
||||
__FUNCTION__);
|
||||
error = -EINVAL;
|
||||
@ -1335,10 +1375,18 @@ found:
|
||||
resp->maxprot = maxprot;
|
||||
resp->flags = mf_flags;
|
||||
resp->size = st.size;
|
||||
|
||||
error = pager_get_path(file, resp->path);
|
||||
if (error) {
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
out_unmap:
|
||||
ihk_device_unmap_virtual(dev, resp, sizeof(*resp));
|
||||
ihk_device_unmap_memory(dev, phys, sizeof(*resp));
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
if (newpager) {
|
||||
kfree(newpager);
|
||||
@ -1570,6 +1618,7 @@ struct pager_map_result {
|
||||
uintptr_t handle;
|
||||
int maxprot;
|
||||
int8_t padding[4];
|
||||
char path[PATH_MAX];
|
||||
};
|
||||
|
||||
static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off,
|
||||
@ -1624,20 +1673,22 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off,
|
||||
maxprot |= PROT_EXEC;
|
||||
}
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
prot_and_flags = MAP_SHARED |
|
||||
(prot_and_flags & (MAP_POPULATE | MAP_LOCKED));
|
||||
|
||||
#define ANY_WHERE 0
|
||||
if (prot_and_flags & MAP_LOCKED) prot_and_flags |= MAP_POPULATE;
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
|
||||
va = do_mmap_pgoff(file, ANY_WHERE, len, maxprot,
|
||||
MAP_SHARED | (prot_and_flags & (MAP_POPULATE | MAP_LOCKED)), pgoff);
|
||||
#endif
|
||||
prot_and_flags, pgoff);
|
||||
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
|
||||
va = vm_mmap(file, ANY_WHERE, len, maxprot, MAP_SHARED |
|
||||
(prot_and_flags & (MAP_POPULATE | MAP_LOCKED)), pgoff << PAGE_SHIFT);
|
||||
#else
|
||||
va = vm_mmap(file, ANY_WHERE, len, maxprot,
|
||||
prot_and_flags, pgoff << PAGE_SHIFT);
|
||||
#endif
|
||||
|
||||
if (IS_ERR_VALUE(va)) {
|
||||
@ -1657,6 +1708,7 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off,
|
||||
phys = ihk_device_map_memory(dev, result_rpa, sizeof(*resp));
|
||||
resp = ihk_device_map_virtual(dev, phys, sizeof(*resp), NULL, 0);
|
||||
if (!resp) {
|
||||
ihk_device_unmap_memory(dev, phys, sizeof(*resp));
|
||||
printk("%s: ERROR: invalid response structure address\n",
|
||||
__FUNCTION__);
|
||||
error = -EINVAL;
|
||||
@ -1665,13 +1717,16 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off,
|
||||
|
||||
resp->handle = (uintptr_t)pager;
|
||||
resp->maxprot = maxprot;
|
||||
ihk_device_unmap_virtual(dev, resp, sizeof(*resp));
|
||||
ihk_device_unmap_memory(dev, phys, sizeof(*resp));
|
||||
|
||||
error = pager_get_path(file, resp->path);
|
||||
if (error) {
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
error = down_interruptible(&ppd->devobj_pager_lock);
|
||||
if (error) {
|
||||
error = -EINTR;
|
||||
goto out;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
list_add_tail(&pager->list, &ppd->devobj_pager_list);
|
||||
@ -1680,6 +1735,10 @@ static int pager_req_map(ihk_os_t os, int fd, size_t len, off_t off,
|
||||
pager = 0;
|
||||
error = 0;
|
||||
|
||||
out_unmap:
|
||||
ihk_device_unmap_virtual(dev, resp, sizeof(*resp));
|
||||
ihk_device_unmap_memory(dev, phys, sizeof(*resp));
|
||||
|
||||
out:
|
||||
if (file) {
|
||||
fput(file);
|
||||
@ -1854,6 +1913,7 @@ static int pager_req_unmap(ihk_os_t os, uintptr_t handle)
|
||||
kfree(pager);
|
||||
|
||||
out:
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ MCKERNEL_INCDIR=@MCKERNEL_INCDIR@
|
||||
MCKERNEL_LIBDIR=@MCKERNEL_LIBDIR@
|
||||
KDIR ?= @KDIR@
|
||||
ARCH=@ARCH@
|
||||
CFLAGS=-Wall -O -I. -I$(VPATH)/arch/${ARCH}
|
||||
CFLAGS=-Wall -O -I. -I$(VPATH)/arch/${ARCH} -I${IHKDIR} -I@abs_builddir@/../../../ihk/linux/include
|
||||
LDFLAGS=@LDFLAGS@
|
||||
RPATH=$(shell echo $(LDFLAGS)|awk '{for(i=1;i<=NF;i++){if($$i~/^-L/){w=$$i;sub(/^-L/,"-Wl,-rpath,",w);print w}}}')
|
||||
VPATH=@abs_srcdir@
|
||||
@ -19,7 +19,7 @@ TARGET=mcexec libsched_yield ldump2mcdump.so
|
||||
@uncomment_if_ENABLE_MEMDUMP@TARGET+=eclair
|
||||
LIBS=@LIBS@
|
||||
IHKDIR ?= $(VPATH)/../../../ihk/linux/include/
|
||||
MCEXEC_LIBS=-lmcexec -lrt -lnuma -pthread
|
||||
MCEXEC_LIBS=-lmcexec -lrt -lnuma -pthread -L@abs_builddir@/../../../ihk/linux/user -lihk -Wl,-rpath,$(MCKERNEL_LIBDIR)
|
||||
ENABLE_QLMPI=@ENABLE_QLMPI@
|
||||
|
||||
ifeq ($(ENABLE_QLMPI),yes)
|
||||
@ -40,7 +40,7 @@ mcexec: mcexec.c libmcexec.a
|
||||
# POSTK_DEBUG_ARCH_DEP_34, eclair arch depend separate.
|
||||
ifeq ($(ARCH), arm64)
|
||||
eclair: eclair.c arch/$(ARCH)/arch-eclair.c
|
||||
$(CC) -I.. -I. -I./arch/$(ARCH)/include -I$(VPATH)/.. -I$(VPATH) -I$(VPATH)/arch/$(ARCH)/include -I${IHKDIR} $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
$(CC) -I.. -I. -I./arch/$(ARCH)/include -I$(VPATH)/.. -I$(VPATH) -I$(VPATH)/arch/$(ARCH)/include $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
else
|
||||
eclair: eclair.c
|
||||
$(CC) $(CFLAGS) -I${IHKDIR} -o $@ $^ $(LIBS)
|
||||
@ -89,6 +89,7 @@ install::
|
||||
mkdir -p -m 755 $(MCKERNEL_LIBDIR)
|
||||
install -m 755 ldump2mcdump.so $(MCKERNEL_LIBDIR)
|
||||
install -m 755 libsched_yield.so.1.0.0 $(MCKERNEL_LIBDIR)
|
||||
mkdir -p -m 755 $(MANDIR)/man1
|
||||
install -m 644 mcexec.1 $(MANDIR)/man1/mcexec.1
|
||||
ifeq ($(ENABLE_QLMPI),yes)
|
||||
install -m 644 ../include/qlmpilib.h $(MCKERNEL_INCDIR)
|
||||
|
||||
@ -9,12 +9,15 @@ LIBS=@LIBS@
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
../../libmcexec.a: archdep.o
|
||||
$(AR) cr ../../libmcexec.a archdep.o
|
||||
../../libmcexec.a: archdep.o arch_syscall.o
|
||||
$(AR) cr ../../libmcexec.a archdep.o arch_syscall.o
|
||||
|
||||
archdep.o: archdep.S
|
||||
$(CC) -c -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) -fPIE -pie -pthread $<
|
||||
|
||||
arch_syscall.o: arch_syscall.c
|
||||
$(CC) -c -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) -fPIE -pie -pthread $<
|
||||
|
||||
clean:
|
||||
$(RM) $(TARGET) *.o
|
||||
|
||||
|
||||
7
executer/user/arch/arm64/arch_syscall.c
Normal file
7
executer/user/arch/arm64/arch_syscall.c
Normal file
@ -0,0 +1,7 @@
|
||||
struct syscall_wait_desc;
|
||||
|
||||
int
|
||||
archdep_syscall(struct syscall_wait_desc *w, long *ret)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -9,12 +9,15 @@ LIBS=@LIBS@
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
../../libmcexec.a: archdep.o
|
||||
$(AR) cr ../../libmcexec.a archdep.o
|
||||
../../libmcexec.a: archdep.o arch_syscall.o
|
||||
$(AR) cr ../../libmcexec.a archdep.o arch_syscall.o
|
||||
|
||||
archdep.o: archdep.S
|
||||
$(CC) -c -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) -fPIE -pie -pthread $<
|
||||
|
||||
arch_syscall.o: arch_syscall.c
|
||||
$(CC) -c -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) -fPIE -pie -pthread $<
|
||||
|
||||
clean:
|
||||
$(RM) $(TARGET) *.o
|
||||
|
||||
|
||||
63
executer/user/arch/x86_64/arch_syscall.c
Normal file
63
executer/user/arch/x86_64/arch_syscall.c
Normal file
@ -0,0 +1,63 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <elf.h>
|
||||
#include <dirent.h>
|
||||
#include "../../../include/uprotocol.h"
|
||||
#include "../../archdep.h"
|
||||
|
||||
//#define DEBUG
|
||||
#ifndef DEBUG
|
||||
#define __dprint(msg, ...)
|
||||
#define __dprintf(arg, ...)
|
||||
#define __eprint(msg, ...)
|
||||
#define __eprintf(format, ...)
|
||||
#else
|
||||
#define __dprint(msg, ...) {printf("%s: " msg, __FUNCTION__);fflush(stdout);}
|
||||
#define __dprintf(format, ...) {printf("%s: " format, __FUNCTION__, \
|
||||
__VA_ARGS__);fflush(stdout);}
|
||||
#define __eprint(msg, ...) {fprintf(stderr, "%s: " msg, __FUNCTION__);\
|
||||
fflush(stderr);}
|
||||
#define __eprintf(format, ...) {fprintf(stderr, "%s: " format, __FUNCTION__, \
|
||||
__VA_ARGS__);fflush(stderr);}
|
||||
#endif
|
||||
|
||||
extern char *chgpath(char *, char *);
|
||||
extern long do_strncpy_from_user(int, void *, void *, unsigned long);
|
||||
extern int fd;
|
||||
|
||||
#define SET_ERR(ret) if (ret == -1) ret = -errno
|
||||
|
||||
int
|
||||
archdep_syscall(struct syscall_wait_desc *w, long *ret)
|
||||
{
|
||||
char *fn;
|
||||
char pathbuf[PATH_MAX];
|
||||
char tmpbuf[PATH_MAX];
|
||||
|
||||
switch (w->sr.number) {
|
||||
case __NR_open:
|
||||
*ret = do_strncpy_from_user(fd, pathbuf,
|
||||
(void *)w->sr.args[0], PATH_MAX);
|
||||
if (*ret >= PATH_MAX) {
|
||||
*ret = -ENAMETOOLONG;
|
||||
}
|
||||
if (ret < 0) {
|
||||
return 0;
|
||||
}
|
||||
__dprintf("open: %s\n", pathbuf);
|
||||
|
||||
fn = chgpath(pathbuf, tmpbuf);
|
||||
|
||||
*ret = open(fn, w->sr.args[1], w->sr.args[2]);
|
||||
SET_ERR(*ret);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
extern int switch_ctx(int fd, unsigned long cmd, void **param, void *lctx, void *rctx);
|
||||
extern unsigned long compare_and_swap(unsigned long *addr, unsigned long old, unsigned long new);
|
||||
extern unsigned int compare_and_swap_int(unsigned int *addr, unsigned int old, unsigned int new);
|
||||
extern int archdep_syscall(struct syscall_wait_desc *w, long *ret);
|
||||
|
||||
@ -76,6 +76,7 @@
|
||||
#include <asm/prctl.h>
|
||||
#endif /* !POSTK_DEBUG_ARCH_DEP_77 */
|
||||
#include "../include/uprotocol.h"
|
||||
#include <ihk/ihk_host_user.h>
|
||||
#include <getopt.h>
|
||||
#include "archdep.h"
|
||||
#include "arch_args.h"
|
||||
@ -88,22 +89,24 @@
|
||||
#include <sys/un.h>
|
||||
#include "../include/pmi.h"
|
||||
#include "../include/qlmpi.h"
|
||||
#include <ihk/ihklib.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
//#define DEBUG
|
||||
#define ADD_ENVS_OPTION
|
||||
|
||||
#ifndef DEBUG
|
||||
#define __dprint(msg, ...)
|
||||
#define __dprint(msg)
|
||||
#define __dprintf(arg, ...)
|
||||
#define __eprint(msg, ...)
|
||||
#define __eprint(msg)
|
||||
#define __eprintf(format, ...)
|
||||
#else
|
||||
#define __dprint(msg, ...) {printf("%s: " msg, __FUNCTION__);fflush(stdout);}
|
||||
#define __dprintf(format, ...) {printf("%s: " format, __FUNCTION__, \
|
||||
__VA_ARGS__);fflush(stdout);}
|
||||
#define __eprint(msg, ...) {fprintf(stderr, "%s: " msg, __FUNCTION__);fflush(stderr);}
|
||||
#define __eprintf(format, ...) {fprintf(stderr, "%s: " format, __FUNCTION__, \
|
||||
__VA_ARGS__);fflush(stderr);}
|
||||
#define __dprint(msg) {printf("%s: " msg, __FUNCTION__);fflush(stdout);}
|
||||
#define __dprintf(format, args...) {printf("%s: " format, __FUNCTION__, \
|
||||
##args);fflush(stdout);}
|
||||
#define __eprint(msg) {fprintf(stderr, "%s: " msg, __FUNCTION__);fflush(stderr);}
|
||||
#define __eprintf(format, args...) {fprintf(stderr, "%s: " format, __FUNCTION__, \
|
||||
##args);fflush(stderr);}
|
||||
#endif
|
||||
|
||||
#define CHKANDJUMPF(cond, err, format, ...) \
|
||||
@ -148,17 +151,25 @@ char **__glob_argv = 0;
|
||||
|
||||
#ifdef ENABLE_MCOVERLAYFS
|
||||
#undef ENABLE_MCOVERLAYFS
|
||||
#ifndef RHEL_RELEASE_CODE
|
||||
|
||||
// RedHat?
|
||||
#ifdef RHEL_RELEASE_CODE
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,10,0)
|
||||
#define ENABLE_MCOVERLAYFS 1
|
||||
#else
|
||||
#error "ERROR: your Linux kernel version on RHEL is not supported"
|
||||
#endif // LINUX_VERSION_CODE <= KERNEL_VERSION(3,10,0)
|
||||
|
||||
// Other distro?
|
||||
#else
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) && LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
|
||||
#define ENABLE_MCOVERLAYFS 1
|
||||
#endif // LINUX_VERSION_CODE == 4.0
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
|
||||
#define ENABLE_MCOVERLAYFS 1
|
||||
#endif // LINUX_VERSION_CODE == 4.6
|
||||
#else
|
||||
#if RHEL_RELEASE_CODE <= RHEL_RELEASE_VERSION(7,3)
|
||||
#define ENABLE_MCOVERLAYFS 1
|
||||
#endif // RHEL_RELEASE_CODE <= 7.3
|
||||
|
||||
#endif // RHEL_RELEASE_CODE
|
||||
#endif // ENABLE_MCOVERLAYFS
|
||||
|
||||
@ -198,7 +209,7 @@ struct thread_data_s;
|
||||
int main_loop(struct thread_data_s *);
|
||||
|
||||
static int mcosid;
|
||||
static int fd;
|
||||
int fd;
|
||||
static char *exec_path = NULL;
|
||||
static char *altroot;
|
||||
static const char rlimit_stack_envname[] = "MCKERNEL_RLIMIT_STACK";
|
||||
@ -224,12 +235,13 @@ static int nr_processes = 0;
|
||||
static int nr_threads = -1;
|
||||
|
||||
struct fork_sync {
|
||||
pid_t pid;
|
||||
int status;
|
||||
volatile int success;
|
||||
sem_t sem;
|
||||
};
|
||||
|
||||
struct fork_sync_container {
|
||||
pid_t pid;
|
||||
struct fork_sync_container *next;
|
||||
struct fork_sync *fs;
|
||||
};
|
||||
@ -1011,6 +1023,89 @@ pid_t master_tid;
|
||||
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_barrier_t init_ready;
|
||||
|
||||
pthread_attr_t watchdog_thread_attr;
|
||||
pthread_t watchdog_thread;
|
||||
|
||||
/* Detects hang of McKernel */
|
||||
static void *watchdog_thread_func(void *arg) {
|
||||
int ret = 0;
|
||||
int evfd = -1;
|
||||
int epfd = -1;
|
||||
struct epoll_event event_in;
|
||||
struct epoll_event event_out;
|
||||
|
||||
if ((evfd = ihk_os_get_eventfd(0, IHK_OS_EVENTFD_TYPE_STATUS)) < 0) {
|
||||
fprintf(stderr, "%s: Error: geteventfd failed (%d)\n", __FUNCTION__, evfd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((epfd = epoll_create(1)) == -1) {
|
||||
fprintf(stderr, "%s: Error: epoll_create failed (%d)\n", __FUNCTION__, epfd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(&event_in, 0, sizeof(struct epoll_event));
|
||||
event_in.events = EPOLLIN;
|
||||
event_in.data.fd = evfd;
|
||||
if ((ret = epoll_ctl(epfd, EPOLL_CTL_ADD, evfd, &event_in)) != 0) {
|
||||
fprintf(stderr, "%s: Error: epoll_ctl failed (%d)\n", __FUNCTION__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
do {
|
||||
int nfd;
|
||||
uint64_t counter;
|
||||
ssize_t nread;
|
||||
|
||||
nfd = epoll_wait(epfd, &event_out, 1, -1);
|
||||
if (nfd == -1) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "%s: Error: epoll_wait failed (%s)\n", __FUNCTION__, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nfd == 0) {
|
||||
fprintf(stderr, "%s: Error: epoll_wait timed out unexpectedly\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nfd > 1) {
|
||||
fprintf(stderr, "%s: Error: Too many (%d) events\n", __FUNCTION__, nfd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (event_out.data.fd != evfd) {
|
||||
fprintf(stderr, "%s: Error: Unknown event (fd:%d)\n", __FUNCTION__, event_out.data.fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
nread = read(evfd, &counter, sizeof(counter));
|
||||
if (nread == 0) {
|
||||
fprintf(stderr, "%s: Error: read got EOF\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nread == -1) {
|
||||
fprintf(stderr, "%s: Error: read failed (%s)\n", __FUNCTION__, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
fprintf(stderr, "mcexec detected hang of McKernel\n");
|
||||
exit(EXIT_FAILURE);
|
||||
} while (1);
|
||||
|
||||
out:
|
||||
if (evfd != -1) {
|
||||
close(evfd);
|
||||
}
|
||||
if (epfd != -1) {
|
||||
close(epfd);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *main_loop_thread_func(void *arg)
|
||||
{
|
||||
struct thread_data_s *td = (struct thread_data_s *)arg;
|
||||
@ -1746,6 +1841,8 @@ static int
|
||||
opendev()
|
||||
{
|
||||
int f;
|
||||
char buildid[] = BUILDID;
|
||||
char query_result[sizeof(BUILDID)];
|
||||
|
||||
sprintf(dev, "/dev/mcos%d", mcosid);
|
||||
|
||||
@ -1757,6 +1854,18 @@ opendev()
|
||||
}
|
||||
fd = f;
|
||||
|
||||
if (ioctl(fd, IHK_OS_GET_BUILDID, query_result)) {
|
||||
fprintf(stderr, "Error: IHK_OS_GET_BUILDID failed");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(buildid, query_result, sizeof(buildid))) {
|
||||
fprintf(stderr, "Error: build-id of mcexec (%s) didn't match that of IHK (%s)\n", buildid, query_result);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
@ -1832,8 +1941,14 @@ int main(int argc, char **argv)
|
||||
altroot = "/usr/linux-k1om-4.7/linux-k1om";
|
||||
}
|
||||
|
||||
/* Disable address space layout randomization */
|
||||
/* Disable READ_IMPLIES_EXEC */
|
||||
persona = personality(0xffffffff);
|
||||
if (persona & READ_IMPLIES_EXEC) {
|
||||
persona &= ~READ_IMPLIES_EXEC;
|
||||
persona = personality(persona);
|
||||
}
|
||||
|
||||
/* Disable address space layout randomization */
|
||||
__dprintf("persona=%08x\n", persona);
|
||||
if ((persona & (PER_LINUX | ADDR_NO_RANDOMIZE)) == 0) {
|
||||
CHKANDJUMP(getenv("MCEXEC_ADDR_NO_RANDOMIZE"), 1, "personality() and then execv() failed\n");
|
||||
@ -2449,6 +2564,26 @@ int main(int argc, char **argv)
|
||||
|
||||
init_sigaction();
|
||||
|
||||
/* Initialize watchdog thread which detects hang of McKernel */
|
||||
|
||||
if ((error = pthread_attr_init(&watchdog_thread_attr))) {
|
||||
fprintf(stderr, "Error: pthread_attr_init failed (%d)\n", error);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((error = pthread_attr_setdetachstate(&watchdog_thread_attr, PTHREAD_CREATE_DETACHED))) {
|
||||
fprintf(stderr, "Error: pthread_attr_getdetachstate failed (%d)\n", error);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((error = pthread_create(&watchdog_thread, &watchdog_thread_attr, watchdog_thread_func, NULL))) {
|
||||
fprintf(stderr, "Error: pthread_create failed (%d)\n", error);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (init_worker_threads(fd) < 0) {
|
||||
perror("worker threads: ");
|
||||
close(fd);
|
||||
@ -2510,20 +2645,11 @@ do_generic_syscall(
|
||||
|
||||
__dprintf("do_generic_syscall(%ld)\n", w->sr.number);
|
||||
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_75 /* syscall return value check add. */
|
||||
ret = syscall(w->sr.number, w->sr.args[0], w->sr.args[1], w->sr.args[2],
|
||||
w->sr.args[3], w->sr.args[4], w->sr.args[5]);
|
||||
if (ret == -1) {
|
||||
ret = -errno;
|
||||
}
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_75 */
|
||||
errno = 0;
|
||||
ret = syscall(w->sr.number, w->sr.args[0], w->sr.args[1], w->sr.args[2],
|
||||
w->sr.args[3], w->sr.args[4], w->sr.args[5]);
|
||||
if (errno != 0) {
|
||||
ret = -errno;
|
||||
}
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_75 */
|
||||
|
||||
/* Overlayfs /sys/X directory lseek() problem work around */
|
||||
if (w->sr.number == __NR_lseek && ret == -EINVAL) {
|
||||
@ -2985,7 +3111,7 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long do_strncpy_from_user(int fd, void *dest, void *src, unsigned long n)
|
||||
long do_strncpy_from_user(int fd, void *dest, void *src, unsigned long n)
|
||||
{
|
||||
struct strncpy_from_user_desc desc;
|
||||
int ret;
|
||||
@ -3199,45 +3325,60 @@ int main_loop(struct thread_data_s *my_thread)
|
||||
my_thread->remote_cpu = w.cpu;
|
||||
|
||||
switch (w.sr.number) {
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_13 /* arch depend hide */
|
||||
#ifdef __aarch64__
|
||||
case __NR_openat:
|
||||
/* initialize buffer */
|
||||
memset(tmpbuf, '\0', sizeof(tmpbuf));
|
||||
memset(pathbuf, '\0', sizeof(pathbuf));
|
||||
|
||||
/* check argument 1 dirfd */
|
||||
if ((int)w.sr.args[0] != AT_FDCWD) {
|
||||
ret = do_strncpy_from_user(fd, pathbuf,
|
||||
(void *)w.sr.args[1],
|
||||
PATH_MAX);
|
||||
__dprintf("openat(dirfd == AT_FDCWD)\n");
|
||||
if (ret >= PATH_MAX) {
|
||||
ret = -ENAMETOOLONG;
|
||||
}
|
||||
if (ret < 0) {
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((int)w.sr.args[0] != AT_FDCWD &&
|
||||
pathbuf[0] != '/') {
|
||||
/* dirfd != AT_FDCWD */
|
||||
__dprintf("openat(dirfd != AT_FDCWD)\n");
|
||||
snprintf(tmpbuf, sizeof(tmpbuf), "/proc/self/fd/%d", (int)w.sr.args[0]);
|
||||
ret = readlink(tmpbuf, pathbuf, sizeof(pathbuf) - 1);
|
||||
snprintf(tmpbuf, sizeof(tmpbuf),
|
||||
"/proc/self/fd/%d", (int)w.sr.args[0]);
|
||||
ret = readlink(tmpbuf, pathbuf,
|
||||
sizeof(pathbuf) - 1);
|
||||
if (ret == -1 &&
|
||||
(errno == ENOENT ||
|
||||
errno == EINVAL)) {
|
||||
do_syscall_return(fd, cpu, -EBADF, 0, 0,
|
||||
0, 0);
|
||||
break;
|
||||
}
|
||||
if (ret < 0) {
|
||||
do_syscall_return(fd, cpu, -errno, 0, 0, 0, 0);
|
||||
do_syscall_return(fd, cpu, -errno, 0, 0,
|
||||
0, 0);
|
||||
break;
|
||||
}
|
||||
__dprintf(" %s -> %s\n", tmpbuf, pathbuf);
|
||||
ret = do_strncpy_from_user(fd, tmpbuf, (void *)w.sr.args[1], PATH_MAX);
|
||||
ret = do_strncpy_from_user(fd, tmpbuf,
|
||||
(void *)w.sr.args[1],
|
||||
PATH_MAX);
|
||||
if (ret >= PATH_MAX) {
|
||||
ret = -ENAMETOOLONG;
|
||||
}
|
||||
if (ret < 0) {
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0,
|
||||
0);
|
||||
break;
|
||||
}
|
||||
strncat(pathbuf, "/", 1);
|
||||
strncat(pathbuf, tmpbuf, strlen(tmpbuf) + 1);
|
||||
} else {
|
||||
/* dirfd == AT_FDCWD */
|
||||
__dprintf("openat(dirfd == AT_FDCWD)\n");
|
||||
ret = do_strncpy_from_user(fd, pathbuf, (void *)w.sr.args[1], PATH_MAX);
|
||||
if (ret >= PATH_MAX) {
|
||||
ret = -ENAMETOOLONG;
|
||||
}
|
||||
if (ret < 0) {
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
__dprintf("openat: %s\n", pathbuf);
|
||||
|
||||
@ -3247,44 +3388,6 @@ int main_loop(struct thread_data_s *my_thread)
|
||||
SET_ERR(ret);
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
#else /* __aarch64__ */
|
||||
case __NR_open:
|
||||
ret = do_strncpy_from_user(fd, pathbuf, (void *)w.sr.args[0], PATH_MAX);
|
||||
if (ret >= PATH_MAX) {
|
||||
ret = -ENAMETOOLONG;
|
||||
}
|
||||
if (ret < 0) {
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
__dprintf("open: %s\n", pathbuf);
|
||||
|
||||
fn = chgpath(pathbuf, tmpbuf);
|
||||
|
||||
ret = open(fn, w.sr.args[1], w.sr.args[2]);
|
||||
SET_ERR(ret);
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
#endif /* __aarch64__ */
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_13 */
|
||||
case __NR_open:
|
||||
ret = do_strncpy_from_user(fd, pathbuf, (void *)w.sr.args[0], PATH_MAX);
|
||||
if (ret >= PATH_MAX) {
|
||||
ret = -ENAMETOOLONG;
|
||||
}
|
||||
if (ret < 0) {
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
__dprintf("open: %s\n", pathbuf);
|
||||
|
||||
fn = chgpath(pathbuf, tmpbuf);
|
||||
|
||||
ret = open(fn, w.sr.args[1], w.sr.args[2]);
|
||||
SET_ERR(ret);
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_13 */
|
||||
|
||||
case __NR_futex:
|
||||
ret = clock_gettime(w.sr.args[1], &tv);
|
||||
@ -3405,74 +3508,58 @@ gettid_out:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_13 /* arch depend hide */
|
||||
case 1079: {
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_13 */
|
||||
case __NR_fork: {
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_13 */
|
||||
case __NR_clone: {
|
||||
struct fork_sync *fs;
|
||||
struct fork_sync_container *fsc;
|
||||
struct fork_sync_container *fsc = NULL;
|
||||
struct fork_sync_container *fp;
|
||||
struct fork_sync_container *fb;
|
||||
int flag = w.sr.args[0];
|
||||
int rc = -1;
|
||||
pid_t pid;
|
||||
|
||||
if (flag == 1) {
|
||||
pid = w.sr.args[1];
|
||||
rc = 0;
|
||||
pthread_mutex_lock(&fork_sync_mutex);
|
||||
for (fp = fork_sync_top, fb = NULL; fp; fb = fp, fp = fp->next)
|
||||
if (fp->pid == pid)
|
||||
break;
|
||||
if (fp) {
|
||||
fs = fp->fs;
|
||||
if (fb)
|
||||
fb->next = fp->next;
|
||||
else
|
||||
fork_sync_top = fp->next;
|
||||
fs->success = 1;
|
||||
munmap(fs, sizeof(struct fork_sync));
|
||||
free(fp);
|
||||
}
|
||||
pthread_mutex_unlock(&fork_sync_mutex);
|
||||
do_syscall_return(fd, cpu, rc, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
fs = mmap(NULL, sizeof(struct fork_sync),
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
if (fs == (void *)-1) {
|
||||
goto fork_err;
|
||||
}
|
||||
memset(fs, '\0', sizeof(struct fork_sync));
|
||||
sem_init(&fs->sem, 1, 0);
|
||||
|
||||
fsc = malloc(sizeof(struct fork_sync_container));
|
||||
if (!fsc) {
|
||||
goto fork_err;
|
||||
}
|
||||
memset(fsc, '\0', sizeof(struct fork_sync_container));
|
||||
pthread_mutex_lock(&fork_sync_mutex);
|
||||
fsc->next = fork_sync_top;
|
||||
fork_sync_top = fsc;
|
||||
pthread_mutex_unlock(&fork_sync_mutex);
|
||||
fsc->fs = fs = mmap(NULL, sizeof(struct fork_sync),
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
if(fs == (void *)-1){
|
||||
goto fork_err;
|
||||
}
|
||||
fsc->fs = fs;
|
||||
|
||||
memset(fs, '\0', sizeof(struct fork_sync));
|
||||
sem_init(&fs->sem, 1, 0);
|
||||
|
||||
if(flag){
|
||||
int pipefds[2];
|
||||
|
||||
if(pipe(pipefds) == -1){
|
||||
rc = -errno;
|
||||
sem_destroy(&fs->sem);
|
||||
goto fork_err;
|
||||
}
|
||||
pid = fork();
|
||||
if(pid == 0){
|
||||
close(pipefds[0]);
|
||||
pid = fork();
|
||||
if(pid != 0){
|
||||
if (write(pipefds[1], &pid, sizeof pid) != sizeof(pid)) {
|
||||
fprintf(stderr, "error: writing pipefds\n");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else if(pid != -1){
|
||||
int npid;
|
||||
int st;
|
||||
|
||||
close(pipefds[1]);
|
||||
if (read(pipefds[0], &npid, sizeof npid) != sizeof(npid)) {
|
||||
fprintf(stderr, "error: reading pipefds\n");
|
||||
}
|
||||
close(pipefds[0]);
|
||||
waitpid(pid, &st, 0);
|
||||
pid = npid;
|
||||
}
|
||||
else{
|
||||
rc = -errno;
|
||||
sem_destroy(&fs->sem);
|
||||
goto fork_err;
|
||||
}
|
||||
}
|
||||
else
|
||||
pid = fork();
|
||||
fsc->pid = pid = fork();
|
||||
|
||||
switch (pid) {
|
||||
/* Error */
|
||||
@ -3538,12 +3625,13 @@ gettid_out:
|
||||
|
||||
fork_child_sync_pipe:
|
||||
sem_post(&fs->sem);
|
||||
sem_destroy(&fs->sem);
|
||||
if (fs->status)
|
||||
exit(1);
|
||||
|
||||
for (fp = fork_sync_top; fp;) {
|
||||
fb = fp->next;
|
||||
if (fp->fs)
|
||||
if (fp->fs && fp->fs != fs)
|
||||
munmap(fp->fs, sizeof(struct fork_sync));
|
||||
free(fp);
|
||||
fp = fb;
|
||||
@ -3555,6 +3643,16 @@ fork_child_sync_pipe:
|
||||
ioctl(fd, MCEXEC_UP_NEW_PROCESS, &npdesc);
|
||||
|
||||
/* TODO: does the forked thread run in a pthread context? */
|
||||
while (getppid() != 1 &&
|
||||
fs->success == 0) {
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
if (fs->success == 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
munmap(fs, sizeof(struct fork_sync));
|
||||
join_all_threads();
|
||||
|
||||
return ret;
|
||||
@ -3562,7 +3660,6 @@ fork_child_sync_pipe:
|
||||
|
||||
/* Parent */
|
||||
default:
|
||||
fs->pid = pid;
|
||||
while ((rc = sem_trywait(&fs->sem)) == -1 && (errno == EAGAIN || errno == EINTR)) {
|
||||
int st;
|
||||
int wrc;
|
||||
@ -3585,20 +3682,25 @@ fork_child_sync_pipe:
|
||||
break;
|
||||
}
|
||||
|
||||
sem_destroy(&fs->sem);
|
||||
munmap(fs, sizeof(struct fork_sync));
|
||||
fork_err:
|
||||
pthread_mutex_lock(&fork_sync_mutex);
|
||||
for (fp = fork_sync_top, fb = NULL; fp; fb = fp, fp = fp->next)
|
||||
if (fp == fsc)
|
||||
break;
|
||||
if (fp) {
|
||||
if (fb)
|
||||
fb->next = fsc->next;
|
||||
else
|
||||
fork_sync_top = fsc->next;
|
||||
if (fs) {
|
||||
sem_destroy(&fs->sem);
|
||||
if (rc < 0) {
|
||||
munmap(fs, sizeof(struct fork_sync));
|
||||
pthread_mutex_lock(&fork_sync_mutex);
|
||||
for (fp = fork_sync_top, fb = NULL; fp; fb = fp, fp = fp->next)
|
||||
if (fp == fsc)
|
||||
break;
|
||||
if (fp) {
|
||||
if (fb)
|
||||
fb->next = fsc->next;
|
||||
else
|
||||
fork_sync_top = fsc->next;
|
||||
free(fp);
|
||||
}
|
||||
pthread_mutex_unlock(&fork_sync_mutex);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&fork_sync_mutex);
|
||||
do_syscall_return(fd, cpu, rc, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
@ -4277,7 +4379,9 @@ return_linux_spawn:
|
||||
}
|
||||
|
||||
default:
|
||||
ret = do_generic_syscall(&w);
|
||||
if (archdep_syscall(&w, &ret)) {
|
||||
ret = do_generic_syscall(&w);
|
||||
}
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
|
||||
|
||||
@ -136,6 +136,18 @@ int devobj_create(int fd, size_t len, off_t off, struct memobj **objp, int *maxp
|
||||
obj->memobj.flags = MF_HAS_PAGER | MF_DEV_FILE;
|
||||
obj->memobj.size = len;
|
||||
obj->handle = result.handle;
|
||||
|
||||
dkprintf("%s: path=%s\n", __FUNCTION__, result.path);
|
||||
if (result.path[0]) {
|
||||
obj->memobj.path = kmalloc(PATH_MAX, IHK_MC_AP_NOWAIT);
|
||||
if (!obj->memobj.path) {
|
||||
error = -ENOMEM;
|
||||
kprintf("%s: ERROR: Out of memory\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
strncpy(obj->memobj.path, result.path, PATH_MAX);
|
||||
}
|
||||
|
||||
obj->ref = 1;
|
||||
obj->pfn_pgoff = off / PAGE_SIZE;
|
||||
obj->npages = npages;
|
||||
@ -217,6 +229,11 @@ static void devobj_release(struct memobj *memobj)
|
||||
ihk_mc_free_pages(obj->pfn_table, pfn_npages);
|
||||
#endif /*POSTK_DEBUG_TEMP_FIX_36*/
|
||||
}
|
||||
|
||||
if (to_memobj(free_obj)->path) {
|
||||
kfree(to_memobj(free_obj)->path);
|
||||
}
|
||||
|
||||
kfree(free_obj);
|
||||
}
|
||||
|
||||
@ -225,7 +242,7 @@ static void devobj_release(struct memobj *memobj)
|
||||
return;
|
||||
}
|
||||
|
||||
static int devobj_get_page(struct memobj *memobj, off_t off, int p2align, uintptr_t *physp, unsigned long *flag)
|
||||
static int devobj_get_page(struct memobj *memobj, off_t off, int p2align, uintptr_t *physp, unsigned long *flag, uintptr_t virt_addr)
|
||||
{
|
||||
const off_t pgoff = off / PAGE_SIZE;
|
||||
struct devobj *obj = to_devobj(memobj);
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
#define ekprintf(...) kprintf(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
mcs_rwlock_lock_t fileobj_list_lock;
|
||||
mcs_lock_t fileobj_list_lock;
|
||||
static LIST_HEAD(fileobj_list);
|
||||
|
||||
#define FILEOBJ_PAGE_HASH_SHIFT 9
|
||||
@ -52,7 +52,7 @@ struct fileobj {
|
||||
uintptr_t handle;
|
||||
struct list_head list;
|
||||
struct list_head page_hash[FILEOBJ_PAGE_HASH_SIZE];
|
||||
mcs_rwlock_lock_t page_hash_locks[FILEOBJ_PAGE_HASH_SIZE];
|
||||
mcs_lock_t page_hash_locks[FILEOBJ_PAGE_HASH_SIZE];
|
||||
};
|
||||
|
||||
static memobj_release_func_t fileobj_release;
|
||||
@ -89,7 +89,7 @@ static void fileobj_page_hash_init(struct fileobj *obj)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < FILEOBJ_PAGE_HASH_SIZE; ++i) {
|
||||
mcs_rwlock_init(&obj->page_hash_locks[i]);
|
||||
mcs_lock_init(&obj->page_hash_locks[i]);
|
||||
INIT_LIST_HEAD(&obj->page_hash[i]);
|
||||
}
|
||||
return;
|
||||
@ -191,14 +191,14 @@ static struct fileobj *obj_list_lookup(uintptr_t handle)
|
||||
/***********************************************************************
|
||||
* fileobj
|
||||
*/
|
||||
int fileobj_create(int fd, struct memobj **objp, int *maxprotp)
|
||||
int fileobj_create(int fd, struct memobj **objp, int *maxprotp, uintptr_t virt_addr)
|
||||
{
|
||||
ihk_mc_user_context_t ctx;
|
||||
struct pager_create_result result __attribute__((aligned(64)));
|
||||
int error;
|
||||
struct fileobj *newobj = NULL;
|
||||
struct fileobj *obj;
|
||||
struct mcs_rwlock_node node;
|
||||
struct mcs_lock_node node;
|
||||
|
||||
dkprintf("fileobj_create(%d)\n", fd);
|
||||
newobj = kmalloc(sizeof(*newobj), IHK_MC_AP_NOWAIT);
|
||||
@ -223,12 +223,13 @@ int fileobj_create(int fd, struct memobj **objp, int *maxprotp)
|
||||
newobj->memobj.ops = &fileobj_ops;
|
||||
newobj->memobj.flags = MF_HAS_PAGER | MF_REG_FILE;
|
||||
newobj->handle = result.handle;
|
||||
|
||||
newobj->sref = 1;
|
||||
newobj->cref = 1;
|
||||
fileobj_page_hash_init(newobj);
|
||||
ihk_mc_spinlock_init(&newobj->memobj.lock);
|
||||
|
||||
mcs_rwlock_writer_lock_noirq(&fileobj_list_lock, &node);
|
||||
mcs_lock_lock_noirq(&fileobj_list_lock, &node);
|
||||
obj = obj_list_lookup(result.handle);
|
||||
if (!obj) {
|
||||
obj_list_insert(newobj);
|
||||
@ -240,6 +241,19 @@ int fileobj_create(int fd, struct memobj **objp, int *maxprotp)
|
||||
to_memobj(obj)->status = MEMOBJ_TO_BE_PREFETCHED;
|
||||
}
|
||||
|
||||
if (result.path[0]) {
|
||||
newobj->memobj.path = kmalloc(PATH_MAX, IHK_MC_AP_NOWAIT);
|
||||
if (!newobj->memobj.path) {
|
||||
error = -ENOMEM;
|
||||
kprintf("%s: error: allocating path\n", __FUNCTION__);
|
||||
mcs_lock_unlock_noirq(&fileobj_list_lock, &node);
|
||||
goto out;
|
||||
}
|
||||
strncpy(newobj->memobj.path, result.path, PATH_MAX);
|
||||
}
|
||||
|
||||
dkprintf("%s: %s\n", __FUNCTION__, obj->memobj.path);
|
||||
|
||||
/* XXX: KNL specific optimization for OFP runs */
|
||||
if ((to_memobj(obj)->flags & MF_PREMAP) &&
|
||||
(to_memobj(obj)->flags & MF_ZEROFILL)) {
|
||||
@ -265,7 +279,7 @@ int fileobj_create(int fd, struct memobj **objp, int *maxprotp)
|
||||
/* Get the actual pages NUMA interleaved */
|
||||
for (j = 0; j < nr_pages; ++j) {
|
||||
mo->pages[j] = ihk_mc_alloc_aligned_pages_node_user(1,
|
||||
PAGE_P2ALIGN, IHK_MC_AP_NOWAIT, node);
|
||||
PAGE_P2ALIGN, IHK_MC_AP_NOWAIT, node, virt_addr);
|
||||
if (!mo->pages[j]) {
|
||||
kprintf("%s: ERROR: allocating pages[%d]\n",
|
||||
__FUNCTION__, j);
|
||||
@ -308,7 +322,7 @@ error_cleanup:
|
||||
to_memobj(obj)->flags & MF_ZEROFILL ? "zerofill" : "");
|
||||
}
|
||||
|
||||
mcs_rwlock_writer_unlock_noirq(&fileobj_list_lock, &node);
|
||||
mcs_lock_unlock_noirq(&fileobj_list_lock, &node);
|
||||
|
||||
error = 0;
|
||||
*objp = to_memobj(obj);
|
||||
@ -339,7 +353,7 @@ static void fileobj_release(struct memobj *memobj)
|
||||
long free_sref = 0;
|
||||
uintptr_t free_handle;
|
||||
struct fileobj *free_obj = NULL;
|
||||
struct mcs_rwlock_node node;
|
||||
struct mcs_lock_node node;
|
||||
|
||||
dkprintf("fileobj_release(%p %lx)\n", obj, obj->handle);
|
||||
|
||||
@ -364,7 +378,7 @@ static void fileobj_release(struct memobj *memobj)
|
||||
obj->cref,
|
||||
free_obj,
|
||||
to_memobj(obj)->flags & MF_ZEROFILL ? "zerofill" : "");
|
||||
mcs_rwlock_writer_lock_noirq(&fileobj_list_lock, &node);
|
||||
mcs_lock_lock_noirq(&fileobj_list_lock, &node);
|
||||
/* zap page_list */
|
||||
for (;;) {
|
||||
struct page *page;
|
||||
@ -434,8 +448,13 @@ static void fileobj_release(struct memobj *memobj)
|
||||
kfree(to_memobj(free_obj)->pages);
|
||||
}
|
||||
|
||||
if (to_memobj(free_obj)->path) {
|
||||
dkprintf("%s: %s\n", __FUNCTION__, to_memobj(free_obj)->path);
|
||||
kfree(to_memobj(free_obj)->path);
|
||||
}
|
||||
|
||||
obj_list_remove(free_obj);
|
||||
mcs_rwlock_writer_unlock_noirq(&fileobj_list_lock, &node);
|
||||
mcs_lock_unlock_noirq(&fileobj_list_lock, &node);
|
||||
kfree(free_obj);
|
||||
}
|
||||
|
||||
@ -481,10 +500,10 @@ static void fileobj_do_pageio(void *args0)
|
||||
struct page *page;
|
||||
ihk_mc_user_context_t ctx;
|
||||
ssize_t ss;
|
||||
struct mcs_rwlock_node mcs_node;
|
||||
struct mcs_lock_node mcs_node;
|
||||
int hash = (off >> PAGE_SHIFT) & FILEOBJ_PAGE_HASH_MASK;
|
||||
|
||||
mcs_rwlock_writer_lock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
page = __fileobj_page_hash_lookup(obj, hash, off);
|
||||
if (!page) {
|
||||
@ -492,10 +511,10 @@ static void fileobj_do_pageio(void *args0)
|
||||
}
|
||||
|
||||
while (page->mode == PM_PAGEIO) {
|
||||
mcs_rwlock_writer_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
cpu_pause();
|
||||
mcs_rwlock_writer_lock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
}
|
||||
|
||||
@ -509,7 +528,7 @@ static void fileobj_do_pageio(void *args0)
|
||||
}
|
||||
else {
|
||||
page->mode = PM_PAGEIO;
|
||||
mcs_rwlock_writer_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
|
||||
ihk_mc_syscall_arg0(&ctx) = PAGER_REQ_READ;
|
||||
@ -522,7 +541,7 @@ static void fileobj_do_pageio(void *args0)
|
||||
__FUNCTION__, obj->handle);
|
||||
ss = syscall_generic_forwarding(__NR_mmap, &ctx);
|
||||
|
||||
mcs_rwlock_writer_lock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
if (page->mode != PM_PAGEIO) {
|
||||
kprintf("fileobj_do_pageio(%p,%lx,%lx):"
|
||||
@ -549,7 +568,7 @@ static void fileobj_do_pageio(void *args0)
|
||||
page->mode = PM_DONE_PAGEIO;
|
||||
}
|
||||
out:
|
||||
mcs_rwlock_writer_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
fileobj_release(&obj->memobj); /* got fileobj_get_page() */
|
||||
kfree(args0);
|
||||
@ -558,7 +577,7 @@ out:
|
||||
}
|
||||
|
||||
static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
int p2align, uintptr_t *physp, unsigned long *pflag)
|
||||
int p2align, uintptr_t *physp, unsigned long *pflag, uintptr_t virt_addr)
|
||||
{
|
||||
struct thread *proc = cpu_local_var(current);
|
||||
struct fileobj *obj = to_fileobj(memobj);
|
||||
@ -568,10 +587,10 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
uintptr_t phys = -1;
|
||||
struct page *page;
|
||||
struct pageio_args *args = NULL;
|
||||
struct mcs_rwlock_node mcs_node;
|
||||
struct mcs_lock_node mcs_node;
|
||||
int hash = (off >> PAGE_SHIFT) & FILEOBJ_PAGE_HASH_MASK;
|
||||
|
||||
dkprintf("fileobj_get_page(%p,%lx,%x,%p)\n", obj, off, p2align, physp);
|
||||
dkprintf("fileobj_get_page(%p,%lx,%x,%x,%p)\n", obj, off, p2align, virt_addr, physp);
|
||||
if (p2align != PAGE_P2ALIGN) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -584,13 +603,13 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
int page_ind = off >> PAGE_SHIFT;
|
||||
|
||||
if (!memobj->pages[page_ind]) {
|
||||
virt = ihk_mc_alloc_pages_user(1, IHK_MC_AP_NOWAIT | IHK_MC_AP_USER);
|
||||
virt = ihk_mc_alloc_pages_user(1, IHK_MC_AP_NOWAIT | IHK_MC_AP_USER, virt_addr);
|
||||
|
||||
if (!virt) {
|
||||
error = -ENOMEM;
|
||||
kprintf("fileobj_get_page(%p,%lx,%x,%p):"
|
||||
kprintf("fileobj_get_page(%p,%lx,%x,%x,%x,%p):"
|
||||
"alloc failed. %d\n",
|
||||
obj, off, p2align, physp,
|
||||
obj, off, p2align, virt_addr, physp,
|
||||
error);
|
||||
goto out_nolock;
|
||||
}
|
||||
@ -619,7 +638,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
goto out_nolock;
|
||||
}
|
||||
|
||||
mcs_rwlock_writer_lock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
page = __fileobj_page_hash_lookup(obj, hash, off);
|
||||
if (!page || (page->mode == PM_WILL_PAGEIO)
|
||||
@ -627,22 +646,22 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
args = kmalloc(sizeof(*args), IHK_MC_AP_NOWAIT);
|
||||
if (!args) {
|
||||
error = -ENOMEM;
|
||||
kprintf("fileobj_get_page(%p,%lx,%x,%p):"
|
||||
kprintf("fileobj_get_page(%p,%lx,%x,%x,%p):"
|
||||
"kmalloc failed. %d\n",
|
||||
obj, off, p2align, physp, error);
|
||||
obj, off, p2align, virt_addr, physp, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!page) {
|
||||
npages = 1 << p2align;
|
||||
|
||||
virt = ihk_mc_alloc_pages_user(npages, IHK_MC_AP_NOWAIT |
|
||||
(to_memobj(obj)->flags & MF_ZEROFILL) ? IHK_MC_AP_USER : 0);
|
||||
virt = ihk_mc_alloc_pages_user(npages, (IHK_MC_AP_NOWAIT |
|
||||
(to_memobj(obj)->flags & MF_ZEROFILL) ? IHK_MC_AP_USER : 0), virt_addr);
|
||||
if (!virt) {
|
||||
error = -ENOMEM;
|
||||
kprintf("fileobj_get_page(%p,%lx,%x,%p):"
|
||||
kprintf("fileobj_get_page(%p,%lx,%x,%x,%p):"
|
||||
"alloc failed. %d\n",
|
||||
obj, off, p2align, physp,
|
||||
obj, off, p2align, virt_addr, physp,
|
||||
error);
|
||||
goto out;
|
||||
}
|
||||
@ -698,7 +717,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
*physp = page_to_phys(page);
|
||||
virt = NULL;
|
||||
out:
|
||||
mcs_rwlock_writer_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
out_nolock:
|
||||
if (virt) {
|
||||
@ -707,8 +726,8 @@ out_nolock:
|
||||
if (args) {
|
||||
kfree(args);
|
||||
}
|
||||
dkprintf("fileobj_get_page(%p,%lx,%x,%p): %d %lx\n",
|
||||
obj, off, p2align, physp, error, phys);
|
||||
dkprintf("fileobj_get_page(%p,%lx,%x,%x,%p): %d %lx\n",
|
||||
obj, off, p2align, virt_addr, physp, error, phys);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -775,7 +794,7 @@ static int fileobj_lookup_page(struct memobj *memobj, off_t off,
|
||||
struct fileobj *obj = to_fileobj(memobj);
|
||||
int error = -1;
|
||||
struct page *page;
|
||||
struct mcs_rwlock_node mcs_node;
|
||||
struct mcs_lock_node mcs_node;
|
||||
int hash = (off >> PAGE_SHIFT) & FILEOBJ_PAGE_HASH_MASK;
|
||||
|
||||
dkprintf("fileobj_lookup_page(%p,%lx,%x,%p)\n", obj, off, p2align, physp);
|
||||
@ -784,7 +803,7 @@ static int fileobj_lookup_page(struct memobj *memobj, off_t off,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mcs_rwlock_reader_lock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
|
||||
page = __fileobj_page_hash_lookup(obj, hash, off);
|
||||
@ -796,7 +815,7 @@ static int fileobj_lookup_page(struct memobj *memobj, off_t off,
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
mcs_rwlock_reader_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
|
||||
&mcs_node);
|
||||
|
||||
dkprintf("fileobj_lookup_page(%p,%lx,%x,%p): %d \n",
|
||||
|
||||
@ -673,9 +673,11 @@ static uint64_t futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q
|
||||
xchg4(&(cpu_local_var(current)->status), PS_INTERRUPTIBLE);
|
||||
|
||||
/* Indicate spin sleep */
|
||||
irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock);
|
||||
thread->spin_sleep = 1;
|
||||
ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate);
|
||||
if (!idle_halt) {
|
||||
irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock);
|
||||
thread->spin_sleep = 1;
|
||||
ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate);
|
||||
}
|
||||
|
||||
queue_me(q, hb);
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
unsigned long s, e, up;
|
||||
char **argv;
|
||||
char **a;
|
||||
int i, n, argc, envc, args_envs_npages, l;
|
||||
int i, n, argc, envc, args_envs_npages;
|
||||
char **env;
|
||||
int range_npages;
|
||||
void *up_v;
|
||||
@ -148,7 +148,7 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
}
|
||||
|
||||
if ((up_v = ihk_mc_alloc_pages_user(range_npages,
|
||||
IHK_MC_AP_NOWAIT | ap_flags)) == NULL) {
|
||||
IHK_MC_AP_NOWAIT | ap_flags, s)) == NULL) {
|
||||
kprintf("ERROR: alloc pages for ELF section %i\n", i);
|
||||
goto err;
|
||||
}
|
||||
@ -259,7 +259,7 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
e = addr + PAGE_SIZE * ARGENV_PAGE_COUNT;
|
||||
|
||||
if((args_envs = ihk_mc_alloc_pages_user(ARGENV_PAGE_COUNT,
|
||||
IHK_MC_AP_NOWAIT)) == NULL){
|
||||
IHK_MC_AP_NOWAIT, -1)) == NULL){
|
||||
kprintf("ERROR: allocating pages for args/envs\n");
|
||||
goto err;
|
||||
}
|
||||
@ -349,21 +349,28 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
// Update variables
|
||||
argc = *((long *)(args_envs));
|
||||
dkprintf("argc: %d\n", argc);
|
||||
|
||||
argv = (char **)(args_envs + (sizeof(long)));
|
||||
if(proc->saved_cmdline){
|
||||
|
||||
if (proc->saved_cmdline) {
|
||||
kfree(proc->saved_cmdline);
|
||||
proc->saved_cmdline = NULL;
|
||||
proc->saved_cmdline_len = 0;
|
||||
}
|
||||
for(a = argv, l = 0; *a; a++)
|
||||
l += strlen(args_envs + (unsigned long)*a) + 1;
|
||||
|
||||
proc->saved_cmdline = kmalloc(p->args_len, IHK_MC_AP_NOWAIT);
|
||||
if(!proc->saved_cmdline)
|
||||
if (!proc->saved_cmdline) {
|
||||
goto err;
|
||||
proc->saved_cmdline_len = l;
|
||||
for(a = argv, l = 0; *a; a++){
|
||||
strcpy(proc->saved_cmdline + l, args_envs + (unsigned long)*a);
|
||||
l += strlen(args_envs + (unsigned long)*a) + 1;
|
||||
}
|
||||
|
||||
proc->saved_cmdline_len = p->args_len - ((argc + 2) * sizeof(char **));
|
||||
memcpy(proc->saved_cmdline,
|
||||
(char *)args_envs + ((argc + 2) * sizeof(char **)),
|
||||
proc->saved_cmdline_len);
|
||||
dkprintf("%s: saved_cmdline: %s\n",
|
||||
__FUNCTION__,
|
||||
proc->saved_cmdline);
|
||||
|
||||
for (a = argv; *a; a++) {
|
||||
*a = (char *)addr + (unsigned long)*a; // Process' address space!
|
||||
}
|
||||
|
||||
@ -590,14 +597,9 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
|
||||
case SCD_MSG_PREPARE_PROCESS:
|
||||
|
||||
if((rc = process_msg_prepare_process(packet->arg)) == 0){
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
|
||||
pckt.err = 0;
|
||||
}
|
||||
else{
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_NACKED;
|
||||
pckt.err = rc;
|
||||
}
|
||||
pckt.err = process_msg_prepare_process(packet->arg);
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
|
||||
pckt.reply = packet->reply;
|
||||
pckt.ref = packet->ref;
|
||||
pckt.arg = packet->arg;
|
||||
syscall_channel_send(resp_channel, &pckt);
|
||||
@ -653,10 +655,11 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
memcpy(&info, sp, sizeof(struct mcctrl_signal));
|
||||
ihk_mc_unmap_virtual(sp, 1, 0);
|
||||
ihk_mc_unmap_memory(NULL, pp, sizeof(struct mcctrl_signal));
|
||||
pckt.msg = SCD_MSG_SEND_SIGNAL;
|
||||
pckt.msg = SCD_MSG_SEND_SIGNAL_ACK;
|
||||
pckt.err = 0;
|
||||
pckt.ref = packet->ref;
|
||||
pckt.arg = packet->arg;
|
||||
pckt.reply = packet->reply;
|
||||
syscall_channel_send(resp_channel, &pckt);
|
||||
|
||||
rc = do_kill(NULL, info.pid, info.tid, info.sig, &info.info, 0);
|
||||
@ -729,6 +732,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
pckt.msg = SCD_MSG_PERF_ACK;
|
||||
pckt.err = 0;
|
||||
pckt.arg = packet->arg;
|
||||
pckt.reply = packet->reply;
|
||||
ihk_ikc_send(resp_channel, &pckt, 0);
|
||||
|
||||
ret = 0;
|
||||
|
||||
@ -97,6 +97,8 @@ struct cpu_local_var {
|
||||
|
||||
ihk_spinlock_t smp_func_req_lock;
|
||||
struct list_head smp_func_req_list;
|
||||
|
||||
struct process_vm *on_fork_vm;
|
||||
} __attribute__((aligned(64)));
|
||||
|
||||
|
||||
|
||||
@ -117,78 +117,9 @@
|
||||
#include <arch/system.h>
|
||||
#endif
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_8 /* arch depend hide */
|
||||
#else
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tem;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
#ifdef __UACCESS__
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
|
||||
return -EFAULT;
|
||||
#endif
|
||||
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ADD:
|
||||
__futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
|
||||
uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_OR:
|
||||
__futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ANDN:
|
||||
__futex_atomic_op2("andl %4, %3", ret, oldval, uaddr, ~oparg);
|
||||
break;
|
||||
case FUTEX_OP_XOR:
|
||||
__futex_atomic_op2("xorl %4, %3", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* arch depend hide */
|
||||
#endif // __KERNEL__
|
||||
#endif // _ASM_X86_FUTEX_H
|
||||
|
||||
|
||||
|
||||
#define FUTEX_HASHBITS 8 /* 256 entries in each futex hash tbl */
|
||||
|
||||
#define FUT_OFF_INODE 1 /* We set bit 0 if key has a reference on inode */
|
||||
|
||||
@ -18,6 +18,7 @@ extern void mem_init(void);
|
||||
extern void ihk_ikc_master_init(void);
|
||||
extern void ap_init(void);
|
||||
extern void arch_ready(void);
|
||||
extern void done_init(void);
|
||||
extern void mc_ikc_test_init(void);
|
||||
extern void cpu_local_var_init(void);
|
||||
extern void kmalloc_init(void);
|
||||
|
||||
@ -34,7 +34,7 @@ void *__kmalloc(int size, ihk_mc_ap_flag flag);
|
||||
void __kfree(void *ptr);
|
||||
|
||||
int _memcheck(void *ptr, char *msg, char *file, int line, int free);
|
||||
int memcheckall();
|
||||
int memcheckall(void);
|
||||
int freecheck(int runcount);
|
||||
void kmalloc_consolidate_free_list(void);
|
||||
|
||||
|
||||
@ -61,11 +61,12 @@ struct memobj {
|
||||
/* For pre-mapped memobjects */
|
||||
void **pages;
|
||||
int nr_pages;
|
||||
char *path;
|
||||
};
|
||||
|
||||
typedef void memobj_release_func_t(struct memobj *obj);
|
||||
typedef void memobj_ref_func_t(struct memobj *obj);
|
||||
typedef int memobj_get_page_func_t(struct memobj *obj, off_t off, int p2align, uintptr_t *physp, unsigned long *flag);
|
||||
typedef int memobj_get_page_func_t(struct memobj *obj, off_t off, int p2align, uintptr_t *physp, unsigned long *flag, uintptr_t virt_addr);
|
||||
typedef uintptr_t memobj_copy_page_func_t(struct memobj *obj, uintptr_t orgphys, int p2align);
|
||||
typedef int memobj_flush_page_func_t(struct memobj *obj, uintptr_t phys, size_t pgsize);
|
||||
typedef int memobj_invalidate_page_func_t(struct memobj *obj, uintptr_t phys, size_t pgsize);
|
||||
@ -96,10 +97,10 @@ static inline void memobj_ref(struct memobj *obj)
|
||||
}
|
||||
|
||||
static inline int memobj_get_page(struct memobj *obj, off_t off,
|
||||
int p2align, uintptr_t *physp, unsigned long *pflag)
|
||||
int p2align, uintptr_t *physp, unsigned long *pflag, uintptr_t virt_addr)
|
||||
{
|
||||
if (obj->ops->get_page) {
|
||||
return (*obj->ops->get_page)(obj, off, p2align, physp, pflag);
|
||||
return (*obj->ops->get_page)(obj, off, p2align, physp, pflag, virt_addr);
|
||||
}
|
||||
return -ENXIO;
|
||||
}
|
||||
@ -159,7 +160,7 @@ static inline int memobj_is_removable(struct memobj *obj)
|
||||
return !!(obj->flags & MF_IS_REMOVABLE);
|
||||
}
|
||||
|
||||
int fileobj_create(int fd, struct memobj **objp, int *maxprotp);
|
||||
int fileobj_create(int fd, struct memobj **objp, int *maxprotp, uintptr_t virt_addr);
|
||||
struct shmid_ds;
|
||||
int shmobj_create(struct shmid_ds *ds, struct memobj **objp);
|
||||
int zeroobj_create(struct memobj **objp);
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#define HEADER_PAGER_H
|
||||
|
||||
#include <ihk/types.h>
|
||||
#include <limits.h>
|
||||
|
||||
enum pager_op {
|
||||
PAGER_REQ_CREATE = 0x0001,
|
||||
@ -32,6 +33,7 @@ struct pager_create_result {
|
||||
int maxprot;
|
||||
uint32_t flags;
|
||||
size_t size;
|
||||
char path[PATH_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -46,6 +48,7 @@ struct pager_map_result {
|
||||
uintptr_t handle;
|
||||
int maxprot;
|
||||
int8_t padding[4];
|
||||
char path[PATH_MAX];
|
||||
};
|
||||
|
||||
/* for pager_req_pfn() */
|
||||
|
||||
@ -142,9 +142,7 @@
|
||||
#define WCONTINUED 0x00000008
|
||||
#define WNOWAIT 0x01000000 /* Don't reap, just poll status. */
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_44 /* wait() add support __WALL */
|
||||
#define __WALL 0x40000000 /* Wait on all children, regardless of type */
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_44 */
|
||||
#define __WCLONE 0x80000000
|
||||
|
||||
/* idtype */
|
||||
@ -277,6 +275,8 @@ struct resource_set {
|
||||
|
||||
extern struct list_head resource_set_list;
|
||||
extern mcs_rwlock_lock_t resource_set_lock;
|
||||
extern int idle_halt;
|
||||
extern int allow_oversubscribe;
|
||||
|
||||
struct process_hash {
|
||||
struct list_head list[HASH_SIZE];
|
||||
@ -390,7 +390,7 @@ struct vm_range {
|
||||
};
|
||||
|
||||
struct vm_range_numa_policy {
|
||||
struct list_head list;
|
||||
struct rb_node policy_rb_node;
|
||||
unsigned long start, end;
|
||||
DECLARE_BITMAP(numa_mask, PROCESS_NUMA_MASK_BITS);
|
||||
int numa_mem_policy;
|
||||
@ -419,6 +419,7 @@ struct mckfd {
|
||||
long (*mmap_cb)(struct mckfd *, ihk_mc_user_context_t *);
|
||||
int (*close_cb)(struct mckfd *, ihk_mc_user_context_t *);
|
||||
int (*fcntl_cb)(struct mckfd *, ihk_mc_user_context_t *);
|
||||
int (*dup_cb)(struct mckfd *, ihk_mc_user_context_t *);
|
||||
};
|
||||
|
||||
#define SFD_CLOEXEC 02000000
|
||||
@ -436,6 +437,7 @@ struct sig_pending {
|
||||
sigset_t sigmask;
|
||||
siginfo_t info;
|
||||
int ptracecont;
|
||||
int interrupted;
|
||||
};
|
||||
|
||||
typedef void pgio_func_t(void *arg);
|
||||
@ -486,7 +488,7 @@ struct process {
|
||||
// V +---- |
|
||||
// PS_STOPPED -----+
|
||||
// (PS_TRACED)
|
||||
int exit_status; // only for zombie
|
||||
unsigned long exit_status; // only for zombie
|
||||
|
||||
/* 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
|
||||
@ -572,9 +574,6 @@ struct process {
|
||||
int nr_processes; /* For partitioned execution */
|
||||
};
|
||||
|
||||
void hold_thread(struct thread *ftn);
|
||||
void release_thread(struct thread *ftn);
|
||||
|
||||
/*
|
||||
* Scheduling policies
|
||||
*/
|
||||
@ -725,7 +724,7 @@ struct process_vm {
|
||||
DECLARE_BITMAP(numa_mask, PROCESS_NUMA_MASK_BITS);
|
||||
int numa_mem_policy;
|
||||
/* Protected by memory_range_lock */
|
||||
struct list_head vm_range_numa_policy_list;
|
||||
struct rb_root vm_range_numa_policy_tree;
|
||||
struct vm_range *range_cache[VM_RANGE_CACHE_SIZE];
|
||||
int range_cache_ind;
|
||||
struct swapinfo *swapinfo;
|
||||
@ -750,7 +749,7 @@ struct thread *create_thread(unsigned long user_pc,
|
||||
struct thread *clone_thread(struct thread *org, unsigned long pc,
|
||||
unsigned long sp, int clone_flags);
|
||||
void destroy_thread(struct thread *thread);
|
||||
void hold_thread(struct thread *thread);
|
||||
int hold_thread(struct thread *thread);
|
||||
void release_thread(struct thread *thread);
|
||||
void flush_process_memory(struct process_vm *vm);
|
||||
void hold_process_vm(struct process_vm *vm);
|
||||
@ -826,8 +825,8 @@ struct process *find_process(int pid, struct mcs_rwlock_node_irqsave *lock);
|
||||
void process_unlock(struct process *proc, struct mcs_rwlock_node_irqsave *lock);
|
||||
void chain_process(struct process *);
|
||||
void chain_thread(struct thread *);
|
||||
void proc_init();
|
||||
void set_timer();
|
||||
void proc_init(void);
|
||||
void set_timer(void);
|
||||
struct sig_pending *hassigpending(struct thread *thread);
|
||||
|
||||
#endif
|
||||
|
||||
@ -35,6 +35,7 @@ rusage_rss_add(unsigned long size)
|
||||
unsigned long newval;
|
||||
unsigned long oldval;
|
||||
unsigned long retval;
|
||||
struct process_vm *vm;
|
||||
|
||||
newval = __sync_add_and_fetch(&rusage->rss_current, size);
|
||||
oldval = rusage->memory_max_usage;
|
||||
@ -46,12 +47,28 @@ rusage_rss_add(unsigned long size)
|
||||
}
|
||||
oldval = retval;
|
||||
}
|
||||
|
||||
/* process rss */
|
||||
vm = cpu_local_var(on_fork_vm);
|
||||
if (!vm) {
|
||||
vm = cpu_local_var(current)->vm;
|
||||
}
|
||||
|
||||
vm->currss += size;
|
||||
if (vm->currss > vm->proc->maxrss) {
|
||||
vm->proc->maxrss = vm->currss;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
rusage_rss_sub(unsigned long size)
|
||||
{
|
||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||
|
||||
__sync_sub_and_fetch(&rusage->rss_current, size);
|
||||
|
||||
/* process rss */
|
||||
vm->currss -= size;
|
||||
}
|
||||
|
||||
static inline void memory_stat_rss_add(unsigned long size, int pgsize)
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
|
||||
#define SCD_MSG_PREPARE_PROCESS 0x1
|
||||
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
||||
#define SCD_MSG_PREPARE_PROCESS_NACKED 0x7
|
||||
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
||||
#define SCD_MSG_WAKE_UP_SYSCALL_THREAD 0x14
|
||||
|
||||
@ -38,8 +37,9 @@
|
||||
#define SCD_MSG_INIT_CHANNEL_ACKED 0x6
|
||||
|
||||
#define SCD_MSG_SYSCALL_ONESIDE 0x4
|
||||
#define SCD_MSG_SEND_SIGNAL 0x8
|
||||
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
||||
#define SCD_MSG_SEND_SIGNAL 0x7
|
||||
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
|
||||
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
||||
#define SCD_MSG_GET_VDSO_INFO 0xa
|
||||
|
||||
#define SCD_MSG_GET_CPU_MAPPING 0xc
|
||||
@ -168,10 +168,8 @@ typedef unsigned long __cpu_set_unit;
|
||||
|
||||
struct program_load_desc {
|
||||
int num_sections;
|
||||
int status;
|
||||
int cpu;
|
||||
int pid;
|
||||
int err;
|
||||
int stack_prot;
|
||||
int pgid;
|
||||
int cred[8];
|
||||
@ -241,6 +239,7 @@ enum mcctrl_os_cpu_operation {
|
||||
struct ikc_scd_packet {
|
||||
int msg;
|
||||
int err;
|
||||
void *reply;
|
||||
union {
|
||||
/* for traditional SCD_MSG_* */
|
||||
struct {
|
||||
@ -276,7 +275,7 @@ struct ikc_scd_packet {
|
||||
int eventfd_type;
|
||||
};
|
||||
};
|
||||
char padding[12];
|
||||
char padding[8];
|
||||
};
|
||||
|
||||
#define IHK_SCD_REQ_THREAD_SPINNING 0
|
||||
@ -340,7 +339,7 @@ struct syscall_post {
|
||||
#define SYSCALL_FOOTER return do_syscall(&request, ihk_mc_get_processor_id(), 0)
|
||||
|
||||
extern long do_syscall(struct syscall_request *req, int cpu, int pid);
|
||||
extern int obtain_clone_cpuid();
|
||||
int obtain_clone_cpuid(cpu_set_t *cpu_set);
|
||||
extern long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx);
|
||||
|
||||
#define DECLARATOR(number,name) __NR_##name = number,
|
||||
@ -458,7 +457,7 @@ static inline unsigned long timespec_to_jiffy(const struct timespec *ats)
|
||||
return ats->tv_sec * 100 + ats->tv_nsec / 10000000;
|
||||
}
|
||||
|
||||
void reset_cputime();
|
||||
void reset_cputime(void);
|
||||
void set_cputime(int mode);
|
||||
int do_munmap(void *addr, size_t len);
|
||||
intptr_t do_mmap(intptr_t addr0, size_t len0, int prot, int flags, int fd,
|
||||
@ -471,6 +470,8 @@ int arch_map_vdso(struct process_vm *vm); /* arch dependent */
|
||||
int arch_setup_vdso(void);
|
||||
int arch_cpu_read_write_register(struct ihk_os_cpu_register *desc,
|
||||
enum mcctrl_os_cpu_operation op);
|
||||
struct vm_range_numa_policy *vm_range_policy_search(struct process_vm *vm, uintptr_t addr);
|
||||
time_t time(void);
|
||||
|
||||
#ifndef POSTK_DEBUG_ARCH_DEP_52
|
||||
#define VDSO_MAXPAGES 2
|
||||
@ -518,7 +519,6 @@ enum perf_ctrl_type {
|
||||
|
||||
struct perf_ctrl_desc {
|
||||
enum perf_ctrl_type ctrl_type;
|
||||
int status;
|
||||
union {
|
||||
/* for SET, GET */
|
||||
struct {
|
||||
|
||||
@ -252,6 +252,7 @@ extern struct xpmem_partition *xpmem_my_part;
|
||||
|
||||
static int xpmem_ioctl(struct mckfd *mckfd, ihk_mc_user_context_t *ctx);
|
||||
static int xpmem_close(struct mckfd *mckfd, ihk_mc_user_context_t *ctx);
|
||||
static int xpmem_dup(struct mckfd *mckfd, ihk_mc_user_context_t *ctx);
|
||||
|
||||
static int xpmem_init(void);
|
||||
static void xpmem_exit(void);
|
||||
@ -275,6 +276,7 @@ static int xpmem_release(xpmem_apid_t);
|
||||
static void xpmem_release_ap(struct xpmem_thread_group *,
|
||||
struct xpmem_access_permit *);
|
||||
static void xpmem_release_aps_of_tg(struct xpmem_thread_group *ap_tg);
|
||||
static void xpmem_flush(struct mckfd *);
|
||||
|
||||
static int xpmem_attach(struct mckfd *, xpmem_apid_t, off_t, size_t,
|
||||
unsigned long, int, int, unsigned long *);
|
||||
|
||||
@ -144,6 +144,18 @@ static void parse_kargs(void)
|
||||
}
|
||||
}
|
||||
ihk_mc_set_dump_level(dump_level);
|
||||
|
||||
/* idle_halt option */
|
||||
ptr = find_command_line("idle_halt");
|
||||
if (ptr) {
|
||||
idle_halt = 1;
|
||||
}
|
||||
|
||||
/* allow_oversubscribe option */
|
||||
ptr = find_command_line("allow_oversubscribe");
|
||||
if (ptr) {
|
||||
allow_oversubscribe = 1;
|
||||
}
|
||||
}
|
||||
|
||||
extern void ihk_mc_get_boot_time(unsigned long *tv_sec, unsigned long *tv_nsec);
|
||||
@ -381,6 +393,7 @@ int main(void)
|
||||
|
||||
futex_init();
|
||||
|
||||
done_init();
|
||||
kputs("IHK/McKernel booted.\n");
|
||||
|
||||
#ifdef DCFA_KMOD
|
||||
|
||||
89
kernel/mem.c
89
kernel/mem.c
@ -76,7 +76,7 @@ static void *___kmalloc(int size, ihk_mc_ap_flag flag);
|
||||
static void ___kfree(void *ptr);
|
||||
|
||||
static void *___ihk_mc_alloc_aligned_pages_node(int npages,
|
||||
int p2align, ihk_mc_ap_flag flag, int node, int is_user);
|
||||
int p2align, ihk_mc_ap_flag flag, int node, int is_user, uintptr_t virt_addr);
|
||||
static void *___ihk_mc_alloc_pages(int npages, ihk_mc_ap_flag flag, int is_user);
|
||||
static void ___ihk_mc_free_pages(void *p, int npages, int is_user);
|
||||
|
||||
@ -193,7 +193,7 @@ struct pagealloc_track_entry *__pagealloc_track_find_entry(
|
||||
|
||||
/* Top level routines called from macros */
|
||||
void *_ihk_mc_alloc_aligned_pages_node(int npages, int p2align,
|
||||
ihk_mc_ap_flag flag, int node, int is_user,
|
||||
ihk_mc_ap_flag flag, int node, int is_user, uintptr_t virt_addr,
|
||||
char *file, int line)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
@ -201,7 +201,7 @@ void *_ihk_mc_alloc_aligned_pages_node(int npages, int p2align,
|
||||
struct pagealloc_track_addr_entry *addr_entry;
|
||||
int hash, addr_hash;
|
||||
void *r = ___ihk_mc_alloc_aligned_pages_node(npages,
|
||||
p2align, flag, node, is_user);
|
||||
p2align, flag, node, is_user, virt_addr);
|
||||
|
||||
if (!memdebug || !pagealloc_track_initialized)
|
||||
return r;
|
||||
@ -497,10 +497,10 @@ void pagealloc_memcheck(void)
|
||||
|
||||
/* Actual allocation routines */
|
||||
static void *___ihk_mc_alloc_aligned_pages_node(int npages, int p2align,
|
||||
ihk_mc_ap_flag flag, int node, int is_user)
|
||||
ihk_mc_ap_flag flag, int node, int is_user, uintptr_t virt_addr)
|
||||
{
|
||||
if (pa_ops)
|
||||
return pa_ops->alloc_page(npages, p2align, flag, node, is_user);
|
||||
return pa_ops->alloc_page(npages, p2align, flag, node, is_user, virt_addr);
|
||||
else
|
||||
return early_alloc_pages(npages);
|
||||
}
|
||||
@ -508,7 +508,7 @@ static void *___ihk_mc_alloc_aligned_pages_node(int npages, int p2align,
|
||||
static void *___ihk_mc_alloc_pages(int npages, ihk_mc_ap_flag flag,
|
||||
int is_user)
|
||||
{
|
||||
return ___ihk_mc_alloc_aligned_pages_node(npages, PAGE_P2ALIGN, flag, -1, is_user);
|
||||
return ___ihk_mc_alloc_aligned_pages_node(npages, PAGE_P2ALIGN, flag, -1, is_user, -1);
|
||||
}
|
||||
|
||||
static void ___ihk_mc_free_pages(void *p, int npages, int is_user)
|
||||
@ -544,7 +544,7 @@ static void reserve_pages(struct ihk_page_allocator_desc *pa_allocator,
|
||||
|
||||
extern int cpu_local_var_initialized;
|
||||
static void *mckernel_allocate_aligned_pages_node(int npages, int p2align,
|
||||
ihk_mc_ap_flag flag, int pref_node, int is_user)
|
||||
ihk_mc_ap_flag flag, int pref_node, int is_user, uintptr_t virt_addr)
|
||||
{
|
||||
unsigned long pa = 0;
|
||||
int i, node;
|
||||
@ -553,6 +553,12 @@ static void *mckernel_allocate_aligned_pages_node(int npages, int p2align,
|
||||
#endif
|
||||
int numa_id;
|
||||
|
||||
struct vm_range_numa_policy *range_policy_iter = NULL;
|
||||
int numa_mem_policy = -1;
|
||||
struct process_vm *vm;
|
||||
struct vm_range *range = NULL;
|
||||
int chk_shm = 0;
|
||||
|
||||
if(npages <= 0)
|
||||
return NULL;
|
||||
|
||||
@ -565,7 +571,23 @@ static void *mckernel_allocate_aligned_pages_node(int npages, int p2align,
|
||||
/* No explicitly requested NUMA or user policy? */
|
||||
if ((pref_node == -1) && (!(flag & IHK_MC_AP_USER) ||
|
||||
cpu_local_var(current)->vm->numa_mem_policy == MPOL_DEFAULT)) {
|
||||
goto distance_based;
|
||||
|
||||
if (virt_addr != -1) {
|
||||
vm = cpu_local_var(current)->vm;
|
||||
range_policy_iter = vm_range_policy_search(vm, virt_addr);
|
||||
if (range_policy_iter) {
|
||||
range = lookup_process_memory_range(vm, (uintptr_t)virt_addr, ((uintptr_t)virt_addr) + 1);
|
||||
if (range) {
|
||||
if( (range->memobj) && (range->memobj->flags == MF_SHM)) {
|
||||
chk_shm = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((!((range_policy_iter) && (range_policy_iter->numa_mem_policy != MPOL_DEFAULT))) && (chk_shm == 0))
|
||||
goto distance_based;
|
||||
}
|
||||
|
||||
node = ihk_mc_get_numa_id();
|
||||
@ -611,7 +633,28 @@ static void *mckernel_allocate_aligned_pages_node(int npages, int p2align,
|
||||
}
|
||||
}
|
||||
|
||||
switch (cpu_local_var(current)->vm->numa_mem_policy) {
|
||||
if ((virt_addr != -1) && (chk_shm == 0)) {
|
||||
|
||||
vm = cpu_local_var(current)->vm;
|
||||
|
||||
if (!(range_policy_iter)) {
|
||||
range_policy_iter = vm_range_policy_search(vm, virt_addr);
|
||||
}
|
||||
|
||||
if (range_policy_iter) {
|
||||
range = lookup_process_memory_range(vm, (uintptr_t)virt_addr, ((uintptr_t)virt_addr) + 1);
|
||||
if ((range && (range->memobj->flags == MF_SHM))) {
|
||||
chk_shm = 1;
|
||||
} else {
|
||||
numa_mem_policy = range_policy_iter->numa_mem_policy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numa_mem_policy == -1)
|
||||
numa_mem_policy = cpu_local_var(current)->vm->numa_mem_policy;
|
||||
|
||||
switch (numa_mem_policy) {
|
||||
case MPOL_BIND:
|
||||
case MPOL_PREFERRED:
|
||||
|
||||
@ -1169,10 +1212,6 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
||||
info._sifields._sigfault.si_addr = fault_addr;
|
||||
set_signal(SIGSEGV, regs, &info);
|
||||
}
|
||||
if(interrupt_from_user(regs)){
|
||||
cpu_enable_interrupt();
|
||||
check_signal(0, regs, 0);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1181,8 +1220,12 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
||||
out:
|
||||
dkprintf("%s: addr: %p, reason: %lx, regs: %p -> error: %d\n",
|
||||
__FUNCTION__, fault_addr, reason, regs, error);
|
||||
check_need_resched();
|
||||
set_cputime(0);
|
||||
if(interrupt_from_user(regs)){
|
||||
cpu_enable_interrupt();
|
||||
check_need_resched();
|
||||
check_signal(0, regs, 0);
|
||||
}
|
||||
set_cputime(interrupt_from_user(regs)? 0: 1);
|
||||
#ifdef PROFILE_ENABLE
|
||||
if (thread->profile)
|
||||
profile_event_add(PROFILE_page_fault, (rdtsc() - t_s));
|
||||
@ -1621,6 +1664,8 @@ void *ihk_mc_map_virtual(unsigned long phys, int npages,
|
||||
ihk_pagealloc_free(vmap_allocator, virt_to_phys(p), npages);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flush_tlb_single((unsigned long)(p + (i << PAGE_SHIFT)));
|
||||
}
|
||||
barrier();
|
||||
return (char *)p + offset;
|
||||
@ -1633,17 +1678,14 @@ void ihk_mc_unmap_virtual(void *va, int npages, int free_physical)
|
||||
va = (void *)((unsigned long)va & PAGE_MASK);
|
||||
for (i = 0; i < npages; i++) {
|
||||
ihk_mc_pt_clear_page(NULL, (char *)va + (i << PAGE_SHIFT));
|
||||
flush_tlb_single((unsigned long)(va + (i << PAGE_SHIFT)));
|
||||
}
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_42 /* add unmap virtual tlb flush. */
|
||||
flush_tlb();
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_42 */
|
||||
|
||||
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_51 /* ihk_mc_unmap_virtual() free_physical disabled */
|
||||
ihk_pagealloc_free(vmap_allocator, (unsigned long)va, npages);
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_51 */
|
||||
if (free_physical) {
|
||||
ihk_pagealloc_free(vmap_allocator, (unsigned long)va, npages);
|
||||
flush_tlb_single((unsigned long)va);
|
||||
}
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_51 */
|
||||
}
|
||||
@ -1704,11 +1746,16 @@ static void rusage_init()
|
||||
{
|
||||
int npages;
|
||||
unsigned long phys;
|
||||
const struct ihk_mc_cpu_info *cpu_info = ihk_mc_get_cpu_info();
|
||||
|
||||
if (!cpu_info) {
|
||||
panic("rusage_init: PANIC: ihk_mc_get_cpu_info returned NULL");
|
||||
}
|
||||
|
||||
npages = (sizeof(struct rusage_global) + PAGE_SIZE -1) >> PAGE_SHIFT;
|
||||
rusage = ihk_mc_alloc_pages(npages, IHK_MC_AP_CRITICAL);
|
||||
memset(rusage, 0, npages * PAGE_SIZE);
|
||||
rusage->num_processors = num_processors;
|
||||
rusage->num_processors = cpu_info->ncpus;
|
||||
rusage->num_numa_nodes = ihk_mc_get_nr_numa_nodes();
|
||||
rusage->ns_per_tsc = ihk_mc_get_ns_per_tsc();
|
||||
phys = virt_to_phys(rusage);
|
||||
|
||||
145
kernel/pager.c
145
kernel/pager.c
@ -96,7 +96,7 @@ struct swapinfo {
|
||||
struct arealist swap_area;
|
||||
struct arealist mlock_area;
|
||||
struct mlockcntnr mlock_container;
|
||||
#define UDATA_BUFSIZE (8*1024)
|
||||
#define UDATA_BUFSIZE PAGE_SIZE
|
||||
char *swapfname;
|
||||
char *udata_buf; /* To read-store data from Linux to user space */
|
||||
|
||||
@ -295,7 +295,7 @@ static int
|
||||
pager_open(struct swapinfo *si, char *fname, int flag, int mode)
|
||||
{
|
||||
int fd;
|
||||
strcpy(si->udata_buf, fname);
|
||||
copy_to_user(si->udata_buf, fname, strlen(fname) + 1);
|
||||
fd = linux_open(si->udata_buf, flag, mode);
|
||||
return fd;
|
||||
}
|
||||
@ -303,22 +303,69 @@ pager_open(struct swapinfo *si, char *fname, int flag, int mode)
|
||||
static int
|
||||
pager_unlink(struct swapinfo *si, char *fname)
|
||||
{
|
||||
strcpy(si->udata_buf, fname);
|
||||
copy_to_user(si->udata_buf, fname, strlen(fname) + 1);
|
||||
return linux_unlink(si->udata_buf);
|
||||
}
|
||||
|
||||
static int
|
||||
pager_copy_from_user(void * dst, void * from, size_t size, struct process_vm *vm)
|
||||
{
|
||||
int ret;
|
||||
void *virt;
|
||||
unsigned long psize;
|
||||
unsigned long rphys;
|
||||
int faulted = 0;
|
||||
|
||||
if (size > PAGE_SIZE) {
|
||||
ret = -EFAULT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
retry_lookup:
|
||||
/* remember page */
|
||||
ret = ihk_mc_pt_virt_to_phys_size(vm->address_space->page_table,
|
||||
dst, &rphys, &psize);
|
||||
|
||||
if (ret) {
|
||||
uint64_t reason = PF_POPULATE | PF_WRITE | PF_USER;
|
||||
void *addr= (void *)(((unsigned long)dst)& PAGE_MASK);
|
||||
|
||||
if (faulted) {
|
||||
ret = -EFAULT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = page_fault_process_vm(vm, addr, reason);
|
||||
if (ret) {
|
||||
ret = -EFAULT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
faulted = 1;
|
||||
goto retry_lookup;
|
||||
}
|
||||
|
||||
virt = phys_to_virt(rphys);
|
||||
|
||||
ret = copy_from_user(virt, from, size);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
pager_read(struct swapinfo *si, int fd, void *start, size_t size)
|
||||
pager_read(struct swapinfo *si, int fd, void *start, size_t size,struct process_vm *vm)
|
||||
{
|
||||
ssize_t off, sz, rs;
|
||||
|
||||
kprintf("pager_read: %lx (%lx)\n", start, size);
|
||||
for (off = 0; off < size; off += sz) {
|
||||
sz = size - off;
|
||||
sz = (sz > UDATA_BUFSIZE) ? UDATA_BUFSIZE : sz;
|
||||
rs = linux_read(fd, si->udata_buf, sz);
|
||||
if (rs != sz) return rs;
|
||||
copy_to_user(start + off, si->udata_buf, sz);
|
||||
|
||||
rs = pager_copy_from_user(start + off, si->udata_buf, sz, vm);
|
||||
if (rs != 0) return rs;
|
||||
}
|
||||
return off;
|
||||
}
|
||||
@ -354,23 +401,26 @@ mlocklist_req(unsigned long start, unsigned long end, struct addrpair *addr, int
|
||||
static int
|
||||
mlocklist_morereq(struct swapinfo *si, unsigned long *start)
|
||||
{
|
||||
struct areaent *ent = si->mlock_area.tail;
|
||||
struct areaent went,*ent = si->mlock_area.tail;
|
||||
copy_from_user(&went, ent, sizeof(struct areaent));
|
||||
|
||||
dkprintf("mlocklist_morereq: start = %ld and = %ld\n",
|
||||
ent->pair[ent->count].start, ent->pair[ent->count].end);
|
||||
if (ent->pair[ent->count].start != (unsigned long) -1) {
|
||||
went.pair[went.count].start, went.pair[went.count].end);
|
||||
if (went.pair[went.count].start != (unsigned long) -1) {
|
||||
return 0;
|
||||
}
|
||||
*start = ent->pair[ent->count].end;
|
||||
*start = went.pair[went.count].end;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
arealist_alloc(struct swapinfo *si, struct arealist *areap)
|
||||
{
|
||||
struct areaent went;
|
||||
areap->head = areap->tail = myalloc(si, sizeof(struct areaent));
|
||||
if (areap->head == NULL) return -ENOMEM;
|
||||
memset(areap->head, 0, sizeof(struct areaent));
|
||||
memset(&went, 0, sizeof(struct areaent));
|
||||
copy_to_user(areap->head, &went, sizeof(struct areaent));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -402,7 +452,7 @@ arealist_free(struct arealist *area)
|
||||
static int
|
||||
arealist_get(struct swapinfo *si, struct addrpair **pair, struct arealist *area)
|
||||
{
|
||||
struct areaent *tmp;
|
||||
struct areaent *tmp,wtmp;
|
||||
struct areaent *tail = area->tail;
|
||||
if (tail->count < MLOCKADDRS_SIZE - 1) { /* at least two entries are needed */
|
||||
if (pair) *pair = &tail->pair[tail->count];
|
||||
@ -412,8 +462,10 @@ arealist_get(struct swapinfo *si, struct addrpair **pair, struct arealist *area)
|
||||
if (tmp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memset(tmp, 0, sizeof(struct areaent));
|
||||
area->tail->next = tmp;
|
||||
memset(&wtmp, 0, sizeof(struct areaent));
|
||||
copy_to_user(tmp, &wtmp, sizeof(struct areaent));
|
||||
copy_to_user(&(area->tail->next), &tmp, sizeof(struct areaent *));
|
||||
|
||||
area->tail = tmp;
|
||||
if (pair) *pair = area->tail->pair;
|
||||
return MLOCKADDRS_SIZE;
|
||||
@ -422,7 +474,10 @@ arealist_get(struct swapinfo *si, struct addrpair **pair, struct arealist *area)
|
||||
static void
|
||||
arealist_update(int cnt, struct arealist *area)
|
||||
{
|
||||
area->tail->count += cnt;
|
||||
int i;
|
||||
copy_from_user(&i, &(area->tail->count), sizeof(int));
|
||||
i += cnt;
|
||||
copy_to_user(&(area->tail->count), &i, sizeof(int));
|
||||
area->count += cnt;
|
||||
}
|
||||
|
||||
@ -431,11 +486,13 @@ arealist_add(struct swapinfo *si, unsigned long start, unsigned long end,
|
||||
unsigned long flag, struct arealist *area)
|
||||
{
|
||||
int cc;
|
||||
struct addrpair *addr;
|
||||
struct addrpair *addr,waddr;
|
||||
|
||||
cc = arealist_get(si, &addr, area);
|
||||
if (cc < 0) return -1;
|
||||
addr->start = start; addr->end = end; addr->flag = flag;
|
||||
waddr.start = start; waddr.end = end; waddr.flag = flag;
|
||||
copy_to_user(addr, &waddr, sizeof(struct addrpair));
|
||||
|
||||
arealist_update(1, area);
|
||||
return 0;
|
||||
}
|
||||
@ -444,27 +501,31 @@ static int
|
||||
arealist_preparewrite(struct arealist *areap, struct swap_areainfo *info,
|
||||
ssize_t off, struct process_vm *vm, int flag)
|
||||
{
|
||||
struct areaent *ent;
|
||||
struct areaent *ent,went;
|
||||
int count = 0;
|
||||
ssize_t totsz = 0;
|
||||
unsigned long pos;
|
||||
struct page_table *pt = vm->address_space->page_table;
|
||||
|
||||
for (ent = areap->head; ent != NULL; ent = ent->next) {
|
||||
int i;
|
||||
for (i = 0; i < ent->count; i++, count++) {
|
||||
ssize_t sz = ent->pair[i].end - ent->pair[i].start;
|
||||
info[count].start = ent->pair[i].start;
|
||||
info[count].end = ent->pair[i].end;
|
||||
info[count].flag = ent->pair[i].flag;
|
||||
copy_from_user(&went, ent, sizeof(struct areaent));
|
||||
for (i = 0; i < went.count; i++, count++) {
|
||||
ssize_t sz = went.pair[i].end - went.pair[i].start;
|
||||
copy_to_user(&(info[count].start), &(went.pair[i].start), sizeof(unsigned long));
|
||||
copy_to_user(&(info[count].end), &(went.pair[i].end), sizeof(unsigned long));
|
||||
copy_to_user(&(info[count].flag), &(went.pair[i].flag), sizeof(unsigned long));
|
||||
if (flag) { /* position in file */
|
||||
info[count].pos = off + totsz;
|
||||
|
||||
pos = off + totsz;
|
||||
} else { /* physical memory */
|
||||
if (ihk_mc_pt_virt_to_phys(pt,
|
||||
(void*) ent->pair[i].start,
|
||||
&info[count].pos)) {
|
||||
&pos)) {
|
||||
kprintf("Cannot get phys\n");
|
||||
}
|
||||
}
|
||||
copy_to_user(&(info[count].pos), &pos, sizeof(unsigned long));
|
||||
totsz += sz;
|
||||
}
|
||||
}
|
||||
@ -489,6 +550,7 @@ arealist_print(char *msg, struct arealist *areap, int count)
|
||||
for (ent = areap->head; ent != NULL; ent = ent->next) {
|
||||
int i;
|
||||
for (i = 0; i < ent->count; i++) {
|
||||
|
||||
kprintf("\t%p -- %p\n",
|
||||
(void*) ent->pair[i].start, (void*) ent->pair[i].end);
|
||||
}
|
||||
@ -608,13 +670,13 @@ do_pagein(int flag)
|
||||
extern int ihk_mc_pt_print_pte(struct page_table *pt, void *virt);
|
||||
sz = si->swap_info[i].end - si->swap_info[i].start;
|
||||
dkprintf("pagein: %016lx:%016lx sz(%lx)\n", si->swap_info[i].start, si->swap_info[i].end, sz);
|
||||
rs = pager_read(si, fd, (void*) si->swap_info[i].start, sz);
|
||||
rs = pager_read(si, fd, (void*) si->swap_info[i].start, sz, vm);
|
||||
if (rs != sz) goto err;
|
||||
// ihk_mc_pt_print_pte(vm->address_space->page_table, (void*) si->swap_info[i].start);
|
||||
}
|
||||
linux_close(fd);
|
||||
print_region("after pagin", vm);
|
||||
kprintf("do_pagein: done, currss(%lx)\n", vm->currss);
|
||||
dkprintf("do_pagein: done, currss(%lx)\n", vm->currss);
|
||||
vm->swapinfo = NULL;
|
||||
kfree(si->swapfname);
|
||||
kfree(si);
|
||||
@ -679,7 +741,8 @@ do_pageout(char *fname, void *buf, size_t size, int flag)
|
||||
goto err;
|
||||
}
|
||||
|
||||
fd = linux_open(fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
|
||||
copy_to_user(si->udata_buf, si->swapfname, strlen(si->swapfname) + 1);
|
||||
fd = linux_open(si->udata_buf, O_RDWR|O_CREAT|O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
ekprintf("do_pageout: Cannot open/create file: %s\n", fname);
|
||||
cc = fd;
|
||||
@ -752,10 +815,10 @@ do_pageout(char *fname, void *buf, size_t size, int flag)
|
||||
|
||||
/* preparing page store */
|
||||
si->swphdr = myalloc(si, sizeof(struct swap_header));
|
||||
strncpy(si->swphdr->magic, MCKERNEL_SWAP, SWAP_HLEN);
|
||||
strncpy(si->swphdr->version, MCKERNEL_SWAP_VERSION, SWAP_HLEN);
|
||||
si->swphdr->count_sarea = si->swap_area.count;
|
||||
si->swphdr->count_marea = si->mlock_area.count;
|
||||
copy_to_user(&(si->swphdr->magic), MCKERNEL_SWAP, SWAP_HLEN);
|
||||
copy_to_user(&(si->swphdr->version), MCKERNEL_SWAP_VERSION, SWAP_HLEN);
|
||||
copy_to_user(&(si->swphdr->count_sarea), &(si->swap_area.count), sizeof(unsigned int));
|
||||
copy_to_user(&(si->swphdr->count_marea), &(si->mlock_area.count), sizeof(unsigned int));
|
||||
if ((cc = pager_write(fd, si->swphdr, sizeof(struct swap_header)))
|
||||
!= sizeof(struct swap_header)) {
|
||||
if (cc >= 0)
|
||||
@ -779,8 +842,10 @@ do_pageout(char *fname, void *buf, size_t size, int flag)
|
||||
if ((cc = arealist_write(fd, si->mlock_info, si->mlock_area.count)) < 0) goto err;
|
||||
/* now pages are stored */
|
||||
for (i = 0; i < si->swap_area.count; i++) {
|
||||
sz = si->swap_info[i].end - si->swap_info[i].start;
|
||||
if ((cc = pager_write(fd, (void*) si->swap_info[i].start, sz)) != sz) {
|
||||
struct swap_areainfo sw_info;
|
||||
copy_from_user(&sw_info, &(si->swap_info[i]), sizeof(struct swap_areainfo));
|
||||
sz = sw_info.end - sw_info.start;
|
||||
if ((cc = pager_write(fd, (void*) sw_info.start, sz)) != sz) {
|
||||
if (cc >= 0)
|
||||
cc = -EIO;
|
||||
goto err;
|
||||
@ -792,10 +857,12 @@ do_pageout(char *fname, void *buf, size_t size, int flag)
|
||||
}
|
||||
kprintf("removing physical memory\n");
|
||||
for (i = 0; i < si->swap_area.count; i++) {
|
||||
struct swap_areainfo sw_info;
|
||||
copy_from_user(&sw_info, &(si->swap_info[i]), sizeof(struct swap_areainfo));
|
||||
cc = ihk_mc_pt_free_range(vm->address_space->page_table,
|
||||
vm,
|
||||
(void*) si->swap_info[i].start,
|
||||
(void*) si->swap_info[i].end, NULL);
|
||||
(void*) sw_info.start,
|
||||
(void*) sw_info.end, NULL);
|
||||
if (cc < 0) {
|
||||
kprintf("ihk_mc_pt_clear_range returns: %d\n", cc);
|
||||
}
|
||||
@ -811,8 +878,10 @@ do_pageout(char *fname, void *buf, size_t size, int flag)
|
||||
* except TEXT, STACK, readonly pages, are not invalid.
|
||||
*/
|
||||
for (i = 0; i < si->swap_area.count; i++) {
|
||||
sz = si->swap_info[i].end - si->swap_info[i].start;
|
||||
cc = linux_munmap((void*) si->swap_info[i].start, sz, 0);
|
||||
struct swap_areainfo sw_info;
|
||||
copy_from_user(&sw_info, &(si->swap_info[i]), sizeof(struct swap_areainfo));
|
||||
sz = sw_info.end - sw_info.start;
|
||||
cc = linux_munmap((void*) sw_info.start, sz, 0);
|
||||
if (cc < 0) {
|
||||
kprintf("do_pageout: Cannot munmap: %lx len(%lx)\n",
|
||||
si->swap_info[i].start, sz);
|
||||
|
||||
142
kernel/process.c
142
kernel/process.c
@ -100,6 +100,9 @@ extern void perf_reset(struct mc_perf_event *event);
|
||||
struct list_head resource_set_list;
|
||||
mcs_rwlock_lock_t resource_set_lock;
|
||||
|
||||
int idle_halt = 0;
|
||||
int allow_oversubscribe = 0;
|
||||
|
||||
void
|
||||
init_process(struct process *proc, struct process *parent)
|
||||
{
|
||||
@ -256,7 +259,7 @@ init_process_vm(struct process *owner, struct address_space *asp, struct process
|
||||
|
||||
ihk_atomic_set(&vm->refcount, 1);
|
||||
vm->vm_range_tree = RB_ROOT;
|
||||
INIT_LIST_HEAD(&vm->vm_range_numa_policy_list);
|
||||
vm->vm_range_numa_policy_tree = RB_ROOT;
|
||||
vm->address_space = asp;
|
||||
vm->proc = owner;
|
||||
vm->exiting = 0;
|
||||
@ -395,6 +398,7 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
|
||||
int termsig = clone_flags & 0xff;
|
||||
struct process *proc = NULL;
|
||||
struct address_space *asp = NULL;
|
||||
struct cpu_local_var *v = get_this_cpu_local_var();
|
||||
|
||||
if ((thread = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES,
|
||||
IHK_MC_AP_NOWAIT)) == NULL) {
|
||||
@ -405,6 +409,9 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
|
||||
ihk_atomic_set(&thread->refcount, 2);
|
||||
memcpy(&thread->cpu_set, &org->cpu_set, sizeof(thread->cpu_set));
|
||||
|
||||
/* New thread is in kernel until jumping to enter_user_mode */
|
||||
thread->in_kernel = org->in_kernel;
|
||||
|
||||
/* NOTE: sp is the user mode stack! */
|
||||
ihk_mc_init_user_process(&thread->ctx, &thread->uctx, ((char *)thread) +
|
||||
KERNEL_STACK_NR_PAGES * PAGE_SIZE, pc, sp);
|
||||
@ -478,12 +485,15 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
|
||||
dkprintf("fork(): copy_user_ranges()\n");
|
||||
/* Copy user-space mappings.
|
||||
* TODO: do this with COW later? */
|
||||
v->on_fork_vm = proc->vm;
|
||||
if (copy_user_ranges(proc->vm, org->vm) != 0) {
|
||||
release_address_space(asp);
|
||||
v->on_fork_vm = NULL;
|
||||
kfree(proc->vm);
|
||||
kfree(proc);
|
||||
goto err_free_proc;
|
||||
}
|
||||
v->on_fork_vm = NULL;
|
||||
|
||||
/* Copy mckfd list
|
||||
FIXME: Replace list manipulation with list_add() etc. */
|
||||
@ -507,13 +517,15 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
|
||||
mckfd->next = proc->mckfd;
|
||||
proc->mckfd = mckfd;
|
||||
}
|
||||
|
||||
if (mckfd->dup_cb) {
|
||||
mckfd->dup_cb(mckfd, NULL);
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock(&proc->mckfd_lock, irqstate);
|
||||
|
||||
thread->vm->vdso_addr = org->vm->vdso_addr;
|
||||
thread->vm->vvar_addr = org->vm->vvar_addr;
|
||||
thread->proc->maxrss = org->proc->maxrss;
|
||||
thread->vm->currss = org->vm->currss;
|
||||
|
||||
thread->sigstack.ss_sp = org->sigstack.ss_sp;
|
||||
thread->sigstack.ss_flags = org->sigstack.ss_flags;
|
||||
@ -646,7 +658,7 @@ static int copy_user_pte(void *arg0, page_table_t src_pt, pte_t *src_ptep, void
|
||||
|
||||
npages = pgsize / PAGE_SIZE;
|
||||
virt = ihk_mc_alloc_aligned_pages_user(npages, pgalign,
|
||||
IHK_MC_AP_NOWAIT);
|
||||
IHK_MC_AP_NOWAIT, (uintptr_t)pgaddr);
|
||||
if (!virt) {
|
||||
kprintf("ERROR: copy_user_pte() allocating new page\n");
|
||||
error = -ENOMEM;
|
||||
@ -1426,6 +1438,20 @@ int change_prot_process_memory_range(struct process_vm *vm,
|
||||
clrattr = oldattr & ~newattr;
|
||||
setattr = newattr & ~oldattr;
|
||||
|
||||
/*
|
||||
* If this is a file mapping don't set any new prot write.
|
||||
* We need to keep the page table read-only to trigger a page
|
||||
* fault for copy-on-write later on
|
||||
*/
|
||||
if (range->memobj && (range->flag & VR_PRIVATE)) {
|
||||
setattr &= ~PTATTR_WRITABLE;
|
||||
if (!clrattr && !setattr) {
|
||||
range->flag = newflag;
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
error = ihk_mc_pt_change_attr_range(vm->address_space->page_table,
|
||||
(void *)range->start, (void *)range->end,
|
||||
@ -1466,14 +1492,6 @@ static int remap_one_page(void *arg0, page_table_t pt, pte_t *ptep,
|
||||
dkprintf("remap_one_page(%p,%p,%p %#lx,%p,%d)\n",
|
||||
arg0, pt, ptep, *ptep, pgaddr, pgshift);
|
||||
|
||||
/* XXX: NYI: large pages */
|
||||
if (pgsize != PAGE_SIZE) {
|
||||
error = -E2BIG;
|
||||
ekprintf("remap_one_page(%p,%p,%p %#lx,%p,%d):%d\n",
|
||||
arg0, pt, ptep, *ptep, pgaddr, pgshift, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
off = args->off + ((uintptr_t)pgaddr - args->start);
|
||||
pte_make_fileoff(off, 0, pgsize, &apte);
|
||||
|
||||
@ -1509,6 +1527,7 @@ int remap_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
{
|
||||
struct rfp_args args;
|
||||
int error;
|
||||
unsigned int retval;
|
||||
|
||||
dkprintf("remap_process_memory_range(%p,%p,%#lx,%#lx,%#lx)\n",
|
||||
vm, range, start, end, off);
|
||||
@ -1519,6 +1538,13 @@ int remap_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
args.off = off;
|
||||
args.memobj = range->memobj;
|
||||
|
||||
retval = __sync_val_compare_and_swap(&range->pgshift, 0, PAGE_SHIFT);
|
||||
if (retval != 0 && retval != PAGE_SHIFT) {
|
||||
error = -E2BIG;
|
||||
ekprintf("%s: pgshift is too big (%d) failed:%d\n", __func__, retval, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = visit_pte_range(vm->address_space->page_table, (void *)start,
|
||||
(void *)end, range->pgshift, VPTEF_DEFAULT,
|
||||
&remap_one_page, &args);
|
||||
@ -1765,7 +1791,7 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
off = pte_get_off(ptep, pgsize);
|
||||
}
|
||||
error = memobj_get_page(range->memobj, off, p2align,
|
||||
&phys, &memobj_flag);
|
||||
&phys, &memobj_flag, fault_addr);
|
||||
if (error) {
|
||||
struct memobj *obj;
|
||||
|
||||
@ -1787,7 +1813,7 @@ retry:
|
||||
npages = pgsize / PAGE_SIZE;
|
||||
virt = ihk_mc_alloc_aligned_pages_user(npages, p2align,
|
||||
IHK_MC_AP_NOWAIT |
|
||||
(range->flag & VR_AP_USER) ? IHK_MC_AP_USER : 0);
|
||||
((range->flag & VR_AP_USER) ? IHK_MC_AP_USER : 0), fault_addr);
|
||||
if (!virt && !range->pgshift && (pgsize != PAGE_SIZE)) {
|
||||
error = arch_get_smaller_page_size(NULL, pgsize, &pgsize, &p2align);
|
||||
if (error) {
|
||||
@ -1847,7 +1873,7 @@ retry:
|
||||
|
||||
npages = pgsize / PAGE_SIZE;
|
||||
virt = ihk_mc_alloc_aligned_pages_user(npages, p2align,
|
||||
IHK_MC_AP_NOWAIT);
|
||||
IHK_MC_AP_NOWAIT, fault_addr);
|
||||
if (!virt) {
|
||||
error = -ENOMEM;
|
||||
kprintf("page_fault_process_memory_range(%p,%lx-%lx %lx,%lx,%lx):cannot allocate copy page. %d\n", vm, range->start, range->end, range->flag, fault_addr, reason, error);
|
||||
@ -1936,9 +1962,6 @@ retry:
|
||||
// memory_stat_rss_add() is called in downstream with !memobj check
|
||||
}
|
||||
flush_tlb_single(fault_addr);
|
||||
vm->currss += pgsize;
|
||||
if(vm->currss > vm->proc->maxrss)
|
||||
vm->proc->maxrss = vm->currss;
|
||||
|
||||
error = 0;
|
||||
page = NULL;
|
||||
@ -2123,6 +2146,8 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
struct process *proc = thread->proc;
|
||||
unsigned long ap_flag;
|
||||
struct vm_range *range;
|
||||
int stack_populated_size = 0;
|
||||
int stack_align_padding = 0;
|
||||
|
||||
/* Create stack range */
|
||||
end = STACK_TOP(&thread->vm->region) & LARGE_PAGE_MASK;
|
||||
@ -2156,7 +2181,7 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
ap_flag ? "(IHK_MC_AP_USER)" : "");
|
||||
|
||||
stack = ihk_mc_alloc_aligned_pages_user(minsz >> PAGE_SHIFT,
|
||||
LARGE_PAGE_P2ALIGN, IHK_MC_AP_NOWAIT | ap_flag);
|
||||
LARGE_PAGE_P2ALIGN, IHK_MC_AP_NOWAIT | ap_flag, start);
|
||||
|
||||
if (!stack) {
|
||||
kprintf("%s: error: couldn't allocate initial stack\n",
|
||||
@ -2194,22 +2219,29 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
return error;
|
||||
}
|
||||
|
||||
// memory_stat_rss_add() is called in ihk_mc_pt_set_range();
|
||||
/* Pre-compute populated size so that we can align stack
|
||||
* and verify the size at the end */
|
||||
stack_align_padding = 0;
|
||||
stack_populated_size = 16 /* Random */ +
|
||||
AUXV_LEN * sizeof(unsigned long) /* AUXV */ +
|
||||
(argc + 2) * sizeof(unsigned long) /* args + term NULL + argc */ +
|
||||
(envc + 1) * sizeof(unsigned long); /* envs + term NULL */
|
||||
|
||||
/* set up initial stack frame */
|
||||
p = (unsigned long *)(stack + minsz);
|
||||
s_ind = -1;
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_15 /* userstack 16byte align */
|
||||
if(!((envc + argc) % 2)){
|
||||
p[s_ind--] = 0;
|
||||
/* Align stack to 64 bytes */
|
||||
while ((unsigned long)(stack + minsz -
|
||||
stack_populated_size - stack_align_padding) & (0x40L - 1)) {
|
||||
s_ind--;
|
||||
stack_align_padding += sizeof(unsigned long);
|
||||
}
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_15 */
|
||||
|
||||
/* "random" 16 bytes on the very top */
|
||||
p[s_ind--] = 0x010101011;
|
||||
p[s_ind--] = 0x010101011;
|
||||
at_rand = end + sizeof(unsigned long) * s_ind;
|
||||
at_rand = end + (s_ind + 1) * sizeof(unsigned long);
|
||||
|
||||
/* auxiliary vector */
|
||||
/* If you add/delete entires, please increase/decrease
|
||||
@ -2261,6 +2293,20 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
/* argc */
|
||||
p[s_ind] = argc;
|
||||
|
||||
if (((void *)&p[s_ind] != (void *)stack + minsz -
|
||||
stack_populated_size - stack_align_padding)) {
|
||||
kprintf("%s: WARNING: stack_populated_size mismatch (is AUXV_LEN up-to-date?): "
|
||||
"&p[s_ind]: %lu, computed: %lu\n",
|
||||
__FUNCTION__,
|
||||
(unsigned long)&p[s_ind],
|
||||
(unsigned long)stack + minsz -
|
||||
stack_populated_size - stack_align_padding);
|
||||
}
|
||||
|
||||
if ((unsigned long)&p[s_ind] & (0x40L - 1)) {
|
||||
kprintf("%s: WARNING: stack alignment mismatch\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
ihk_mc_modify_user_context(thread->uctx, IHK_UCR_STACK_POINTER,
|
||||
end + sizeof(unsigned long) * s_ind);
|
||||
thread->vm->region.stack_end = end;
|
||||
@ -2300,7 +2346,7 @@ unsigned long extend_process_region(struct process_vm *vm,
|
||||
p = ihk_mc_alloc_aligned_pages_user(
|
||||
(new_end_allocated - end_allocated) >> PAGE_SHIFT,
|
||||
align_p2align, IHK_MC_AP_NOWAIT |
|
||||
(!(vm->proc->mpol_flags & MPOL_NO_HEAP) ? IHK_MC_AP_USER : 0));
|
||||
(!(vm->proc->mpol_flags & MPOL_NO_HEAP) ? IHK_MC_AP_USER : 0), end_allocated);
|
||||
|
||||
if (!p) {
|
||||
return end_allocated;
|
||||
@ -2542,14 +2588,15 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
void hold_thread(struct thread *thread)
|
||||
int hold_thread(struct thread *thread)
|
||||
{
|
||||
if (thread->status == PS_EXITED) {
|
||||
panic("hold_thread: already exited process");
|
||||
kprintf("hold_thread: ERROR: already exited process,tid=%d\n", thread->tid);
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
ihk_atomic_inc(&thread->refcount);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2596,21 +2643,30 @@ void destroy_thread(struct thread *thread)
|
||||
{
|
||||
struct sig_pending *pending;
|
||||
struct sig_pending *signext;
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
struct mcs_rwlock_node_irqsave lock, updatelock;
|
||||
struct process *proc = thread->proc;
|
||||
struct resource_set *resource_set = cpu_local_var(resource_set);
|
||||
int hash;
|
||||
struct timespec ats;
|
||||
|
||||
hash = thread_hash(thread->tid);
|
||||
mcs_rwlock_writer_lock(&resource_set->thread_hash->lock[hash], &lock);
|
||||
list_del(&thread->hash_list);
|
||||
mcs_rwlock_writer_unlock(&resource_set->thread_hash->lock[hash], &lock);
|
||||
|
||||
mcs_rwlock_writer_lock(&proc->update_lock, &updatelock);
|
||||
tsc_to_ts(thread->system_tsc, &ats);
|
||||
ts_add(&thread->proc->stime, &ats);
|
||||
tsc_to_ts(thread->user_tsc, &ats);
|
||||
ts_add(&thread->proc->utime, &ats);
|
||||
|
||||
mcs_rwlock_writer_lock(&proc->threads_lock, &lock);
|
||||
list_del(&thread->siblings_list);
|
||||
__release_tid(proc, thread);
|
||||
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
||||
|
||||
mcs_rwlock_writer_unlock(&proc->update_lock, &updatelock);
|
||||
|
||||
cpu_clear(thread->cpu_id, &thread->vm->address_space->cpu_set,
|
||||
&thread->vm->address_space->cpu_set_lock);
|
||||
list_for_each_entry_safe(pending, signext, &thread->sigpending, list){
|
||||
@ -2639,20 +2695,11 @@ void destroy_thread(struct thread *thread)
|
||||
void release_thread(struct thread *thread)
|
||||
{
|
||||
struct process_vm *vm;
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
struct timespec ats;
|
||||
|
||||
if (!ihk_atomic_dec_and_test(&thread->refcount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mcs_rwlock_writer_lock(&thread->proc->update_lock, &lock);
|
||||
tsc_to_ts(thread->system_tsc, &ats);
|
||||
ts_add(&thread->proc->stime, &ats);
|
||||
tsc_to_ts(thread->user_tsc, &ats);
|
||||
ts_add(&thread->proc->utime, &ats);
|
||||
mcs_rwlock_writer_unlock(&thread->proc->update_lock, &lock);
|
||||
|
||||
vm = thread->vm;
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
@ -2891,7 +2938,7 @@ void sched_init(void)
|
||||
ihk_mc_init_context(&idle_thread->ctx, NULL, idle);
|
||||
ihk_mc_spinlock_init(&idle_thread->vm->memory_range_lock);
|
||||
idle_thread->vm->vm_range_tree = RB_ROOT;
|
||||
INIT_LIST_HEAD(&idle_thread->vm->vm_range_numa_policy_list);
|
||||
idle_thread->vm->vm_range_numa_policy_tree = RB_ROOT;
|
||||
idle_thread->proc->pid = 0;
|
||||
idle_thread->tid = ihk_mc_get_processor_id();
|
||||
|
||||
@ -3044,6 +3091,12 @@ void spin_sleep_or_schedule(void)
|
||||
int woken = 0;
|
||||
long irqstate;
|
||||
|
||||
/* Spinning disabled explicitly */
|
||||
if (idle_halt) {
|
||||
dkprintf("%s: idle_halt -> schedule()\n", __FUNCTION__);
|
||||
goto out_schedule;
|
||||
}
|
||||
|
||||
/* Try to spin sleep */
|
||||
irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock);
|
||||
if (thread->spin_sleep == 0) {
|
||||
@ -3092,6 +3145,7 @@ void spin_sleep_or_schedule(void)
|
||||
cpu_pause();
|
||||
}
|
||||
|
||||
out_schedule:
|
||||
schedule();
|
||||
}
|
||||
|
||||
@ -3109,6 +3163,9 @@ void schedule(void)
|
||||
}
|
||||
|
||||
redo:
|
||||
/* Reset for redo */
|
||||
switch_ctx = 0;
|
||||
|
||||
cpu_local_var(runq_irqstate) =
|
||||
ihk_mc_spinlock_lock(&(get_this_cpu_local_var()->runq_lock));
|
||||
v = get_this_cpu_local_var();
|
||||
@ -3130,7 +3187,10 @@ redo:
|
||||
}
|
||||
}
|
||||
|
||||
if (v->flags & CPU_FLAG_NEED_MIGRATE) {
|
||||
/* Switch to idle() when prev is PS_EXITED since it always reaches release_thread()
|
||||
because it always resumes from just after ihk_mc_switch_context() call. See #1029 */
|
||||
if (v->flags & CPU_FLAG_NEED_MIGRATE ||
|
||||
prev->status == PS_EXITED) {
|
||||
next = &cpu_local_var(idle);
|
||||
} else {
|
||||
/* Pick a new running process or one that has a pending signal */
|
||||
|
||||
@ -358,7 +358,7 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
|
||||
* 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
|
||||
*/
|
||||
written_now = snprintf(_buf, left,
|
||||
"%lx-%lx %s%s%s%s %lx %lx:%lx %d %s\n",
|
||||
"%012lx-%012lx %s%s%s%s %lx %lx:%lx %d\t\t\t%s\n",
|
||||
range->start, range->end,
|
||||
range->flag & VR_PROT_READ ? "r" : "-",
|
||||
range->flag & VR_PROT_WRITE ? "w" : "-",
|
||||
@ -369,6 +369,15 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
|
||||
0UL,
|
||||
0UL,
|
||||
0,
|
||||
range->memobj && range->memobj->path ? range->memobj->path :
|
||||
range->start ==
|
||||
(unsigned long)vm->vdso_addr ? "[vdso]" :
|
||||
range->start ==
|
||||
(unsigned long)vm->vvar_addr ? "[vsyscall]" :
|
||||
range->flag & VR_STACK ? "[stack]" :
|
||||
range->start >= vm->region.brk_start &&
|
||||
range->end <= vm->region.brk_end_allocated ?
|
||||
"[heap]" :
|
||||
""
|
||||
);
|
||||
|
||||
@ -410,7 +419,7 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
|
||||
}
|
||||
kfree(tmp);
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_47 */
|
||||
ans = written + 1;
|
||||
ans = written;
|
||||
eof = 1;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
|
||||
goto end;
|
||||
@ -422,12 +431,6 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
|
||||
if (strcmp(p, "pagemap") == 0) {
|
||||
uint64_t *_buf = (uint64_t *)buf;
|
||||
uint64_t start, end;
|
||||
|
||||
if (offset < PAGE_SIZE) {
|
||||
kprintf("WARNING: /proc/pagemap queried for NULL page\n");
|
||||
ans = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Check alignment */
|
||||
if ((offset % sizeof(uint64_t) != 0) ||
|
||||
|
||||
@ -374,7 +374,7 @@ static void shmobj_ref(struct memobj *memobj)
|
||||
}
|
||||
|
||||
static int shmobj_get_page(struct memobj *memobj, off_t off, int p2align,
|
||||
uintptr_t *physp, unsigned long *pflag)
|
||||
uintptr_t *physp, unsigned long *pflag, uintptr_t virt_addr)
|
||||
{
|
||||
struct shmobj *obj = to_shmobj(memobj);
|
||||
int error;
|
||||
@ -415,7 +415,7 @@ static int shmobj_get_page(struct memobj *memobj, off_t off, int p2align,
|
||||
if (!page) {
|
||||
npages = 1 << p2align;
|
||||
virt = ihk_mc_alloc_aligned_pages_user(npages, p2align,
|
||||
IHK_MC_AP_NOWAIT);
|
||||
IHK_MC_AP_NOWAIT, virt_addr);
|
||||
if (!virt) {
|
||||
error = -ENOMEM;
|
||||
ekprintf("shmobj_get_page(%p,%#lx,%d,%p):"
|
||||
|
||||
499
kernel/syscall.c
499
kernel/syscall.c
@ -113,6 +113,7 @@ static ihk_spinlock_t tod_data_lock = SPIN_LOCK_UNLOCKED;
|
||||
static void calculate_time_from_tsc(struct timespec *ts);
|
||||
|
||||
void check_signal(unsigned long, void *, int);
|
||||
void save_syscall_return_value(int num, unsigned long rc);
|
||||
void do_signal(long rc, void *regs, struct thread *thread, struct sig_pending *pending, int num);
|
||||
extern unsigned long do_kill(struct thread *thread, int pid, int tid, int sig, struct siginfo *info, int ptracecont);
|
||||
extern long alloc_debugreg(struct thread *thread);
|
||||
@ -319,10 +320,10 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
|
||||
flags = cpu_disable_interrupt_save();
|
||||
|
||||
/* Try to sleep until notified */
|
||||
if (__sync_bool_compare_and_swap(&res.req_thread_status,
|
||||
IHK_SCD_REQ_THREAD_SPINNING,
|
||||
IHK_SCD_REQ_THREAD_DESCHEDULED)) {
|
||||
|
||||
if (res.req_thread_status == IHK_SCD_REQ_THREAD_DESCHEDULED ||
|
||||
__sync_bool_compare_and_swap(&res.req_thread_status,
|
||||
IHK_SCD_REQ_THREAD_SPINNING,
|
||||
IHK_SCD_REQ_THREAD_DESCHEDULED)) {
|
||||
dkprintf("%s: tid %d waiting for syscall reply...\n",
|
||||
__FUNCTION__, thread->tid);
|
||||
waitq_init(&thread->scd_wq);
|
||||
@ -459,16 +460,10 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
|
||||
|
||||
/* -ERESTARTSYS indicates that the proxy process is gone
|
||||
* and the application should be terminated */
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_70 /* interrupt_syscall returned -ERESTARTSYS fix */
|
||||
if (rc == -ERESTARTSYS && req->number != __NR_exit_group
|
||||
&& req->number != __NR_kill) {
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_70 */
|
||||
if (rc == -ERESTARTSYS && req->number != __NR_exit_group) {
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_70 */
|
||||
if (rc == -ERESTARTSYS) {
|
||||
kprintf("%s: proxy PID %d is dead, terminate()\n",
|
||||
__FUNCTION__, thread->proc->pid);
|
||||
thread->proc->nohost = 1;
|
||||
terminate(0, SIGKILL);
|
||||
}
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
@ -674,21 +669,12 @@ do_wait(int pid, int *status, int options, void *rusage)
|
||||
|
||||
mcs_rwlock_writer_lock_noirq(&thread->proc->children_lock, &lock);
|
||||
list_for_each_entry_safe(child, next, &proc->children_list, siblings_list) {
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_44 /* wait() add support __WALL */
|
||||
/*
|
||||
if (!(options & __WALL)) {
|
||||
if (!(!!(options & __WCLONE) ^ (child->termsig == SIGCHLD))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_44 */
|
||||
/*
|
||||
if (!(!!(options & __WCLONE) ^ (child->termsig == SIGCHLD))) {
|
||||
if (!(options & __WALL) &&
|
||||
!(!!(options & __WCLONE) ^ (child->termsig == SIGCHLD))) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_44 */
|
||||
|
||||
/* Find thread with pid == tid, this will be either the main thread
|
||||
* or the one we are looking for specifically when __WCLONE is passed */
|
||||
@ -887,11 +873,7 @@ SYSCALL_DECLARE(wait4)
|
||||
int rc;
|
||||
struct rusage usage;
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_44 /* wait() add support __WALL */
|
||||
if(options & ~(WNOHANG | WUNTRACED | WCONTINUED | __WCLONE | __WALL)){
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_44 */
|
||||
if(options & ~(WNOHANG | WUNTRACED | WCONTINUED | __WCLONE)){
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_44 */
|
||||
dkprintf("wait4: unexpected options(%x).\n", options);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -923,11 +905,7 @@ SYSCALL_DECLARE(waitid)
|
||||
pid = -1;
|
||||
else
|
||||
return -EINVAL;
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_44 /* wait() add support __WALL */
|
||||
if(options & ~(WEXITED | WSTOPPED | WCONTINUED | WNOHANG | WNOWAIT | __WCLONE | __WALL)){
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_44 */
|
||||
if(options & ~(WEXITED | WSTOPPED | WCONTINUED | WNOHANG | WNOWAIT | __WCLONE)){
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_44 */
|
||||
dkprintf("wait4: unexpected options(%x).\n", options);
|
||||
dkprintf("waitid: unexpected options(%x).\n", options);
|
||||
return -EINVAL;
|
||||
@ -963,6 +941,28 @@ SYSCALL_DECLARE(waitid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void terminate_mcexec(int rc, int sig)
|
||||
{
|
||||
unsigned long old_exit_status;
|
||||
unsigned long exit_status;
|
||||
struct thread *mythread = cpu_local_var(current);
|
||||
struct process *proc = mythread->proc;
|
||||
struct syscall_request request IHK_DMA_ALIGN;
|
||||
|
||||
if ((old_exit_status = proc->exit_status) & 0x0000000100000000L)
|
||||
return;
|
||||
exit_status = 0x0000000100000000L | ((rc & 0x00ff) << 8) | (sig & 0xff);
|
||||
if (!__sync_bool_compare_and_swap(&proc->exit_status,
|
||||
old_exit_status, exit_status))
|
||||
return;
|
||||
if (!proc->nohost) {
|
||||
request.number = __NR_exit_group;
|
||||
request.args[0] = proc->exit_status;
|
||||
proc->nohost = 1;
|
||||
do_syscall(&request, ihk_mc_get_processor_id(), proc->pid);
|
||||
}
|
||||
}
|
||||
|
||||
void terminate(int rc, int sig)
|
||||
{
|
||||
struct resource_set *resource_set = cpu_local_var(resource_set);
|
||||
@ -980,7 +980,6 @@ void terminate(int rc, int sig)
|
||||
int i;
|
||||
int n;
|
||||
int *ids = NULL;
|
||||
struct syscall_request request IHK_DMA_ALIGN;
|
||||
int exit_status;
|
||||
|
||||
// sync perf info
|
||||
@ -988,13 +987,15 @@ void terminate(int rc, int sig)
|
||||
sync_child_event(proc->monitoring_event);
|
||||
|
||||
// clean up threads
|
||||
mcs_rwlock_reader_lock(&proc->threads_lock, &lock); // conflict clone
|
||||
mcs_rwlock_writer_lock_noirq(&proc->update_lock, &updatelock);
|
||||
mcs_rwlock_writer_lock(&proc->threads_lock, &lock); // conflict clone
|
||||
if (proc->status == PS_EXITED) {
|
||||
mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock);
|
||||
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
||||
dkprintf("%s: PID: %d, TID: %d PS_EXITED already\n",
|
||||
__FUNCTION__, proc->pid, mythread->tid);
|
||||
preempt_disable();
|
||||
mythread->status = PS_EXITED;
|
||||
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
||||
mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock);
|
||||
release_thread(mythread);
|
||||
preempt_enable();
|
||||
schedule();
|
||||
@ -1002,10 +1003,15 @@ void terminate(int rc, int sig)
|
||||
return;
|
||||
}
|
||||
|
||||
exit_status = mythread->exit_status = ((rc & 0x00ff) << 8) | (sig & 0xff);
|
||||
dkprintf("%s: PID: %d, TID: %d setting PS_EXITED\n",
|
||||
__FUNCTION__, proc->pid, mythread->tid);
|
||||
exit_status = ((rc & 0x00ff) << 8) | (sig & 0xff);
|
||||
mythread->exit_status = exit_status;
|
||||
proc->status = PS_EXITED;
|
||||
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
||||
mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock);
|
||||
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
||||
|
||||
terminate_mcexec(rc, sig);
|
||||
|
||||
mcs_rwlock_writer_lock(&proc->threads_lock, &lock);
|
||||
list_del(&mythread->siblings_list);
|
||||
@ -1151,23 +1157,13 @@ void terminate(int rc, int sig)
|
||||
#endif
|
||||
|
||||
// clean up memory
|
||||
if (!proc->nohost) {
|
||||
request.number = __NR_exit_group;
|
||||
request.args[0] = exit_status;
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_48 /* nohost flag missed fix */
|
||||
proc->nohost = 1;
|
||||
do_syscall(&request, ihk_mc_get_processor_id(), proc->pid);
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_48 */
|
||||
do_syscall(&request, ihk_mc_get_processor_id(), proc->pid);
|
||||
proc->nohost = 1;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_48 */
|
||||
}
|
||||
|
||||
proc->exit_status = exit_status;
|
||||
finalize_process(proc);
|
||||
|
||||
preempt_disable();
|
||||
mcs_rwlock_writer_lock(&proc->threads_lock, &lock);
|
||||
mythread->status = PS_EXITED;
|
||||
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
||||
release_thread(mythread);
|
||||
release_process_vm(vm);
|
||||
preempt_enable();
|
||||
@ -1479,7 +1475,7 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
|
||||
maxprot = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||
if (!(flags & MAP_ANONYMOUS)) {
|
||||
off = off0;
|
||||
error = fileobj_create(fd, &memobj, &maxprot);
|
||||
error = fileobj_create(fd, &memobj, &maxprot, addr0);
|
||||
#ifdef ATTACHED_MIC
|
||||
/*
|
||||
* XXX: refuse device mapping in attached-mic now:
|
||||
@ -1542,7 +1538,7 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
|
||||
}
|
||||
|
||||
p = ihk_mc_alloc_aligned_pages_user(npages, p2align,
|
||||
IHK_MC_AP_NOWAIT | ap_flag);
|
||||
IHK_MC_AP_NOWAIT | ap_flag, addr0);
|
||||
if (p == NULL) {
|
||||
dkprintf("%s: warning: failed to allocate %d contiguous pages "
|
||||
" (bytes: %lu, pgshift: %d), enabling demand paging\n",
|
||||
@ -1966,9 +1962,7 @@ static void settid(struct thread *thread, int nr_tids, int *tids)
|
||||
int ret;
|
||||
struct syscall_request request IHK_DMA_ALIGN;
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_58 /* settid() arguments area 0 clear add. */
|
||||
memset(&request, 0, sizeof(request));
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_58 */
|
||||
|
||||
request.number = __NR_gettid;
|
||||
/*
|
||||
@ -2141,6 +2135,9 @@ static void munmap_all(void)
|
||||
/* free vm_ranges which do_munmap() failed to remove. */
|
||||
free_process_memory_ranges(thread->vm);
|
||||
|
||||
/* reset vm_region's map area */
|
||||
thread->vm->region.map_end = thread->vm->region.map_start;
|
||||
|
||||
return;
|
||||
} /* munmap_all() */
|
||||
|
||||
@ -2152,11 +2149,9 @@ SYSCALL_DECLARE(execve)
|
||||
{
|
||||
int error;
|
||||
long ret;
|
||||
char *empty_envp[1] = {NULL};
|
||||
const char *filename = (const char *)ihk_mc_syscall_arg0(ctx);
|
||||
char **argv = (char **)ihk_mc_syscall_arg1(ctx);
|
||||
char **envp = (char **)ihk_mc_syscall_arg2(ctx) ?
|
||||
(char **)ihk_mc_syscall_arg2(ctx) : empty_envp;
|
||||
char **envp = (char **)ihk_mc_syscall_arg2(ctx);
|
||||
|
||||
char *argv_flat = NULL;
|
||||
int argv_flat_len = 0;
|
||||
@ -2202,13 +2197,8 @@ SYSCALL_DECLARE(execve)
|
||||
if (ret != 0) {
|
||||
dkprintf("execve(): ERROR: host failed to load elf header, errno: %d\n",
|
||||
ret);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_10 /* sys_execve() memleak fix. */
|
||||
ret = -ret;
|
||||
goto desc_free;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_10 */
|
||||
ihk_mc_free_pages(desc, 4);
|
||||
return -ret;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_10 */
|
||||
goto end;
|
||||
}
|
||||
|
||||
dkprintf("execve(): ELF desc received, num sections: %d\n",
|
||||
@ -2221,7 +2211,7 @@ SYSCALL_DECLARE(execve)
|
||||
/* Flatten argv and envp into kernel-space buffers */
|
||||
argv_flat_len = flatten_strings_from_user(-1, (desc->shell_path[0] ?
|
||||
desc->shell_path : NULL), argv, &argv_flat);
|
||||
if (argv_flat_len == 0) {
|
||||
if (argv_flat_len < 0) {
|
||||
char *kfilename;
|
||||
int len = strlen_user(filename);
|
||||
|
||||
@ -2231,17 +2221,12 @@ SYSCALL_DECLARE(execve)
|
||||
kprintf("ERROR: no argv for executable: %s?\n", kfilename? kfilename: "");
|
||||
if(kfilename)
|
||||
kfree(kfilename);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_10 /* sys_execve() memleak fix. */
|
||||
ret = -EINVAL;
|
||||
goto desc_free;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_10 */
|
||||
ihk_mc_free_pages(desc, 4);
|
||||
return -EINVAL;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_10 */
|
||||
ret = argv_flat_len;
|
||||
goto end;
|
||||
}
|
||||
|
||||
envp_flat_len = flatten_strings_from_user(-1, NULL, envp, &envp_flat);
|
||||
if (envp_flat_len == 0) {
|
||||
if (envp_flat_len < 0) {
|
||||
char *kfilename;
|
||||
int len = strlen_user(filename);
|
||||
|
||||
@ -2251,29 +2236,26 @@ SYSCALL_DECLARE(execve)
|
||||
kprintf("ERROR: no envp for executable: %s?\n", kfilename? kfilename: "");
|
||||
if(kfilename)
|
||||
kfree(kfilename);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_10 /* sys_execve() memleak fix. */
|
||||
ret = -EINVAL;
|
||||
goto argv_free;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_10 */
|
||||
return -EINVAL;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_10 */
|
||||
ret = envp_flat_len;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cpu_local_var(current)->proc->ptrace) {
|
||||
if (thread->proc->ptrace) {
|
||||
ihk_mc_syscall_ret(ctx) = 0;
|
||||
ptrace_syscall_event(cpu_local_var(current));
|
||||
ptrace_syscall_event(thread);
|
||||
}
|
||||
|
||||
/* Unmap all memory areas of the process, userspace will be gone */
|
||||
munmap_all();
|
||||
|
||||
ihk_mc_init_user_process(&cpu_local_var(current)->ctx,
|
||||
&cpu_local_var(current)->uctx,
|
||||
((char *)cpu_local_var(current)) +
|
||||
/* Code assumes no process switch from here on */
|
||||
preempt_disable();
|
||||
ihk_mc_init_user_process(&thread->ctx, &thread->uctx,
|
||||
((char *)thread) +
|
||||
KERNEL_STACK_NR_PAGES * PAGE_SIZE, desc->entry, 0);
|
||||
|
||||
/* Create virtual memory ranges and update args/envs */
|
||||
if (prepare_process_ranges_args_envs(cpu_local_var(current), desc, desc,
|
||||
if (prepare_process_ranges_args_envs(thread, desc, desc,
|
||||
PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER,
|
||||
argv_flat, argv_flat_len, envp_flat, envp_flat_len) != 0) {
|
||||
kprintf("execve(): PANIC: preparing ranges, args, envs, stack\n");
|
||||
@ -2293,11 +2275,8 @@ SYSCALL_DECLARE(execve)
|
||||
request.args[2] = sizeof(struct program_load_desc) +
|
||||
sizeof(struct program_image_section) * desc->num_sections;
|
||||
|
||||
ret = do_syscall(&request, ihk_mc_get_processor_id(), 0);
|
||||
|
||||
if (ret != 0) {
|
||||
kprintf("execve(): PANIC: host failed to load elf image\n");
|
||||
panic("");
|
||||
if ((ret = do_syscall(&request, ihk_mc_get_processor_id(), 0)) != 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
for(i = 0; i < _NSIG; i++){
|
||||
@ -2311,7 +2290,7 @@ SYSCALL_DECLARE(execve)
|
||||
clear_fp_regs(thread);
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_19 */
|
||||
|
||||
error = ptrace_report_exec(cpu_local_var(current));
|
||||
error = ptrace_report_exec(thread);
|
||||
if(error) {
|
||||
kprintf("execve(): ERROR: ptrace_report_exec()\n");
|
||||
}
|
||||
@ -2320,44 +2299,31 @@ SYSCALL_DECLARE(execve)
|
||||
dkprintf("execve(): switching to new process\n");
|
||||
proc->execed = 1;
|
||||
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_10 /* sys_execve() memleak fix. */
|
||||
ret = 0;
|
||||
end:
|
||||
if (envp_flat) {
|
||||
kfree(envp_flat);
|
||||
}
|
||||
|
||||
argv_free:
|
||||
if (argv_flat) {
|
||||
kfree(argv_flat);
|
||||
}
|
||||
|
||||
desc_free:
|
||||
ihk_mc_free_pages(desc, 4);
|
||||
|
||||
if (!ret) {
|
||||
/* Lock run queue because enter_user_mode expects to release it */
|
||||
cpu_local_var(runq_irqstate) =
|
||||
ihk_mc_spinlock_lock(&(get_this_cpu_local_var()->runq_lock));
|
||||
preempt_enable();
|
||||
|
||||
ihk_mc_switch_context(NULL, &cpu_local_var(current)->ctx,
|
||||
cpu_local_var(current));
|
||||
ihk_mc_switch_context(NULL, &thread->ctx, thread);
|
||||
|
||||
/* not reached */
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* no preempt_enable, errors can only happen before we disabled it */
|
||||
|
||||
return ret;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_10 */
|
||||
ihk_mc_free_pages(desc, 4);
|
||||
kfree(argv_flat);
|
||||
kfree(envp_flat);
|
||||
|
||||
/* Lock run queue because enter_user_mode expects to release it */
|
||||
cpu_local_var(runq_irqstate) =
|
||||
ihk_mc_spinlock_lock(&(get_this_cpu_local_var()->runq_lock));
|
||||
|
||||
ihk_mc_switch_context(NULL, &cpu_local_var(current)->ctx,
|
||||
cpu_local_var(current));
|
||||
|
||||
/* Never reach here */
|
||||
return 0;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_10 */
|
||||
}
|
||||
|
||||
unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
@ -2374,6 +2340,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
struct syscall_request request1 IHK_DMA_ALIGN;
|
||||
int ptrace_event = 0;
|
||||
int termsig = clone_flags & 0x000000ff;
|
||||
const struct ihk_mc_cpu_info *cpu_info = ihk_mc_get_cpu_info();
|
||||
|
||||
dkprintf("do_fork,flags=%08x,newsp=%lx,ptidptr=%lx,ctidptr=%lx,tls=%lx,curpc=%lx,cursp=%lx",
|
||||
clone_flags, newsp, parent_tidptr, child_tidptr, tlsblock_base, curpc, cursp);
|
||||
@ -2413,6 +2380,11 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!allow_oversubscribe && rusage->num_threads >= cpu_info->ncpus) {
|
||||
kprintf("%s: ERROR: CPU oversubscription is not allowed. Specify -O option in mcreboot.sh to allow it.\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cpuid = obtain_clone_cpuid(&old->cpu_set);
|
||||
if (cpuid == -1) {
|
||||
kprintf("do_fork,core not available\n");
|
||||
@ -2482,33 +2454,30 @@ retry_tid:
|
||||
}
|
||||
}
|
||||
|
||||
mcs_rwlock_writer_unlock(&newproc->threads_lock, &lock);
|
||||
|
||||
/* TODO: spawn more mcexec threads */
|
||||
if (!new->tid) {
|
||||
release_cpuid(cpuid);
|
||||
kprintf("%s: no more TIDs available\n");
|
||||
panic("");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mcs_rwlock_writer_unlock(&newproc->threads_lock, &lock);
|
||||
}
|
||||
/* fork() a new process on the host */
|
||||
else {
|
||||
request1.number = __NR_fork;
|
||||
request1.number = __NR_clone;
|
||||
request1.args[0] = 0;
|
||||
if(clone_flags & CLONE_PARENT){
|
||||
if(oldproc->ppid_parent->pid != 1)
|
||||
request1.args[0] = clone_flags;
|
||||
}
|
||||
newproc->pid = do_syscall(&request1, ihk_mc_get_processor_id(), 0);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_12 /* __NR_fork retval check fix. */
|
||||
if (newproc->pid < 0) {
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_12 */
|
||||
if (newproc->pid == -1) {
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_12 */
|
||||
kprintf("ERROR: forking host process\n");
|
||||
|
||||
/* TODO: clean-up new */
|
||||
release_cpuid(cpuid);
|
||||
return -EFAULT;
|
||||
return newproc->pid;
|
||||
}
|
||||
|
||||
/* In a single threaded process TID equals to PID */
|
||||
@ -2651,6 +2620,13 @@ retry_tid:
|
||||
old->tid,
|
||||
new->tid);
|
||||
|
||||
if (!(clone_flags & CLONE_VM)) {
|
||||
request1.number = __NR_clone;
|
||||
request1.args[0] = 1;
|
||||
request1.args[1] = new->tid;
|
||||
do_syscall(&request1, ihk_mc_get_processor_id(), 0);
|
||||
}
|
||||
|
||||
runq_add_thread(new, cpuid);
|
||||
|
||||
if (ptrace_event) {
|
||||
@ -2660,11 +2636,6 @@ retry_tid:
|
||||
return new->tid;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(vfork)
|
||||
{
|
||||
return do_fork(CLONE_VFORK|SIGCHLD, 0, 0, 0, 0, ihk_mc_syscall_pc(ctx), ihk_mc_syscall_sp(ctx));
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(set_tid_address)
|
||||
{
|
||||
cpu_local_var(current)->clear_child_tid =
|
||||
@ -3093,6 +3064,13 @@ do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
|
||||
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||
ihk_mc_user_context_t ctx0;
|
||||
|
||||
if (!valid_signal(sig) || sig < 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (act && (sig == SIGKILL || sig == SIGSTOP)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mcs_rwlock_writer_lock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||
k = thread->sigcommon->action + sig - 1;
|
||||
if(oact)
|
||||
@ -3817,6 +3795,57 @@ perf_mmap(struct mckfd *sfd, ihk_mc_user_context_t *ctx)
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct vm_range_numa_policy *vm_range_policy_search(struct process_vm *vm, uintptr_t addr)
|
||||
{
|
||||
struct rb_root *root = &vm->vm_range_numa_policy_tree;
|
||||
struct rb_node *node = root->rb_node;
|
||||
struct vm_range_numa_policy *numa_policy = NULL;
|
||||
|
||||
while (node) {
|
||||
numa_policy = rb_entry(node, struct vm_range_numa_policy, policy_rb_node);
|
||||
if (addr < numa_policy->start) {
|
||||
node = node->rb_left;
|
||||
} else if (addr >= numa_policy->end) {
|
||||
node = node->rb_right;
|
||||
} else {
|
||||
return numa_policy;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int vm_policy_insert(struct process_vm *vm, struct vm_range_numa_policy *newrange)
|
||||
{
|
||||
struct rb_root *root = &vm->vm_range_numa_policy_tree;
|
||||
struct rb_node **new = &(root->rb_node), *parent = NULL;
|
||||
struct vm_range_numa_policy *range;
|
||||
|
||||
while (*new) {
|
||||
range = rb_entry(*new, struct vm_range_numa_policy, policy_rb_node);
|
||||
parent = *new;
|
||||
if (newrange->end <= range->start) {
|
||||
new = &((*new)->rb_left);
|
||||
} else if (newrange->start >= range->end) {
|
||||
new = &((*new)->rb_right);
|
||||
} else {
|
||||
ekprintf("vm_range_insert(%p,%lx-%lx (nodemask)%lx (policy)%d): overlap %lx-%lx (nodemask)%lx (policy)%d\n",
|
||||
vm, newrange->start, newrange->end, newrange->numa_mask, newrange->numa_mem_policy,
|
||||
range->start, range->end, range->numa_mask, range->numa_mem_policy);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
dkprintf("vm_range_insert: %p,%p: %lx-%lx (nodemask)%lx (policy)%d\n",
|
||||
vm, newrange, newrange->start, newrange->end, newrange->numa_mask, newrange->numa_mem_policy);
|
||||
|
||||
rb_link_node(&newrange->policy_rb_node, parent, new);
|
||||
rb_insert_color(&newrange->policy_rb_node, root);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct mc_perf_event*
|
||||
mc_perf_event_alloc(struct perf_event_attr *attr)
|
||||
{
|
||||
@ -3926,7 +3955,7 @@ SYSCALL_DECLARE(perf_event_open)
|
||||
}
|
||||
|
||||
if (not_supported_flag) {
|
||||
return -1;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
event = mc_perf_event_alloc((struct perf_event_attr*)attr);
|
||||
@ -4684,30 +4713,6 @@ struct shminfo the_shminfo = {
|
||||
};
|
||||
struct shm_info the_shm_info = { 0, };
|
||||
|
||||
time_t time(void) {
|
||||
#ifndef POSTK_DEBUG_ARCH_DEP_13 /* arch depend tmp hide */
|
||||
struct syscall_request sreq IHK_DMA_ALIGN;
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_13 */
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_49 /* time() local calculate added. */
|
||||
struct timespec ats;
|
||||
|
||||
if (gettime_local_support) {
|
||||
calculate_time_from_tsc(&ats);
|
||||
return ats.tv_sec;
|
||||
}
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_49 */
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_13 /* arch depend tmp hide */
|
||||
return (time_t)0;
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_13 */
|
||||
sreq.number = __NR_time;
|
||||
sreq.args[0] = (uintptr_t)NULL;
|
||||
return (time_t)do_syscall(&sreq, ihk_mc_get_processor_id(), thread->proc->pid);
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_13 */
|
||||
}
|
||||
|
||||
static int make_shmid(struct shmobj *obj)
|
||||
{
|
||||
return ((int)obj->index << 16) | obj->ds.shm_perm.seq;
|
||||
@ -5475,16 +5480,16 @@ do_exit(int code)
|
||||
FUTEX_WAKE, 1, 0, NULL, 0, 0, 1);
|
||||
}
|
||||
|
||||
mcs_rwlock_reader_lock(&proc->threads_lock, &lock);
|
||||
mcs_rwlock_writer_lock(&proc->threads_lock, &lock);
|
||||
if(proc->status == PS_EXITED){
|
||||
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
||||
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
||||
terminate(exit_status, 0);
|
||||
return;
|
||||
}
|
||||
preempt_disable();
|
||||
thread->status = PS_EXITED;
|
||||
sync_child_event(thread->proc->monitoring_event);
|
||||
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
||||
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
||||
release_thread(thread);
|
||||
preempt_enable();
|
||||
|
||||
@ -5681,15 +5686,8 @@ SYSCALL_DECLARE(getrusage)
|
||||
kusage.ru_maxrss = proc->maxrss / 1024;
|
||||
}
|
||||
else if(who == RUSAGE_CHILDREN){
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_72 /* fix RUSAGE_CHILDREN time */
|
||||
ts_to_tv(&kusage.ru_utime, &proc->utime_children);
|
||||
ts_to_tv(&kusage.ru_stime, &proc->stime_children);
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_72 */
|
||||
tsc_to_ts(thread->user_tsc, &ats);
|
||||
ts_to_tv(&kusage.ru_utime, &ats);
|
||||
tsc_to_ts(thread->system_tsc, &ats);
|
||||
ts_to_tv(&kusage.ru_stime, &ats);
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_72 */
|
||||
|
||||
kusage.ru_maxrss = proc->maxrss_children / 1024;
|
||||
}
|
||||
@ -6095,6 +6093,13 @@ static int ptrace_attach(int pid)
|
||||
error = -ESRCH;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (proc->pid == pid) {
|
||||
thread_unlock(thread, &lock);
|
||||
error = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
child = thread->proc;
|
||||
dkprintf("ptrace_attach(): pid requested:%d, thread->tid:%d, thread->proc->pid=%d, thread->proc->parent=%p\n", pid, thread->tid, thread->proc->pid, thread->proc->parent);
|
||||
|
||||
@ -6112,7 +6117,6 @@ static int ptrace_attach(int pid)
|
||||
}
|
||||
|
||||
parent = child->parent;
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_53 /* attach for child-process fix. */
|
||||
dkprintf("ptrace_attach() parent->pid=%d\n", parent->pid);
|
||||
|
||||
mcs_rwlock_writer_lock_noirq(&parent->children_lock, &childlock);
|
||||
@ -6124,23 +6128,6 @@ static int ptrace_attach(int pid)
|
||||
list_add_tail(&child->siblings_list, &proc->children_list);
|
||||
child->parent = proc;
|
||||
mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &childlock);
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_53 */
|
||||
/* XXX: tmp */
|
||||
if (parent != proc) {
|
||||
|
||||
dkprintf("ptrace_attach() parent->pid=%d\n", parent->pid);
|
||||
|
||||
mcs_rwlock_writer_lock_noirq(&parent->children_lock, &childlock);
|
||||
list_del(&child->siblings_list);
|
||||
list_add_tail(&child->ptraced_siblings_list, &parent->ptraced_children_list);
|
||||
mcs_rwlock_writer_unlock_noirq(&parent->children_lock, &childlock);
|
||||
|
||||
mcs_rwlock_writer_lock_noirq(&proc->children_lock, &childlock);
|
||||
list_add_tail(&child->siblings_list, &proc->children_list);
|
||||
child->parent = proc;
|
||||
mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &childlock);
|
||||
}
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_53 */
|
||||
|
||||
child->ptrace = PT_TRACED | PT_TRACE_EXEC;
|
||||
|
||||
@ -6809,22 +6796,14 @@ SYSCALL_DECLARE(sched_getaffinity)
|
||||
int ret;
|
||||
|
||||
dkprintf("%s() len: %d, mask: %p\n", __FUNCTION__, len, u_cpu_set);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_5 /* sched_getaffinity arguments check add (S64FX_10) */
|
||||
if (len * 8 < num_processors) {
|
||||
kprintf("%s:%d Too small buffer.\n", __FILE__, __LINE__);
|
||||
dkprintf("%s: Too small buffer.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (len & (sizeof(unsigned long)-1)) {
|
||||
kprintf("%s:%d Size not align to unsigned long.\n", __FILE__, __LINE__);
|
||||
dkprintf("%s: Size not align to unsigned long.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_5 */
|
||||
if (!len || u_cpu_set == (cpu_set_t *)-1)
|
||||
return -EINVAL;
|
||||
|
||||
if ((len * BITS_PER_BYTE) < __CPU_SETSIZE)
|
||||
return -EINVAL;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_5 */
|
||||
|
||||
len = MIN2(len, sizeof(k_cpu_set));
|
||||
|
||||
@ -6859,11 +6838,8 @@ SYSCALL_DECLARE(sched_getaffinity)
|
||||
}
|
||||
|
||||
dkprintf("%s() len: %d, ret: %d\n", __FUNCTION__, len, ret);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_58 /* sched_getafifnity return value fix */
|
||||
|
||||
return ret;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_58 */
|
||||
return len;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_58 */
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(get_cpu_id)
|
||||
@ -7728,8 +7704,8 @@ SYSCALL_DECLARE(mremap)
|
||||
const size_t newsize0 = ihk_mc_syscall_arg2(ctx);
|
||||
const int flags = ihk_mc_syscall_arg3(ctx);
|
||||
const uintptr_t newaddr = ihk_mc_syscall_arg4(ctx);
|
||||
const ssize_t oldsize = (oldsize0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
const ssize_t newsize = (newsize0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
const size_t oldsize = (oldsize0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
const size_t newsize = (newsize0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
const uintptr_t oldstart = oldaddr;
|
||||
const uintptr_t oldend = oldstart + oldsize;
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
@ -7748,9 +7724,9 @@ SYSCALL_DECLARE(mremap)
|
||||
oldaddr, oldsize0, newsize0, flags, newaddr);
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
/* check arguments */
|
||||
if ((oldaddr & ~PAGE_MASK)
|
||||
|| (oldsize < 0)
|
||||
|| (newsize <= 0)
|
||||
|| (newsize == 0)
|
||||
|| (flags & ~(MREMAP_MAYMOVE | MREMAP_FIXED))
|
||||
|| ((flags & MREMAP_FIXED)
|
||||
&& !(flags & MREMAP_MAYMOVE))
|
||||
@ -7763,6 +7739,24 @@ SYSCALL_DECLARE(mremap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (oldend < oldstart) {
|
||||
error = -EINVAL;
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"old range overflow. %d\n",
|
||||
oldaddr, oldsize0, newsize0,
|
||||
flags, newaddr, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (newsize > (vm->region.user_end - vm->region.user_start)) {
|
||||
error = -ENOMEM;
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"cannot allocate. %d\n",
|
||||
oldaddr, oldsize0, newsize0,
|
||||
flags, newaddr, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check original mapping */
|
||||
range = lookup_process_memory_range(vm, oldstart, oldstart+PAGE_SIZE);
|
||||
if (!range || (oldstart < range->start) || (range->end < oldend)
|
||||
@ -7777,15 +7771,6 @@ SYSCALL_DECLARE(mremap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (oldend < oldstart) {
|
||||
error = -EINVAL;
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"old range overflow. %d\n",
|
||||
oldaddr, oldsize0, newsize0, flags, newaddr,
|
||||
error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* determine new mapping range */
|
||||
need_relocate = 0;
|
||||
if (flags & MREMAP_FIXED) {
|
||||
@ -8109,8 +8094,7 @@ SYSCALL_DECLARE(mbind)
|
||||
int error = 0;
|
||||
int bit;
|
||||
struct vm_range *range;
|
||||
struct vm_range_numa_policy *range_policy, *range_policy_iter;
|
||||
struct vm_range_numa_policy *range_policy_next = NULL;
|
||||
struct vm_range_numa_policy *range_policy, *range_policy_iter = NULL;
|
||||
DECLARE_BITMAP(numa_mask, PROCESS_NUMA_MASK_BITS);
|
||||
|
||||
dkprintf("%s: addr: 0x%lx, len: %lu, mode: 0x%x, "
|
||||
@ -8321,17 +8305,12 @@ SYSCALL_DECLARE(mbind)
|
||||
case MPOL_INTERLEAVE:
|
||||
case MPOL_PREFERRED:
|
||||
/* Adjust any overlapping range settings and add new one */
|
||||
range_policy_next = NULL;
|
||||
list_for_each_entry(range_policy_iter,
|
||||
&vm->vm_range_numa_policy_list, list) {
|
||||
range_policy_iter = vm_range_policy_search(vm, addr);
|
||||
if (range_policy_iter) {
|
||||
int adjusted = 0;
|
||||
unsigned long orig_end = range_policy_iter->end;
|
||||
|
||||
if (range_policy_iter->end < addr)
|
||||
continue;
|
||||
|
||||
/* Special case of entirely overlapping */
|
||||
if (range_policy_iter->start == addr &&
|
||||
if (range_policy_iter->start == addr &&
|
||||
range_policy_iter->end == addr + len) {
|
||||
range_policy = range_policy_iter;
|
||||
goto mbind_update_only;
|
||||
@ -8348,7 +8327,7 @@ SYSCALL_DECLARE(mbind)
|
||||
if (orig_end > addr + len) {
|
||||
if (adjusted) {
|
||||
/* Add a new entry after */
|
||||
range_policy = kmalloc(sizeof(*range_policy),
|
||||
range_policy = kmalloc(sizeof(struct vm_range_numa_policy),
|
||||
IHK_MC_AP_NOWAIT);
|
||||
if (!range_policy) {
|
||||
dkprintf("%s: error allocating range_policy\n",
|
||||
@ -8357,31 +8336,24 @@ SYSCALL_DECLARE(mbind)
|
||||
goto unlock_out;
|
||||
}
|
||||
|
||||
memcpy(range_policy, range_policy_iter,
|
||||
sizeof(*range_policy));
|
||||
RB_CLEAR_NODE(&range_policy->policy_rb_node);
|
||||
range_policy->start = addr + len;
|
||||
range_policy->end = orig_end;
|
||||
list_add(&range_policy->list,
|
||||
&range_policy_iter->list);
|
||||
range_policy_next = range_policy;
|
||||
break;
|
||||
|
||||
error = vm_policy_insert(vm, range_policy);
|
||||
if (error) {
|
||||
kprintf("%s: ERROR: could not insert range: %d\n",__FUNCTION__, error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
range_policy_iter->start = addr + len;
|
||||
range_policy_next = range_policy_iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Next one in ascending address order? */
|
||||
if (range_policy_iter->start >= addr + len) {
|
||||
range_policy_next = range_policy_iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a new entry */
|
||||
range_policy = kmalloc(sizeof(*range_policy),
|
||||
range_policy = kmalloc(sizeof(struct vm_range_numa_policy),
|
||||
IHK_MC_AP_NOWAIT);
|
||||
if (!range_policy) {
|
||||
dkprintf("%s: error allocating range_policy\n",
|
||||
@ -8390,17 +8362,14 @@ SYSCALL_DECLARE(mbind)
|
||||
goto unlock_out;
|
||||
}
|
||||
|
||||
memset(range_policy, 0, sizeof(*range_policy));
|
||||
RB_CLEAR_NODE(&range_policy->policy_rb_node);
|
||||
range_policy->start = addr;
|
||||
range_policy->end = addr + len;
|
||||
|
||||
if (range_policy_next) {
|
||||
list_add_tail(&range_policy->list,
|
||||
&range_policy_next->list);
|
||||
}
|
||||
else {
|
||||
list_add_tail(&range_policy->list,
|
||||
&vm->vm_range_numa_policy_list);
|
||||
error = vm_policy_insert(vm, range_policy);
|
||||
if (error) {
|
||||
kprintf("%s: ERROR: could not insert range: %d\n",__FUNCTION__, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
mbind_update_only:
|
||||
@ -8441,8 +8410,6 @@ SYSCALL_DECLARE(set_mempolicy)
|
||||
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||
int error = 0;
|
||||
int bit, valid_mask;
|
||||
struct vm_range_numa_policy *range_policy_iter;
|
||||
struct vm_range_numa_policy *range_policy_next = NULL;
|
||||
DECLARE_BITMAP(numa_mask, PROCESS_NUMA_MASK_BITS);
|
||||
|
||||
memset(numa_mask, 0, sizeof(numa_mask));
|
||||
@ -8463,6 +8430,8 @@ SYSCALL_DECLARE(set_mempolicy)
|
||||
}
|
||||
}
|
||||
|
||||
mode &= ~MPOL_MODE_FLAGS;
|
||||
|
||||
switch (mode) {
|
||||
case MPOL_DEFAULT:
|
||||
if (nodemask && nodemask_bits) {
|
||||
@ -8486,6 +8455,13 @@ SYSCALL_DECLARE(set_mempolicy)
|
||||
set_bit(bit, vm->numa_mask);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* In man, "MPOL_DEFAULT mode deletes a process memory policy
|
||||
other than the default and interprets that the memory policy"
|
||||
falls back to the system default policy ", but not to delete
|
||||
the NUMA memory policy.
|
||||
There was no processing of Linux's same name command. */
|
||||
|
||||
/* Delete all range settings */
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
list_for_each_entry_safe(range_policy_iter, range_policy_next,
|
||||
@ -8494,6 +8470,7 @@ SYSCALL_DECLARE(set_mempolicy)
|
||||
kfree(range_policy_iter);
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
#endif
|
||||
|
||||
vm->numa_mem_policy = mode;
|
||||
error = 0;
|
||||
@ -8641,7 +8618,6 @@ SYSCALL_DECLARE(get_mempolicy)
|
||||
|
||||
/* Address range specific? */
|
||||
if (flags & MPOL_F_ADDR) {
|
||||
struct vm_range_numa_policy *range_policy_iter;
|
||||
struct vm_range *range;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
@ -8653,16 +8629,8 @@ SYSCALL_DECLARE(get_mempolicy)
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_for_each_entry(range_policy_iter,
|
||||
&vm->vm_range_numa_policy_list, list) {
|
||||
if (range_policy_iter->start > addr ||
|
||||
range_policy_iter->end <= addr) {
|
||||
continue;
|
||||
}
|
||||
range_policy = vm_range_policy_search(vm, addr);
|
||||
|
||||
range_policy = range_policy_iter;
|
||||
break;
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
}
|
||||
|
||||
@ -9288,6 +9256,7 @@ set_cputime(int mode)
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_disable_interrupt();
|
||||
tsc = rdtsc();
|
||||
if(thread->base_tsc != 0){
|
||||
unsigned long dtsc = tsc - thread->base_tsc;
|
||||
@ -9368,6 +9337,7 @@ set_cputime(int mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
cpu_enable_interrupt();
|
||||
}
|
||||
|
||||
long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
@ -9386,6 +9356,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
#endif // DISABLE_SCHED_YIELD
|
||||
set_cputime(1);
|
||||
|
||||
//kprintf("syscall=%d\n", num);
|
||||
#ifdef PROFILE_ENABLE
|
||||
if (thread->profile && thread->profile_start_ts) {
|
||||
unsigned long ts = rdtsc();
|
||||
@ -9396,6 +9367,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
|
||||
if(cpu_local_var(current)->proc->status == PS_EXITED &&
|
||||
(num != __NR_exit && num != __NR_exit_group)){
|
||||
save_syscall_return_value(num, -EINVAL);
|
||||
check_signal(-EINVAL, NULL, 0);
|
||||
set_cputime(0);
|
||||
return -EINVAL;
|
||||
@ -9456,22 +9428,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
l = ihk_mc_syscall_ret(ctx);
|
||||
}
|
||||
|
||||
#if defined(POSTK_DEBUG_TEMP_FIX_60) && defined(POSTK_DEBUG_TEMP_FIX_56)
|
||||
check_signal(l, NULL, num);
|
||||
#elif defined(POSTK_DEBUG_TEMP_FIX_60) /* sched_yield called check_signal fix. */
|
||||
if (num != __NR_futex) {
|
||||
check_signal(l, NULL, num);
|
||||
}
|
||||
#elif defined(POSTK_DEBUG_TEMP_FIX_56) /* in futex_wait() signal handring fix. */
|
||||
if (num != __NR_sched_yield) {
|
||||
check_signal(l, NULL, num);
|
||||
}
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_60 && POSTK_DEBUG_TEMP_FIX_56 */
|
||||
if (!list_empty(&thread->sigpending) ||
|
||||
!list_empty(&thread->sigcommon->sigpending)) {
|
||||
check_signal(l, NULL, num);
|
||||
}
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_60 && POSTK_DEBUG_TEMP_FIX_56 */
|
||||
save_syscall_return_value(num, l);
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
{
|
||||
@ -9511,10 +9468,20 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
}
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_60 && POSTK_DEBUG_TEMP_FIX_56 */
|
||||
|
||||
if (!list_empty(&thread->sigpending) ||
|
||||
!list_empty(&thread->sigcommon->sigpending)) {
|
||||
check_signal(l, NULL, num);
|
||||
}
|
||||
|
||||
#ifdef DISABLE_SCHED_YIELD
|
||||
if (num != __NR_sched_yield)
|
||||
#endif // DISABLE_SCHED_YIELD
|
||||
set_cputime(0);
|
||||
|
||||
if (thread->proc->nohost) { // mcexec termination was detected
|
||||
terminate(0, SIGKILL);
|
||||
}
|
||||
//kprintf("syscall=%d returns %lx(%ld)\n", num, l, l);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
#include <ihk/mm.h>
|
||||
#include <xpmem_private.h>
|
||||
|
||||
|
||||
struct xpmem_partition *xpmem_my_part = NULL; /* pointer to this partition */
|
||||
|
||||
|
||||
@ -107,6 +106,7 @@ int xpmem_open(
|
||||
mckfd->sig_no = -1;
|
||||
mckfd->ioctl_cb = xpmem_ioctl;
|
||||
mckfd->close_cb = xpmem_close;
|
||||
mckfd->dup_cb = xpmem_dup;
|
||||
mckfd->data = (long)proc;
|
||||
irqstate = ihk_mc_spinlock_lock(&proc->mckfd_lock);
|
||||
|
||||
@ -276,16 +276,11 @@ static int xpmem_ioctl(
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static int xpmem_close(
|
||||
struct mckfd *mckfd,
|
||||
ihk_mc_user_context_t *ctx)
|
||||
{
|
||||
int n_opened;
|
||||
struct process *proc = (struct process *)mckfd->data;
|
||||
struct xpmem_thread_group *tg;
|
||||
int index;
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
|
||||
XPMEM_DEBUG("call: fd=%d, pid=%d, rgid=%d",
|
||||
mckfd->fd, proc->pid, proc->rgid);
|
||||
@ -293,37 +288,11 @@ static int xpmem_close(
|
||||
n_opened = ihk_atomic_dec_return(&xpmem_my_part->n_opened);
|
||||
XPMEM_DEBUG("n_opened=%d", n_opened);
|
||||
|
||||
index = xpmem_tg_hashtable_index(proc->pid);
|
||||
|
||||
mcs_rwlock_writer_lock(&xpmem_my_part->tg_hashtable[index].lock, &lock);
|
||||
|
||||
tg = xpmem_tg_ref_by_tgid_all_nolock(proc->pid);
|
||||
if (IS_ERR(tg)) {
|
||||
mcs_rwlock_writer_unlock(
|
||||
&xpmem_my_part->tg_hashtable[index].lock, &lock);
|
||||
return 0;
|
||||
if (mckfd->data) {
|
||||
/* release my xpmem-objects */
|
||||
xpmem_flush(mckfd);
|
||||
}
|
||||
|
||||
list_del_init(&tg->tg_hashlist);
|
||||
|
||||
mcs_rwlock_writer_unlock(&xpmem_my_part->tg_hashtable[index].lock,
|
||||
&lock);
|
||||
|
||||
XPMEM_DEBUG("tg->vm=0x%p", tg->vm);
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&tg->lock);
|
||||
tg->flags |= XPMEM_FLAG_DESTROYING;
|
||||
ihk_mc_spinlock_unlock_noirq(&tg->lock);
|
||||
|
||||
xpmem_release_aps_of_tg(tg);
|
||||
xpmem_remove_segs_of_tg(tg);
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&tg->lock);
|
||||
tg->flags |= XPMEM_FLAG_DESTROYED;
|
||||
ihk_mc_spinlock_unlock_noirq(&tg->lock);
|
||||
|
||||
xpmem_destroy_tg(tg);
|
||||
|
||||
if (!n_opened) {
|
||||
xpmem_exit();
|
||||
}
|
||||
@ -333,6 +302,15 @@ static int xpmem_close(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xpmem_dup(
|
||||
struct mckfd *mckfd,
|
||||
ihk_mc_user_context_t *ctx)
|
||||
{
|
||||
mckfd->data = 0;
|
||||
ihk_atomic_inc_return(&xpmem_my_part->n_opened);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xpmem_init(void)
|
||||
{
|
||||
@ -987,6 +965,44 @@ static void xpmem_release_aps_of_tg(
|
||||
XPMEM_DEBUG("return: ");
|
||||
}
|
||||
|
||||
static void xpmem_flush(struct mckfd *mckfd)
|
||||
{
|
||||
struct process *proc = (struct process *)mckfd->data;
|
||||
struct xpmem_thread_group *tg;
|
||||
int index;
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
|
||||
index = xpmem_tg_hashtable_index(proc->pid);
|
||||
|
||||
mcs_rwlock_writer_lock(&xpmem_my_part->tg_hashtable[index].lock, &lock);
|
||||
|
||||
tg = xpmem_tg_ref_by_tgid_all_nolock(proc->pid);
|
||||
if (IS_ERR(tg)) {
|
||||
mcs_rwlock_writer_unlock(
|
||||
&xpmem_my_part->tg_hashtable[index].lock, &lock);
|
||||
return;
|
||||
}
|
||||
|
||||
list_del_init(&tg->tg_hashlist);
|
||||
|
||||
mcs_rwlock_writer_unlock(&xpmem_my_part->tg_hashtable[index].lock,
|
||||
&lock);
|
||||
|
||||
XPMEM_DEBUG("tg->vm=0x%p", tg->vm);
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&tg->lock);
|
||||
tg->flags |= XPMEM_FLAG_DESTROYING;
|
||||
ihk_mc_spinlock_unlock_noirq(&tg->lock);
|
||||
|
||||
xpmem_release_aps_of_tg(tg);
|
||||
xpmem_remove_segs_of_tg(tg);
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&tg->lock);
|
||||
tg->flags |= XPMEM_FLAG_DESTROYED;
|
||||
ihk_mc_spinlock_unlock_noirq(&tg->lock);
|
||||
|
||||
xpmem_destroy_tg(tg);
|
||||
}
|
||||
|
||||
static int xpmem_attach(
|
||||
struct mckfd *mckfd,
|
||||
@ -1431,11 +1447,12 @@ static void xpmem_detach_att(
|
||||
att->at_vaddr, att->at_vaddr + 1);
|
||||
|
||||
if (!range || range->start > att->at_vaddr) {
|
||||
DBUG_ON(1);
|
||||
ihk_mc_spinlock_lock_noirq(&ap->lock);
|
||||
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);
|
||||
ekprintf("%s: ERROR: lookup_process_memory_range() failed\n",
|
||||
__FUNCTION__);
|
||||
xpmem_att_destroyable(att);
|
||||
XPMEM_DEBUG("return: range=%p");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ out:
|
||||
}
|
||||
|
||||
static int zeroobj_get_page(struct memobj *memobj, off_t off, int p2align,
|
||||
uintptr_t *physp, unsigned long *pflag)
|
||||
uintptr_t *physp, unsigned long *pflag, uintptr_t virt_addr)
|
||||
{
|
||||
int error;
|
||||
struct zeroobj *obj = to_zeroobj(memobj);
|
||||
|
||||
@ -60,9 +60,9 @@ void ihk_mc_boot_cpu(int cpuid, unsigned long pc);
|
||||
int ihk_mc_get_processor_id(void);
|
||||
int ihk_mc_get_hardware_processor_id(void);
|
||||
int ihk_mc_get_numa_id(void);
|
||||
int ihk_mc_get_nr_cores();
|
||||
int ihk_mc_get_nr_linux_cores();
|
||||
int ihk_mc_get_osnum();
|
||||
int ihk_mc_get_nr_cores(void);
|
||||
int ihk_mc_get_nr_linux_cores(void);
|
||||
int ihk_mc_get_osnum(void);
|
||||
int ihk_mc_get_core(int id, unsigned long *linux_core_id, unsigned long *apic_id,
|
||||
int *numa_id);
|
||||
int ihk_mc_get_ikc_cpu(int id);
|
||||
@ -78,7 +78,7 @@ void ihk_mc_init_context(ihk_mc_kernel_context_t *new_ctx,
|
||||
void (*next_function)(void));
|
||||
|
||||
int ihk_mc_get_extra_reg_id(unsigned long hw_config, unsigned long hw_config_ext);
|
||||
unsigned int ihk_mc_get_nr_extra_regs();
|
||||
unsigned int ihk_mc_get_nr_extra_regs(void);
|
||||
int ihk_mc_get_extra_reg_idx(int id);
|
||||
unsigned int ihk_mc_get_extra_reg_msr(int id);
|
||||
unsigned long ihk_mc_get_extra_reg_event(int id);
|
||||
|
||||
@ -90,7 +90,7 @@ void ihk_mc_reserve_arch_pages(struct ihk_page_allocator_desc *pa_allocator,
|
||||
unsigned long, unsigned long, int));
|
||||
|
||||
struct ihk_mc_pa_ops {
|
||||
void *(*alloc_page)(int, int, ihk_mc_ap_flag, int node, int is_user);
|
||||
void *(*alloc_page)(int, int, ihk_mc_ap_flag, int node, int is_user, uintptr_t virt_addr);
|
||||
void (*free_page)(void *, int, int is_user);
|
||||
|
||||
void *(*alloc)(int, ihk_mc_ap_flag);
|
||||
@ -115,33 +115,33 @@ int ihk_mc_free_micpa(unsigned long mic_pa);
|
||||
void ihk_mc_clean_micpa(void);
|
||||
|
||||
void *_ihk_mc_alloc_aligned_pages_node(int npages, int p2align,
|
||||
ihk_mc_ap_flag flag, int node, int is_user, char *file, int line);
|
||||
ihk_mc_ap_flag flag, int node, int is_user, uintptr_t virt_addr, char *file, int line);
|
||||
#define ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, node) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, node, IHK_MC_PG_KERNEL, __FILE__, __LINE__);\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, node, IHK_MC_PG_KERNEL, -1, __FILE__, __LINE__);\
|
||||
r;\
|
||||
})
|
||||
#define ihk_mc_alloc_aligned_pages_node_user(npages, p2align, flag, node) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, node, IHK_MC_PG_USER, __FILE__, __LINE__);\
|
||||
#define ihk_mc_alloc_aligned_pages_node_user(npages, p2align, flag, node, virt_addr) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, node, IHK_MC_PG_USER, virt_addr, __FILE__, __LINE__);\
|
||||
r;\
|
||||
})
|
||||
|
||||
#define ihk_mc_alloc_aligned_pages(npages, p2align, flag) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, -1, IHK_MC_PG_KERNEL, __FILE__, __LINE__);\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, -1, IHK_MC_PG_KERNEL, -1, __FILE__, __LINE__);\
|
||||
r;\
|
||||
})
|
||||
|
||||
#define ihk_mc_alloc_aligned_pages_user(npages, p2align, flag) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, -1, IHK_MC_PG_USER, __FILE__, __LINE__);\
|
||||
#define ihk_mc_alloc_aligned_pages_user(npages, p2align, flag, virt_addr) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, p2align, flag, -1, IHK_MC_PG_USER, virt_addr, __FILE__, __LINE__);\
|
||||
r;\
|
||||
})
|
||||
|
||||
#define ihk_mc_alloc_pages(npages, flag) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, PAGE_P2ALIGN, flag, -1, IHK_MC_PG_KERNEL, __FILE__, __LINE__);\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, PAGE_P2ALIGN, flag, -1, IHK_MC_PG_KERNEL, -1, __FILE__, __LINE__);\
|
||||
r;\
|
||||
})
|
||||
|
||||
#define ihk_mc_alloc_pages_user(npages, flag) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, PAGE_P2ALIGN, flag, -1, IHK_MC_PG_USER, __FILE__, __LINE__);\
|
||||
#define ihk_mc_alloc_pages_user(npages, flag, virt_addr) ({\
|
||||
void *r = _ihk_mc_alloc_aligned_pages_node(npages, PAGE_P2ALIGN, flag, -1, IHK_MC_PG_USER, virt_addr, __FILE__, __LINE__);\
|
||||
r;\
|
||||
})
|
||||
|
||||
@ -224,7 +224,7 @@ void remote_flush_tlb_array_cpumask(struct process_vm *vm,
|
||||
int cpu_id);
|
||||
|
||||
int ihk_get_kmsg_buf(unsigned long *addr, unsigned long *size);
|
||||
char *ihk_get_kargs();
|
||||
char *ihk_get_kargs(void);
|
||||
|
||||
int ihk_set_monitor(unsigned long addr, unsigned long size);
|
||||
int ihk_set_rusage(unsigned long addr, unsigned long size);
|
||||
|
||||
12
lib/string.c
12
lib/string.c
@ -280,6 +280,18 @@ int flatten_strings_from_user(int nr_strings, char *first, char **strings, char
|
||||
long r;
|
||||
int n, ret;
|
||||
|
||||
/* When strings is NULL, make array one NULL */
|
||||
if (!strings) {
|
||||
full_len = sizeof(long) + sizeof(char *);
|
||||
_flat = kmalloc(full_len, IHK_MC_AP_NOWAIT);
|
||||
if (!_flat) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(_flat, 0, full_len);
|
||||
*flat = (char *)_flat;
|
||||
return full_len;
|
||||
}
|
||||
|
||||
/* How many strings do we have? */
|
||||
if (nr_strings == -1) {
|
||||
nr_strings = 0;
|
||||
|
||||
23
test/dump/README
Normal file
23
test/dump/README
Normal file
@ -0,0 +1,23 @@
|
||||
===================
|
||||
Advance preparation
|
||||
===================
|
||||
1)Implement patch of destroy_mem.patch
|
||||
cd mckernel
|
||||
patch -p0 < destroy_mem.patch
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
2)Compile command execution processing
|
||||
cd mckernel/test/dump/mcexec_test_proc/
|
||||
make
|
||||
|
||||
==========
|
||||
How to run
|
||||
==========
|
||||
#Run McKernel led dump test
|
||||
./go_mck_dump_test.sh
|
||||
|
||||
#Run Linux led dump test
|
||||
./go_linux_dump_test.sh
|
||||
|
||||
13
test/error_handling/Issue1011/1011.patch
Normal file
13
test/error_handling/Issue1011/1011.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c
|
||||
index 2d0d50e..9f109aa 100644
|
||||
--- a/executer/user/mcexec.c
|
||||
+++ b/executer/user/mcexec.c
|
||||
@@ -470,7 +470,7 @@ struct program_load_desc *load_interp(struct program_load_desc *desc0, FILE *fp)
|
||||
j++;
|
||||
}
|
||||
}
|
||||
- desc->num_sections = j;
|
||||
+ desc->num_sections = -1; // Test for num_secionts check Issue#1011
|
||||
|
||||
desc->entry = hdr.e_entry;
|
||||
desc->interp_align = align;
|
||||
17
test/error_handling/Issue1011/README
Normal file
17
test/error_handling/Issue1011/README
Normal file
@ -0,0 +1,17 @@
|
||||
■ Issue#1011 動作確認
|
||||
1. ファイルの説明
|
||||
1011.patch mcexec からmcctrl.ko に渡すprogram_load_des構造体のnum_sections に
|
||||
常に-1 を設定するパッチ
|
||||
|
||||
2. 確認方法
|
||||
1. 上記パッチを適用していない状態でMcKernelを起動する
|
||||
2. mcexec hostname を実行し、ホスト名が表示されることを確認する
|
||||
3. 上記パッチをMcKernelに適用後、ビルドと起動を行う
|
||||
4. mcexec hostname を実行し、ホスト名が表示されず、"prepare: Invalid argument"が
|
||||
コンソールに出力されることを確認する
|
||||
5. /var/log/messages に"kernel: mcexec_prepare_image: ERROR: # of sections: -1"が
|
||||
出力されていることを確認する
|
||||
|
||||
3. 確認結果
|
||||
上記確認方法で期待される動作が確認できたため、問題ない。
|
||||
|
||||
15
test/error_handling/Issue727/727.patch
Normal file
15
test/error_handling/Issue727/727.patch
Normal file
@ -0,0 +1,15 @@
|
||||
diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c
|
||||
index 2d0d50e..70856e7 100644
|
||||
--- a/executer/user/mcexec.c
|
||||
+++ b/executer/user/mcexec.c
|
||||
@@ -3732,7 +3732,9 @@ return_execve1:
|
||||
|
||||
/* Copy program image phase */
|
||||
case 2:
|
||||
-
|
||||
+ fprintf(stderr, "execve killed\n");
|
||||
+ fflush(stderr);
|
||||
+ kill(getpid(), SIGKILL);
|
||||
ret = -1;
|
||||
/* Alloc descriptor */
|
||||
desc = malloc(w.sr.args[2]);
|
||||
17
test/error_handling/Issue727/README
Normal file
17
test/error_handling/Issue727/README
Normal file
@ -0,0 +1,17 @@
|
||||
■ Issue#727 動作確認
|
||||
1. ファイルの説明
|
||||
727.patch 再現確認用パッチ mcexec において、execve phase 2 を SIGKILL
|
||||
終了させる
|
||||
exec.c 確認用テストプログラム exec ls する
|
||||
patch-off.log パッチ非適用時の動作確認結果 ls の結果が表示されれば OK
|
||||
patch-on.log パッチ適用時の動作確認結果 強制終了し、McKernel が PANIC して
|
||||
いなければ OK
|
||||
|
||||
2. 確認用テストプログラムのコンパイル方法
|
||||
gcc -o exec exec.c を行い、実行ファイル exec を得る
|
||||
|
||||
3. 確認結果
|
||||
patch-on.log において、mcexec が強制終了し、McKernelのログに PANIC の表示が
|
||||
無いため、確認結果は OK。
|
||||
また、パッチ非適用時 (patch-off.log)、正常に ls の結果が表示されているので OK。
|
||||
以上より、確認結果は問題無い。
|
||||
10
test/error_handling/Issue727/exec.c
Normal file
10
test/error_handling/Issue727/exec.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
execlp("ls", "ls", NULL);
|
||||
}
|
||||
33
test/error_handling/Issue727/patch-off.log
Normal file
33
test/error_handling/Issue727/patch-off.log
Normal file
@ -0,0 +1,33 @@
|
||||
スクリプトは Wed Nov 29 11:22:32 2017
|
||||
に開始しました[?1034hbash-4.2$ ../../../../mic/mcexec ./exec
|
||||
727.patch exec exec.c patch-off.log
|
||||
bash-4.2$ ../../../../mic/ihkosctl 0kmsg kmsg
|
||||
IHK/McKernel started.
|
||||
[ -1]: no_execute_available: 1
|
||||
[ -1]: X86_IA32_NUM_PERF_COUNTERS: 4, X86_IA32_NUM_FIXED_PERF_COUNTERS: 3
|
||||
[ -1]: Invariant TSC supported.
|
||||
[ -1]: setup_x86 done.
|
||||
[ -1]: ns_per_tsc: 384
|
||||
[ -1]: KCommand Line: hidos dump_level=24
|
||||
[ -1]: Physical memory: 0x1002c7000 - 0x140000000, 1070829568 bytes, 261433 pages available @ NUMA: 0
|
||||
[ -1]: Physical memory: 0x880000000 - 0x8c0000000, 1073741824 bytes, 262144 pages available @ NUMA: 1
|
||||
[ -1]: NUMA: 0, Linux NUMA: 0, type: 1, available bytes: 1070829568, pages: 261433
|
||||
[ -1]: NUMA: 1, Linux NUMA: 1, type: 1, available bytes: 1073741824, pages: 262144
|
||||
[ -1]: NUMA 0 distances: 0 (10), 1 (21),
|
||||
[ -1]: NUMA 1 distances: 1 (10), 0 (21),
|
||||
[ -1]: map_fixed: phys: 0x90000 => 0xffffffff70015000 (2 pages)
|
||||
[ -1]: Trampoline area: 0x90000
|
||||
[ -1]: map_fixed: phys: 0x0 => 0xffffffff70017000 (1 pages)
|
||||
[ -1]: # of cpus : 7
|
||||
[ -1]: locals = ffff8001002eb000
|
||||
[ 0]: BSP: 0 (HW ID: 2 @ NUMA 0)
|
||||
[ 0]: BSP: booted 6 AP CPUs
|
||||
[ 0]: Master channel init acked.
|
||||
[ 0]: vdso is enabled
|
||||
IHK/McKernel booted.
|
||||
|
||||
bash-4.2$ シェルから脱出するには "exit" を使用してください。
|
||||
bash-4.2$ exit
|
||||
|
||||
スクリプトは Wed Nov 29 11:22:57 2017
|
||||
に終了しました
|
||||
35
test/error_handling/Issue727/patch-on.log
Normal file
35
test/error_handling/Issue727/patch-on.log
Normal file
@ -0,0 +1,35 @@
|
||||
スクリプトは Wed Nov 29 11:25:01 2017
|
||||
に開始しました[?1034hbash-4.2$ ../../../../mic/mcexec ./exec
|
||||
execve killed
|
||||
強制終了
|
||||
bash-4.2$ ../../../../mic/ihkosctl 0 kmsg
|
||||
IHK/McKernel started.
|
||||
[ -1]: no_execute_available: 1
|
||||
[ -1]: X86_IA32_NUM_PERF_COUNTERS: 4, X86_IA32_NUM_FIXED_PERF_COUNTERS: 3
|
||||
[ -1]: Invariant TSC supported.
|
||||
[ -1]: setup_x86 done.
|
||||
[ -1]: ns_per_tsc: 384
|
||||
[ -1]: KCommand Line: hidos dump_level=24
|
||||
[ -1]: Physical memory: 0x1002c7000 - 0x140000000, 1070829568 bytes, 261433 pages available @ NUMA: 0
|
||||
[ -1]: Physical memory: 0x880000000 - 0x8c0000000, 1073741824 bytes, 262144 pages available @ NUMA: 1
|
||||
[ -1]: NUMA: 0, Linux NUMA: 0, type: 1, available bytes: 1070829568, pages: 261433
|
||||
[ -1]: NUMA: 1, Linux NUMA: 1, type: 1, available bytes: 1073741824, pages: 262144
|
||||
[ -1]: NUMA 0 distances: 0 (10), 1 (21),
|
||||
[ -1]: NUMA 1 distances: 1 (10), 0 (21),
|
||||
[ -1]: map_fixed: phys: 0x90000 => 0xffffffff70015000 (2 pages)
|
||||
[ -1]: Trampoline area: 0x90000
|
||||
[ -1]: map_fixed: phys: 0x0 => 0xffffffff70017000 (1 pages)
|
||||
[ -1]: # of cpus : 7
|
||||
[ -1]: locals = ffff8001002eb000
|
||||
[ 0]: BSP: 0 (HW ID: 2 @ NUMA 0)
|
||||
[ 0]: BSP: booted 6 AP CPUs
|
||||
[ 0]: Master channel init acked.
|
||||
[ 0]: vdso is enabled
|
||||
IHK/McKernel booted.
|
||||
[ 0]: do_syscall: proxy PID 14276 is dead, terminate()
|
||||
|
||||
bash-4.2$ シェルから脱出するには "exit" を使用してください。
|
||||
bash-4.2$ exit
|
||||
|
||||
スクリプトは Wed Nov 29 11:25:33 2017
|
||||
に終了しました
|
||||
12
test/error_handling/Issue873/README
Normal file
12
test/error_handling/Issue873/README
Normal file
@ -0,0 +1,12 @@
|
||||
■ Issue#873 動作確認
|
||||
1. ファイルの説明
|
||||
mck_boot_test.sh McKernelの停止→起動 を100回繰り返すスクリプト
|
||||
すべてで成功した場合には[OK]メッセージを、途中で失敗した場合には[NG] メッセージを出力する
|
||||
|
||||
2. 確認方法
|
||||
1. mck_boot_test.sh のMCK_DIR にMcKernelのインストールディレクトリを指定する
|
||||
2. sh ./mck_boot_test.sh を実行する
|
||||
3. [OK]メッセージがコンソールに出力されることを確認する
|
||||
|
||||
3. 確認結果
|
||||
上記の確認方法で期待される動作が確認できたため、問題ない。
|
||||
18
test/error_handling/Issue873/mck_boot_test.sh
Executable file
18
test/error_handling/Issue873/mck_boot_test.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
MCK_DIR=/home/satoken/ppos
|
||||
REP_NUM=100
|
||||
|
||||
for i in `seq 1 ${REP_NUM}`
|
||||
do
|
||||
sudo ${MCK_DIR}/sbin/mcstop+release.sh
|
||||
sleep 1
|
||||
sudo ${MCK_DIR}/sbin/mcreboot.sh
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "[NG] failed to boot Mckernel :${i}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "[OK] succeed to boot McKernel ${i} times"
|
||||
38
test/issues/1065/CT_001.sh
Executable file
38
test/issues/1065/CT_001.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_001
|
||||
arg_path=`realpath ./dummy_file`
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
real_path=`realpath ${arg_path}`
|
||||
|
||||
echo "file map: ${arg_path}"
|
||||
|
||||
${MCEXEC} ./file_map ${arg_path} | tee ./${TESTNAME}.log
|
||||
if [ X$? != X0 ]; then
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${real_path} from maps"
|
||||
grep -a -e "${real_path}$" ./${TESTNAME}.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${real_path} is found"
|
||||
else
|
||||
echo "[NG] ${real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
rm ./${TESTNAME}.log
|
||||
38
test/issues/1065/CT_002.sh
Executable file
38
test/issues/1065/CT_002.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_002
|
||||
arg_path=./dummy_file
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
real_path=`realpath ${arg_path}`
|
||||
|
||||
echo "file map: ${arg_path}"
|
||||
|
||||
${MCEXEC} ./file_map ${arg_path} | tee ./${TESTNAME}.log
|
||||
if [ X$? != X0 ]; then
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${real_path} from maps"
|
||||
grep -a -e "${real_path}$" ./${TESTNAME}.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${real_path} is found"
|
||||
else
|
||||
echo "[NG] ${real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
rm ./${TESTNAME}.log
|
||||
38
test/issues/1065/CT_003.sh
Executable file
38
test/issues/1065/CT_003.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_003
|
||||
arg_path=./lnk_to_dummy
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
real_path=`realpath ${arg_path}`
|
||||
|
||||
echo "file map: ${arg_path}"
|
||||
|
||||
${MCEXEC} ./file_map ${arg_path} | tee ./${TESTNAME}.log
|
||||
if [ X$? != X0 ]; then
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${real_path} from maps"
|
||||
grep -a -e "${real_path}$" ./${TESTNAME}.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${real_path} is found"
|
||||
else
|
||||
echo "[NG] ${real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
rm ./${TESTNAME}.log
|
||||
52
test/issues/1065/CT_004.sh
Executable file
52
test/issues/1065/CT_004.sh
Executable file
@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_004
|
||||
test_program=./print_maps
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
real_path=`realpath ${test_program}`
|
||||
interp_path=`readelf -l ${test_program} | grep "interpreter:" | sed -r 's/.*\[.*interpreter:\s(.*)\].*/\1/'`
|
||||
interp_real_path=`realpath ${interp_path}`
|
||||
|
||||
echo "exec : ${test_program}"
|
||||
|
||||
${MCEXEC} ${test_program} | tee ./${TESTNAME}.log
|
||||
if [ X$? != X0 ]; then
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${real_path} from maps"
|
||||
grep -a -e "${real_path}$" ./${TESTNAME}.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${real_path} is found"
|
||||
else
|
||||
echo "[NG] ${real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${interp_real_path} from maps"
|
||||
grep -a -e "${interp_real_path}$" ./${TESTNAME}.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${interp_real_path} is found"
|
||||
else
|
||||
echo "[NG] ${interp_real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
rm ./${TESTNAME}.log
|
||||
53
test/issues/1065/CT_005.sh
Executable file
53
test/issues/1065/CT_005.sh
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_005
|
||||
test_program=./static_print_maps
|
||||
ref_program=./print_maps
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
real_path=`realpath ${test_program}`
|
||||
interp_path=`readelf -l ${ref_program} | grep "interpreter:" | sed -r 's/.*\[.*interpreter:\s(.*)\].*/\1/'`
|
||||
interp_real_path=`realpath ${interp_path}`
|
||||
|
||||
echo "exec : ${test_program}"
|
||||
|
||||
${MCEXEC} ${test_program} | tee ./${TESTNAME}.log
|
||||
if [ X$? != X0 ]; then
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${real_path} from maps"
|
||||
grep -a -e "${real_path}$" ./${TESTNAME}.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${real_path} is found"
|
||||
else
|
||||
echo "[NG] ${real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${interp_real_path} from maps"
|
||||
grep -a -e "${interp_real_path}$" ./${TESTNAME}.log
|
||||
|
||||
if [ X$? != X0 ]; then
|
||||
echo "[OK] ${interp_real_path} is not found"
|
||||
else
|
||||
echo "[NG] ${interp_real_path} is found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
rm ./${TESTNAME}.log
|
||||
23
test/issues/1065/CT_006.sh
Executable file
23
test/issues/1065/CT_006.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_006
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
${MCEXEC} cat /proc/self/maps
|
||||
|
||||
if [ $? = 0 ]; then
|
||||
echo "[OK] shell script is running normaly"
|
||||
else
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
67
test/issues/1065/CT_007.sh
Executable file
67
test/issues/1065/CT_007.sh
Executable file
@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_007
|
||||
exec_program="./print_maps_and_cmdline"
|
||||
test_program="./call_execve ${exec_program}"
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
real_path=`realpath ${exec_program}`
|
||||
interp_path=`readelf -l ${exec_program} | grep "interpreter:" | sed -r 's/.*\[.*interpreter:\s(.*)\].*/\1/'`
|
||||
interp_real_path=`realpath ${interp_path}`
|
||||
|
||||
echo "exec : ${test_program}"
|
||||
|
||||
#${test_program} | tee ./${TESTNAME}.log
|
||||
${MCEXEC} ${test_program} 1> ./${TESTNAME}_maps.log 2> ./${TESTNAME}_cmdline.log
|
||||
if [ X$? != X0 ]; then
|
||||
fail=1
|
||||
fi
|
||||
|
||||
cat ./${TESTNAME}_maps.log
|
||||
echo ""
|
||||
echo "** grep ${real_path} from maps"
|
||||
grep -a -e "${real_path}$" ./${TESTNAME}_maps.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${real_path} is found"
|
||||
else
|
||||
echo "[NG] ${real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${interp_real_path} from maps"
|
||||
grep -a -e "${interp_real_path}$" ./${TESTNAME}_maps.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${interp_real_path} is found"
|
||||
else
|
||||
echo "[NG] ${interp_real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
cat ./${TESTNAME}_cmdline.log
|
||||
echo ""
|
||||
echo "** grep ${exec_program} from cmdline"
|
||||
grep -a -e "${exec_program}" ./${TESTNAME}_cmdline.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${exec_program} is found"
|
||||
else
|
||||
echo "[NG] ${exec_program} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
rm ./${TESTNAME}_maps.log
|
||||
rm ./${TESTNAME}_cmdline.log
|
||||
66
test/issues/1065/CT_008.sh
Executable file
66
test/issues/1065/CT_008.sh
Executable file
@ -0,0 +1,66 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_008
|
||||
exec_program="./print_maps_and_cmdline"
|
||||
test_program="./call_execve.sh ${exec_program}"
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
real_path=`realpath ${exec_program}`
|
||||
interp_path=`readelf -l ${exec_program} | grep "interpreter:" | sed -r 's/.*\[.*interpreter:\s(.*)\].*/\1/'`
|
||||
interp_real_path=`realpath ${interp_path}`
|
||||
|
||||
echo "exec : ${test_program}"
|
||||
|
||||
${MCEXEC} ${test_program} 1> ./${TESTNAME}_maps.log 2> ./${TESTNAME}_cmdline.log
|
||||
if [ X$? != X0 ]; then
|
||||
fail=1
|
||||
fi
|
||||
|
||||
cat ./${TESTNAME}_maps.log
|
||||
echo ""
|
||||
echo "** grep ${real_path} from maps"
|
||||
grep -a -e "${real_path}$" ./${TESTNAME}_maps.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${real_path} is found"
|
||||
else
|
||||
echo "[NG] ${real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "** grep ${interp_real_path} from maps"
|
||||
grep -a -e "${interp_real_path}$" ./${TESTNAME}_maps.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${interp_real_path} is found"
|
||||
else
|
||||
echo "[NG] ${interp_real_path} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
cat ./${TESTNAME}_cmdline.log
|
||||
echo ""
|
||||
echo "** grep ${exec_program} from cmdline"
|
||||
grep -a -e "${exec_program}" ./${TESTNAME}_cmdline.log
|
||||
|
||||
if [ X$? = X0 ]; then
|
||||
echo "[OK] ${exec_program} is found"
|
||||
else
|
||||
echo "[NG] ${exec_program} is not found"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#rm ./${TESTNAME}_maps.log
|
||||
#rm ./${TESTNAME}_cmdline.log
|
||||
0
test/issues/1065/CT_008_cmdline.log
Normal file
0
test/issues/1065/CT_008_cmdline.log
Normal file
3
test/issues/1065/CT_008_maps.log
Normal file
3
test/issues/1065/CT_008_maps.log
Normal file
@ -0,0 +1,3 @@
|
||||
STKN:[main] This is shell script
|
||||
STKN:[main_loop] filename:./call_execve shell:0x(nil)
|
||||
STKN:[main_loop] filename:./print_maps_and_cmdline shell:0x(nil)
|
||||
45
test/issues/1065/Makefile
Normal file
45
test/issues/1065/Makefile
Normal file
@ -0,0 +1,45 @@
|
||||
CC = gcc
|
||||
MCK_DIR=/home/satoken/ppos
|
||||
|
||||
MCEXEC=$(MCK_DIR)/bin/mcexec
|
||||
TARGET= file_map print_maps static_print_maps call_execve print_maps_and_cmdline config
|
||||
|
||||
CPPFLAGS =
|
||||
LDFLAGS =
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
file_map: file_map.c
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
print_maps: print_maps.c
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
print_maps_and_cmdline: print_maps_and_cmdline.c
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
static_print_maps: print_maps.c
|
||||
$(CC) -o $@ $^ $(LDFLAGS) -static
|
||||
|
||||
call_execve: call_execve.c
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
config:
|
||||
@echo "MCEXEC=$(MCEXEC)" > ./config
|
||||
|
||||
init:
|
||||
ln -nfs ./dummy_file ./lnk_to_dummy
|
||||
|
||||
test: init all
|
||||
./CT_001.sh
|
||||
./CT_002.sh
|
||||
./CT_003.sh
|
||||
./CT_004.sh
|
||||
./CT_005.sh
|
||||
./CT_006.sh
|
||||
./CT_007.sh
|
||||
./CT_008.sh
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) *.o ./lnk_to_dummy
|
||||
|
||||
32
test/issues/1065/README
Normal file
32
test/issues/1065/README
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
CT_001:
|
||||
ファイル実体を指す絶対パスを指定したファイルマップを実行する
|
||||
-> /proc/<PID>/maps にファイル実体の絶対パスで表示される
|
||||
|
||||
CT_002:
|
||||
ファイル実体を指す相対パスを指定したファイルマップを実行する
|
||||
-> /proc/<PID>/maps にファイル実体の絶対パスで表示される
|
||||
|
||||
CT_003:
|
||||
ファイル実体を指すシンボリックリンクを指定したファイルマップを実行する
|
||||
-> /proc/<PID>/maps にファイル実体の絶対パスで表示される
|
||||
|
||||
CT_004:
|
||||
ELF形式のプログラムを実行する
|
||||
-> /proc/<PID>/maps に実行したプログラムと、そのinterpの絶対パスが表示される
|
||||
|
||||
CT_005:
|
||||
static linkでビルドされたELF形式のプログラムを実行する
|
||||
-> /proc/<PID>/maps に実行したプログラムと、そのinterpの絶対パスが表示される
|
||||
|
||||
CT_006:
|
||||
シェルスクリプトを実行する
|
||||
-> シェルスクリプトが正しく実行される
|
||||
|
||||
CT_007:
|
||||
execveを行うプログラムを実行する
|
||||
-> execveされたプログラムが正常に実行され、/proc下のmaps, cmdline から新しい情報が取得できる
|
||||
|
||||
CT_008:
|
||||
execveを行うプログラムをシェルスクリプトから実行する
|
||||
-> execveされたプログラムが正常に実行され、/proc下のmaps, cmdline から新しい情報が取得できる
|
||||
28
test/issues/1065/call_execve.c
Normal file
28
test/issues/1065/call_execve.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char* command;
|
||||
char* exargv[] = {NULL, NULL};
|
||||
char* exenvp[] = {NULL};
|
||||
int rc;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Error: too few arguments\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
exargv[0] = argv[1];
|
||||
|
||||
rc = execve(argv[1], exargv, exenvp);
|
||||
|
||||
/* Don't reach here */
|
||||
if (rc == -1) {
|
||||
perror("Error: failed to execve");
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
4
test/issues/1065/call_execve.sh
Executable file
4
test/issues/1065/call_execve.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
./call_execve $*
|
||||
|
||||
1
test/issues/1065/dummy_file
Normal file
1
test/issues/1065/dummy_file
Normal file
@ -0,0 +1 @@
|
||||
This is Test file for mmap.
|
||||
46
test/issues/1065/file_map.c
Normal file
46
test/issues/1065/file_map.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define FILE_SIZE 1024
|
||||
#define CMD_SIZE 128
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int fd;
|
||||
void *file_map;
|
||||
long page_size, file_map_size;
|
||||
char command[CMD_SIZE];
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Error: too few arguments\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = open(argv[1], O_RDWR);
|
||||
|
||||
if (fd < 0) {
|
||||
printf("Error: open %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
page_size = sysconf(_SC_PAGESIZE);
|
||||
file_map_size = (FILE_SIZE / page_size + 1) * page_size;
|
||||
|
||||
file_map = mmap(0, file_map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (file_map == MAP_FAILED) {
|
||||
printf("Error: mmap file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(command, "cat /proc/%d/maps", getpid());
|
||||
system(command);
|
||||
|
||||
close(fd);
|
||||
munmap(file_map, file_map_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
13
test/issues/1065/print_maps.c
Normal file
13
test/issues/1065/print_maps.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char command[128];
|
||||
|
||||
sprintf(command, "cat /proc/%d/maps", getpid());
|
||||
system(command);
|
||||
|
||||
return 0;
|
||||
}
|
||||
21
test/issues/1065/print_maps_and_cmdline.c
Normal file
21
test/issues/1065/print_maps_and_cmdline.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CMD_SIZE 128
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char command[CMD_SIZE];
|
||||
|
||||
memset(command, '0', CMD_SIZE);
|
||||
sprintf(command, "cat /proc/%d/maps", getpid());
|
||||
system(command);
|
||||
|
||||
memset(command, '0', CMD_SIZE);
|
||||
sprintf(command, "cat /proc/%d/cmdline 1>&2", getpid());
|
||||
system(command);
|
||||
|
||||
return 0;
|
||||
}
|
||||
225
test/issues/1065/result.log
Normal file
225
test/issues/1065/result.log
Normal file
@ -0,0 +1,225 @@
|
||||
./CT_001.sh
|
||||
*** CT_001 start *******************
|
||||
file map: /home/satoken/2018_work/04/test/dummy_file
|
||||
000000400000-000000401000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
000000600000-000000601000 r--s 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
000000601000-000000602000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
2aaaaa9f8000-2aaaaaa00000 rw-s 0 0:0 0
|
||||
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac22000-2aaaaac23000 rw-s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac23000-2aaaaac24000 rw-p 0 0:0 0
|
||||
2aaaaac24000-2aaaaac26000 r-xs 0 0:0 0 [vdso]
|
||||
2aaaaac26000-2aaaaac27000 rw-p 0 0:0 0
|
||||
2aaaaac4d000-2aaaaac4e000 rw-p 0 0:0 0
|
||||
2aaaaac4e000-2aaaaae06000 r-xp 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaaae06000-2aaaab006000 ---p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab006000-2aaaab00a000 r--p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00a000-2aaaab00c000 rw-p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00c000-2aaaab011000 rw-p 0 0:0 0
|
||||
2aaaab011000-2aaaab013000 rw-p 0 0:0 0
|
||||
2aaaab013000-2aaaab014000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/dummy_file
|
||||
547fff800000-548000000000 rw-s 0 0:0 0 [stack]
|
||||
|
||||
** grep /home/satoken/2018_work/04/test/dummy_file from maps
|
||||
2aaaab013000-2aaaab014000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/dummy_file
|
||||
[OK] /home/satoken/2018_work/04/test/dummy_file is found
|
||||
*** CT_001 PASSED
|
||||
|
||||
./CT_002.sh
|
||||
*** CT_002 start *******************
|
||||
file map: ./dummy_file
|
||||
000000400000-000000401000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
000000600000-000000601000 r--s 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
000000601000-000000602000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
2aaaaa9f8000-2aaaaaa00000 rw-s 0 0:0 0
|
||||
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac22000-2aaaaac23000 rw-s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac23000-2aaaaac24000 rw-p 0 0:0 0
|
||||
2aaaaac24000-2aaaaac26000 r-xs 0 0:0 0 [vdso]
|
||||
2aaaaac26000-2aaaaac27000 rw-p 0 0:0 0
|
||||
2aaaaac4d000-2aaaaac4e000 rw-p 0 0:0 0
|
||||
2aaaaac4e000-2aaaaae06000 r-xp 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaaae06000-2aaaab006000 ---p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab006000-2aaaab00a000 r--p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00a000-2aaaab00c000 rw-p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00c000-2aaaab011000 rw-p 0 0:0 0
|
||||
2aaaab011000-2aaaab013000 rw-p 0 0:0 0
|
||||
2aaaab013000-2aaaab014000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/dummy_file
|
||||
547fff800000-548000000000 rw-s 0 0:0 0 [stack]
|
||||
|
||||
** grep /home/satoken/2018_work/04/test/dummy_file from maps
|
||||
2aaaab013000-2aaaab014000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/dummy_file
|
||||
[OK] /home/satoken/2018_work/04/test/dummy_file is found
|
||||
*** CT_002 PASSED
|
||||
|
||||
./CT_003.sh
|
||||
*** CT_003 start *******************
|
||||
file map: ./lnk_to_dummy
|
||||
000000400000-000000401000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
000000600000-000000601000 r--s 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
000000601000-000000602000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/file_map
|
||||
2aaaaa9f8000-2aaaaaa00000 rw-s 0 0:0 0
|
||||
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac22000-2aaaaac23000 rw-s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac23000-2aaaaac24000 rw-p 0 0:0 0
|
||||
2aaaaac24000-2aaaaac26000 r-xs 0 0:0 0 [vdso]
|
||||
2aaaaac26000-2aaaaac27000 rw-p 0 0:0 0
|
||||
2aaaaac4d000-2aaaaac4e000 rw-p 0 0:0 0
|
||||
2aaaaac4e000-2aaaaae06000 r-xp 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaaae06000-2aaaab006000 ---p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab006000-2aaaab00a000 r--p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00a000-2aaaab00c000 rw-p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00c000-2aaaab011000 rw-p 0 0:0 0
|
||||
2aaaab011000-2aaaab013000 rw-p 0 0:0 0
|
||||
2aaaab013000-2aaaab014000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/dummy_file
|
||||
547fff800000-548000000000 rw-s 0 0:0 0 [stack]
|
||||
|
||||
** grep /home/satoken/2018_work/04/test/dummy_file from maps
|
||||
2aaaab013000-2aaaab014000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/dummy_file
|
||||
[OK] /home/satoken/2018_work/04/test/dummy_file is found
|
||||
*** CT_003 PASSED
|
||||
|
||||
./CT_004.sh
|
||||
*** CT_004 start *******************
|
||||
exec : ./print_maps
|
||||
000000400000-000000401000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/print_maps
|
||||
000000600000-000000601000 r--s 0 0:0 0 /home/satoken/2018_work/04/test/print_maps
|
||||
000000601000-000000602000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/print_maps
|
||||
2aaaaa9f8000-2aaaaaa00000 rw-s 0 0:0 0
|
||||
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac22000-2aaaaac23000 rw-s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac23000-2aaaaac24000 rw-p 0 0:0 0
|
||||
2aaaaac24000-2aaaaac26000 r-xs 0 0:0 0 [vdso]
|
||||
2aaaaac26000-2aaaaac27000 rw-p 0 0:0 0
|
||||
2aaaaac4d000-2aaaaac4e000 rw-p 0 0:0 0
|
||||
2aaaaac4e000-2aaaaae06000 r-xp 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaaae06000-2aaaab006000 ---p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab006000-2aaaab00a000 r--p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00a000-2aaaab00c000 rw-p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00c000-2aaaab011000 rw-p 0 0:0 0
|
||||
2aaaab011000-2aaaab013000 rw-p 0 0:0 0
|
||||
547fff800000-548000000000 rw-s 0 0:0 0 [stack]
|
||||
|
||||
** grep /home/satoken/2018_work/04/test/print_maps from maps
|
||||
000000400000-000000401000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/print_maps
|
||||
000000600000-000000601000 r--s 0 0:0 0 /home/satoken/2018_work/04/test/print_maps
|
||||
000000601000-000000602000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/print_maps
|
||||
[OK] /home/satoken/2018_work/04/test/print_maps is found
|
||||
|
||||
** grep /usr/lib64/ld-2.17.so from maps
|
||||
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac22000-2aaaaac23000 rw-s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
[OK] /usr/lib64/ld-2.17.so is found
|
||||
*** CT_004 PASSED
|
||||
|
||||
./CT_005.sh
|
||||
*** CT_005 start *******************
|
||||
exec : ./static_print_maps
|
||||
000000400000-0000004b8000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/static_print_maps
|
||||
0000006b7000-0000006ba000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/static_print_maps
|
||||
0000006ba000-0000006bc000 rw-p 0 0:0 0
|
||||
000000800000-000000802000 rw-s 0 0:0 0 [heap]
|
||||
000000802000-000000823000 rw-s 0 0:0 0 [heap]
|
||||
000000823000-000000824000 rw-s 0 0:0 0 [heap]
|
||||
2aaaaa9f8000-2aaaaaa00000 rw-s 0 0:0 0
|
||||
2aaaaaa00000-2aaaaaa02000 r-xs 0 0:0 0 [vdso]
|
||||
547fff800000-548000000000 rw-s 0 0:0 0 [stack]
|
||||
|
||||
** grep /home/satoken/2018_work/04/test/static_print_maps from maps
|
||||
000000400000-0000004b8000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/static_print_maps
|
||||
0000006b7000-0000006ba000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/static_print_maps
|
||||
[OK] /home/satoken/2018_work/04/test/static_print_maps is found
|
||||
|
||||
** grep /usr/lib64/ld-2.17.so from maps
|
||||
[OK] /usr/lib64/ld-2.17.so is not found
|
||||
*** CT_005 PASSED
|
||||
|
||||
./CT_006.sh
|
||||
*** CT_006 start *******************
|
||||
000000400000-00000040b000 r-xs 0 0:0 0 /usr/bin/cat
|
||||
00000060b000-00000060c000 r--s 0 0:0 0 /usr/bin/cat
|
||||
00000060c000-00000060d000 rw-s 0 0:0 0 /usr/bin/cat
|
||||
000000800000-000000821000 rw-s 0 0:0 0 [heap]
|
||||
2aaaaa9f8000-2aaaaaa00000 rw-s 0 0:0 0
|
||||
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac22000-2aaaaac23000 rw-s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac23000-2aaaaac24000 rw-p 0 0:0 0
|
||||
2aaaaac24000-2aaaaac26000 r-xs 0 0:0 0 [vdso]
|
||||
2aaaaac26000-2aaaaac27000 rw-p 0 0:0 0
|
||||
2aaaaac4d000-2aaaaac4e000 rw-p 0 0:0 0
|
||||
2aaaaac4e000-2aaaaae06000 r-xp 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaaae06000-2aaaab006000 ---p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab006000-2aaaab00a000 r--p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00a000-2aaaab00c000 rw-p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00c000-2aaaab011000 rw-p 0 0:0 0
|
||||
2aaaab011000-2aaaab013000 rw-p 0 0:0 0
|
||||
2aaaab013000-2aaab153c000 r--p 0 0:0 0 /usr/lib/locale/locale-archive
|
||||
547fff800000-548000000000 rw-s 0 0:0 0 [stack]
|
||||
[OK] shell script is running normaly
|
||||
*** CT_006 PASSED
|
||||
|
||||
./CT_007.sh
|
||||
*** CT_007 start *******************
|
||||
exec : ./call_execve ./print_maps_and_cmdline
|
||||
000000400000-000000401000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/print_maps_and_cmdline
|
||||
000000600000-000000601000 r--s 0 0:0 0 /home/satoken/2018_work/04/test/print_maps_and_cmdline
|
||||
000000601000-000000602000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/print_maps_and_cmdline
|
||||
2aaaaa9f8000-2aaaaaa00000 rw-s 0 0:0 0
|
||||
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac22000-2aaaaac23000 rw-s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac23000-2aaaaac24000 rw-p 0 0:0 0
|
||||
2aaaaac24000-2aaaaac26000 r-xs 0 0:0 0 [vdso]
|
||||
2aaaaac26000-2aaaaac27000 rw-p 0 0:0 0
|
||||
2aaaaac4d000-2aaaaae05000 r-xp 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaaae05000-2aaaab005000 ---p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab005000-2aaaab009000 r--p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab009000-2aaaab00b000 rw-p 0 0:0 0 /usr/lib64/libc-2.17.so
|
||||
2aaaab00b000-2aaaab010000 rw-p 0 0:0 0
|
||||
2aaaab010000-2aaaab011000 rw-p 0 0:0 0
|
||||
2aaaab011000-2aaaab013000 rw-p 0 0:0 0
|
||||
547fff800000-548000000000 rw-s 0 0:0 0 [stack]
|
||||
STKN:[main_loop] filename:./print_maps_and_cmdline shell:0x(nil)
|
||||
STKN:[main_loop] filename:/bin/sh shell:0x(nil)
|
||||
STKN:[main_loop] filename:./print_maps_and_cmdline shell:0x(nil)
|
||||
|
||||
** grep /home/satoken/2018_work/04/test/print_maps_and_cmdline from maps
|
||||
000000400000-000000401000 r-xs 0 0:0 0 /home/satoken/2018_work/04/test/print_maps_and_cmdline
|
||||
000000600000-000000601000 r--s 0 0:0 0 /home/satoken/2018_work/04/test/print_maps_and_cmdline
|
||||
000000601000-000000602000 rw-s 0 0:0 0 /home/satoken/2018_work/04/test/print_maps_and_cmdline
|
||||
[OK] /home/satoken/2018_work/04/test/print_maps_and_cmdline is found
|
||||
|
||||
** grep /usr/lib64/ld-2.17.so from maps
|
||||
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
2aaaaac22000-2aaaaac23000 rw-s 0 0:0 0 /usr/lib64/ld-2.17.so
|
||||
[OK] /usr/lib64/ld-2.17.so is found
|
||||
./print_maps_and_cmdlineso.6o.
|
||||
** grep ./print_maps_and_cmdline from cmdline
|
||||
./print_maps_and_cmdlineso.6o.
|
||||
[OK] ./print_maps_and_cmdline is found
|
||||
*** CT_007 PASSED
|
||||
|
||||
./CT_008.sh
|
||||
*** CT_008 start *******************
|
||||
exec : ./call_execve.sh ./print_maps_and_cmdline
|
||||
./CT_008.sh: line 18: 25571 Segmentation fault (core dumped) ${MCEXEC} ${test_program} > ./${TESTNAME}_maps.log 2> ./${TESTNAME}_cmdline.log
|
||||
STKN:[main] This is shell script
|
||||
STKN:[main_loop] filename:./call_execve shell:0x(nil)
|
||||
STKN:[main_loop] filename:./print_maps_and_cmdline shell:0x(nil)
|
||||
|
||||
** grep /home/satoken/2018_work/04/test/print_maps_and_cmdline from maps
|
||||
[NG] /home/satoken/2018_work/04/test/print_maps_and_cmdline is not found
|
||||
|
||||
** grep /usr/lib64/ld-2.17.so from maps
|
||||
[NG] /usr/lib64/ld-2.17.so is not found
|
||||
|
||||
** grep ./print_maps_and_cmdline from cmdline
|
||||
[NG] ./print_maps_and_cmdline is not found
|
||||
*** CT_008 FAILED
|
||||
34
test/issues/1102/CT_001.sh
Executable file
34
test/issues/1102/CT_001.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_001
|
||||
REP=30
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
echo "** exec ltp-syscall_mkdir09 ${REP} times"
|
||||
echo -n "" > ./${TESTNAME}.log
|
||||
for i in `seq 1 ${REP}`
|
||||
do
|
||||
${MCEXEC} ${LTP_DIR}/testcases/bin/mkdir09 | tee -a ./${TESTNAME}.log
|
||||
done
|
||||
|
||||
grep -a -e "FAIL" ./${TESTNAME}.log
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "[OK] ltp-syscall_mkdir09 ${REP} times all passed"
|
||||
else
|
||||
echo "[NG] ltp-syscall_mkdir09 failed"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
rm ./${TESTNAME}.log
|
||||
29
test/issues/1102/CT_002.sh
Executable file
29
test/issues/1102/CT_002.sh
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_002
|
||||
|
||||
. ./config
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
echo "** exec ostest siginfo_00"
|
||||
${MCEXEC} ${OSTEST_DIR}/bin/test_mck -s siginfo -n 0| tee -a ./${TESTNAME}.log
|
||||
|
||||
tail -n 1 ./${TESTNAME}.log | grep -a -e "RESULT: ok" &> /dev/null
|
||||
|
||||
if [ $? = 0 ]; then
|
||||
echo "[OK] ostest siginfo_00 passed"
|
||||
else
|
||||
echo "[NG] ostest siginfo_00 failed"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
rm ./${TESTNAME}.log
|
||||
51
test/issues/1102/CT_003.sh
Executable file
51
test/issues/1102/CT_003.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_003
|
||||
|
||||
. ./config
|
||||
|
||||
SIG_NAME=SIGHUP
|
||||
SIG_NUM=1
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
echo "** exec ostest siginfo_01 and then send ${SIG_NAME} to mcexec"
|
||||
${MCEXEC} ${OSTEST_DIR}/bin/test_mck -s siginfo -n 1 &
|
||||
sleep 1
|
||||
|
||||
echo "** back ground process(mcexec): $!"
|
||||
echo "** send ${SIG_NAME} to mcexec once"
|
||||
kill -${SIG_NUM} $!
|
||||
sleep 1
|
||||
|
||||
echo "** check existing of $!"
|
||||
ps -p $!
|
||||
|
||||
if [ $? = 0 ]; then
|
||||
echo "[OK] $! exists yet"
|
||||
else
|
||||
echo "[NG] $! doesn't exist"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo "** send ${SIG_NAME} to mcexec again"
|
||||
kill -${SIG_NUM} $!
|
||||
sleep 1
|
||||
echo "** check existing of $!"
|
||||
ps -p $!
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "[OK] $! doesn't exist (be killed by signal)"
|
||||
else
|
||||
echo "[NG] exist yet"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
51
test/issues/1102/CT_004.sh
Executable file
51
test/issues/1102/CT_004.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_004
|
||||
|
||||
. ./config
|
||||
|
||||
SIG_NAME=SIGINT
|
||||
SIG_NUM=2
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
echo "** exec ostest siginfo_01 and then send ${SIG_NAME} to mcexec"
|
||||
${MCEXEC} ${OSTEST_DIR}/bin/test_mck -s siginfo -n 1 &
|
||||
sleep 1
|
||||
|
||||
echo "** back ground process(mcexec): $!"
|
||||
echo "** send ${SIG_NAME} to mcexec once"
|
||||
kill -${SIG_NUM} $!
|
||||
sleep 1
|
||||
|
||||
echo "** check existing of $!"
|
||||
ps -p $!
|
||||
|
||||
if [ $? = 0 ]; then
|
||||
echo "[OK] $! exists yet"
|
||||
else
|
||||
echo "[NG] $! doesn't exist"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo "** send ${SIG_NAME} to mcexec again"
|
||||
kill -${SIG_NUM} $!
|
||||
sleep 1
|
||||
echo "** check existing of $!"
|
||||
ps -p $!
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "[OK] $! doesn't exist (be killed by signal)"
|
||||
else
|
||||
echo "[NG] exist yet"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
51
test/issues/1102/CT_005.sh
Executable file
51
test/issues/1102/CT_005.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
|
||||
TESTNAME=CT_005
|
||||
|
||||
. ./config
|
||||
|
||||
SIG_NAME=SIGTERM
|
||||
SIG_NUM=15
|
||||
|
||||
fail=0
|
||||
|
||||
echo "*** ${TESTNAME} start *******************"
|
||||
echo "** exec ostest siginfo_01 and then send ${SIG_NAME} to mcexec"
|
||||
${MCEXEC} ${OSTEST_DIR}/bin/test_mck -s siginfo -n 1 &
|
||||
sleep 1
|
||||
|
||||
echo "** back ground process(mcexec): $!"
|
||||
echo "** send ${SIG_NAME} to mcexec once"
|
||||
kill -${SIG_NUM} $!
|
||||
sleep 1
|
||||
|
||||
echo "** check existing of $!"
|
||||
ps -p $!
|
||||
|
||||
if [ $? = 0 ]; then
|
||||
echo "[OK] $! exists yet"
|
||||
else
|
||||
echo "[NG] $! doesn't exist"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
echo "** send ${SIG_NAME} to mcexec again"
|
||||
kill -${SIG_NUM} $!
|
||||
sleep 1
|
||||
echo "** check existing of $!"
|
||||
ps -p $!
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "[OK] $! doesn't exist (be killed by signal)"
|
||||
else
|
||||
echo "[NG] exist yet"
|
||||
fail=1
|
||||
fi
|
||||
|
||||
if [ X$fail = X0 ]; then
|
||||
echo "*** ${TESTNAME} PASSED"
|
||||
else
|
||||
echo "*** ${TESTNAME} FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
29
test/issues/1102/Makefile
Normal file
29
test/issues/1102/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
CC = gcc
|
||||
MCK_DIR=/home/satoken/ppos
|
||||
MCEXEC=$(MCK_DIR)/bin/mcexec
|
||||
|
||||
LTP_DIR=/home/satoken/ltp
|
||||
OSTEST_DIR=/home/satoken/ostest
|
||||
|
||||
TARGET=config
|
||||
|
||||
CPPFLAGS =
|
||||
LDFLAGS =
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
config:
|
||||
@echo "MCEXEC=$(MCEXEC)" > ./config
|
||||
@echo "LTP_DIR=$(LTP_DIR)" >> ./config
|
||||
@echo "OSTEST_DIR=$(OSTEST_DIR)" >> ./config
|
||||
|
||||
test: all
|
||||
./CT_001.sh
|
||||
./CT_002.sh
|
||||
./CT_003.sh
|
||||
./CT_004.sh
|
||||
./CT_005.sh
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) *.o
|
||||
|
||||
26
test/issues/1102/README
Normal file
26
test/issues/1102/README
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
CT_001:
|
||||
ltp-syscall_mkdir09 を繰り返し実行する
|
||||
-> いずれの実行結果もFAILとならない
|
||||
|
||||
CT_002:
|
||||
ostest のsiginfo_00 を実行する
|
||||
-> 実行結果がRESULT: ok となる
|
||||
|
||||
CT_003:
|
||||
ostest のsiginfo_01 を実行する
|
||||
動作の確認には、SIGHUP を用いる
|
||||
-> 1度目のSIGHUPはハンドルされ、プロセスが残存する
|
||||
2度目のSIGHUPにより、プロセスが終了する
|
||||
|
||||
CT_004:
|
||||
ostest のsiginfo_01 を実行する
|
||||
動作の確認には、SIGINT を用いる
|
||||
-> 1度目のSIGINTはハンドルされ、プロセスが残存する
|
||||
2度目のSIGINTにより、プロセスが終了する
|
||||
|
||||
CT_005:
|
||||
ostest のsiginfo_01 を実行する
|
||||
動作の確認には、SIGTERM を用いる
|
||||
-> 1度目のSIGTERMはハンドルされ、プロセスが残存する
|
||||
2度目のSIGTERMにより、プロセスが終了する
|
||||
273
test/issues/1102/result.log
Normal file
273
test/issues/1102/result.log
Normal file
@ -0,0 +1,273 @@
|
||||
./CT_001.sh
|
||||
*** CT_001 start *******************
|
||||
** exec ltp-syscall_mkdir09 30 times
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
mkdir09 1 TPASS : PASS
|
||||
[OK] ltp-syscall_mkdir09 30 times all passed
|
||||
*** CT_001 PASSED
|
||||
|
||||
./CT_002.sh
|
||||
*** CT_002 start *******************
|
||||
** exec ostest siginfo_00
|
||||
TEST_SUITE: siginfo
|
||||
TEST_NUMBER: 0
|
||||
ARGS:
|
||||
=== raise signal #1 ===
|
||||
Catch signal #1
|
||||
siginfo->si_signo = 1
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #2 ===
|
||||
Catch signal #2
|
||||
siginfo->si_signo = 2
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #3 ===
|
||||
Catch signal #3
|
||||
siginfo->si_signo = 3
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #4 ===
|
||||
Catch signal #4
|
||||
siginfo->si_signo = 4
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #5 ===
|
||||
Catch signal #5
|
||||
siginfo->si_signo = 5
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #6 ===
|
||||
Catch signal #6
|
||||
siginfo->si_signo = 6
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #7 ===
|
||||
Catch signal #7
|
||||
siginfo->si_signo = 7
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #8 ===
|
||||
Catch signal #8
|
||||
siginfo->si_signo = 8
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #10 ===
|
||||
Catch signal #10
|
||||
siginfo->si_signo = 10
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #11 ===
|
||||
Catch signal #11
|
||||
siginfo->si_signo = 11
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #12 ===
|
||||
Catch signal #12
|
||||
siginfo->si_signo = 12
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #13 ===
|
||||
Catch signal #13
|
||||
siginfo->si_signo = 13
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #14 ===
|
||||
Catch signal #14
|
||||
siginfo->si_signo = 14
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #15 ===
|
||||
Catch signal #15
|
||||
siginfo->si_signo = 15
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #16 ===
|
||||
Catch signal #16
|
||||
siginfo->si_signo = 16
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #17 ===
|
||||
Catch signal #17
|
||||
siginfo->si_signo = 17
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #18 ===
|
||||
Catch signal #18
|
||||
siginfo->si_signo = 18
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #20 ===
|
||||
Catch signal #20
|
||||
siginfo->si_signo = 20
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #21 ===
|
||||
Catch signal #21
|
||||
siginfo->si_signo = 21
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #22 ===
|
||||
Catch signal #22
|
||||
siginfo->si_signo = 22
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #23 ===
|
||||
Catch signal #23
|
||||
siginfo->si_signo = 23
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #24 ===
|
||||
Catch signal #24
|
||||
siginfo->si_signo = 24
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #25 ===
|
||||
Catch signal #25
|
||||
siginfo->si_signo = 25
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #26 ===
|
||||
Catch signal #26
|
||||
siginfo->si_signo = 26
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #27 ===
|
||||
Catch signal #27
|
||||
siginfo->si_signo = 27
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #28 ===
|
||||
Catch signal #28
|
||||
siginfo->si_signo = 28
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #29 ===
|
||||
Catch signal #29
|
||||
siginfo->si_signo = 29
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #30 ===
|
||||
Catch signal #30
|
||||
siginfo->si_signo = 30
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
=== raise signal #31 ===
|
||||
Catch signal #31
|
||||
siginfo->si_signo = 31
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0xfffffffa
|
||||
RESULT: ok
|
||||
[OK] ostest siginfo_00 passed
|
||||
*** CT_002 PASSED
|
||||
|
||||
./CT_003.sh
|
||||
*** CT_003 start *******************
|
||||
** exec ostest siginfo_01 and then send SIGHUP to mcexec
|
||||
TEST_SUITE: siginfo
|
||||
TEST_NUMBER: 1
|
||||
ARGS:
|
||||
==================================================
|
||||
Please send signal to mcexec(pid=12295) from console.
|
||||
Exit Once you throw twice the same signal.
|
||||
==================================================
|
||||
** back ground process(mcexec): 12295
|
||||
** send SIGHUP to mcexec once
|
||||
Catch signal #1
|
||||
siginfo->si_signo = 1
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0x0
|
||||
** check existing of 12295
|
||||
PID TTY TIME CMD
|
||||
12295 pts/0 00:00:00 exe
|
||||
[OK] 12295 exists yet
|
||||
** send SIGHUP to mcexec again
|
||||
Terminate by signal 1
|
||||
./CT_003.sh: line 34: 12295 Hangup ${MCEXEC} ${OSTEST_DIR}/bin/test_mck -s siginfo -n 1
|
||||
** check existing of 12295
|
||||
PID TTY TIME CMD
|
||||
[OK] 12295 doesn't exist (be killed by signal)
|
||||
*** CT_003 PASSED
|
||||
|
||||
./CT_004.sh
|
||||
*** CT_004 start *******************
|
||||
** exec ostest siginfo_01 and then send SIGINT to mcexec
|
||||
TEST_SUITE: siginfo
|
||||
TEST_NUMBER: 1
|
||||
ARGS:
|
||||
==================================================
|
||||
Please send signal to mcexec(pid=12311) from console.
|
||||
Exit Once you throw twice the same signal.
|
||||
==================================================
|
||||
** back ground process(mcexec): 12311
|
||||
** send SIGINT to mcexec once
|
||||
Catch signal #2
|
||||
siginfo->si_signo = 2
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0x0
|
||||
** check existing of 12311
|
||||
PID TTY TIME CMD
|
||||
12311 pts/0 00:00:00 exe
|
||||
[OK] 12311 exists yet
|
||||
** send SIGINT to mcexec again
|
||||
Terminate by signal 2
|
||||
** check existing of 12311
|
||||
PID TTY TIME CMD
|
||||
[OK] 12311 doesn't exist (be killed by signal)
|
||||
*** CT_004 PASSED
|
||||
|
||||
./CT_005.sh
|
||||
*** CT_005 start *******************
|
||||
** exec ostest siginfo_01 and then send SIGTERM to mcexec
|
||||
TEST_SUITE: siginfo
|
||||
TEST_NUMBER: 1
|
||||
ARGS:
|
||||
==================================================
|
||||
Please send signal to mcexec(pid=12327) from console.
|
||||
Exit Once you throw twice the same signal.
|
||||
==================================================
|
||||
** back ground process(mcexec): 12327
|
||||
** send SIGTERM to mcexec once
|
||||
Catch signal #15
|
||||
siginfo->si_signo = 15
|
||||
siginfo->si_errno = 0
|
||||
siginfo->si_code = 0x0
|
||||
** check existing of 12327
|
||||
PID TTY TIME CMD
|
||||
12327 pts/0 00:00:00 exe
|
||||
[OK] 12327 exists yet
|
||||
** send SIGTERM to mcexec again
|
||||
Terminate by signal 15
|
||||
./CT_005.sh: line 34: 12327 Terminated ${MCEXEC} ${OSTEST_DIR}/bin/test_mck -s siginfo -n 1
|
||||
** check existing of 12327
|
||||
PID TTY TIME CMD
|
||||
[OK] 12327 doesn't exist (be killed by signal)
|
||||
*** CT_005 PASSED
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user