Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddc33821cf | ||
|
|
0ab7d02994 | ||
|
|
a8c4ab221b | ||
|
|
87d36a7752 | ||
|
|
998ded414c | ||
|
|
f78d031e64 | ||
|
|
4ab37dd34a | ||
|
|
8129dec2f7 | ||
|
|
a1035a1878 | ||
|
|
db169c5f90 | ||
|
|
bbb55ef261 | ||
|
|
1130cafe41 | ||
|
|
a1cf27e232 | ||
|
|
5a1ce99d87 | ||
|
|
c7db296e1b |
@@ -148,7 +148,7 @@ extern char page_fault[], general_protection_exception[];
|
|||||||
extern char debug_exception[], int3_exception[];
|
extern char debug_exception[], int3_exception[];
|
||||||
|
|
||||||
uint64_t boot_pat_state = 0;
|
uint64_t boot_pat_state = 0;
|
||||||
int no_turbo = 0; /* May be updated by early parsing of kargs */
|
int no_turbo = 1; /* May be updated by early parsing of kargs */
|
||||||
|
|
||||||
extern int num_processors; /* kernel/ap.c */
|
extern int num_processors; /* kernel/ap.c */
|
||||||
struct pvclock_vsyscall_time_info *pvti = NULL;
|
struct pvclock_vsyscall_time_info *pvti = NULL;
|
||||||
@@ -1079,6 +1079,10 @@ unhandled_page_fault(struct thread *thread, void *fault_addr, void *regs)
|
|||||||
|
|
||||||
kprintf_unlock(irqflags);
|
kprintf_unlock(irqflags);
|
||||||
|
|
||||||
|
if (!(error & PF_USER)) {
|
||||||
|
panic("panic: kernel mode PF");
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
ihk_mc_debug_show_interrupt_context(regs);
|
ihk_mc_debug_show_interrupt_context(regs);
|
||||||
|
|
||||||
|
|||||||
@@ -150,5 +150,8 @@ SYSCALL_HANDLED(602, pmc_start)
|
|||||||
SYSCALL_HANDLED(603, pmc_stop)
|
SYSCALL_HANDLED(603, pmc_stop)
|
||||||
SYSCALL_HANDLED(604, pmc_reset)
|
SYSCALL_HANDLED(604, pmc_reset)
|
||||||
SYSCALL_HANDLED(700, get_cpu_id)
|
SYSCALL_HANDLED(700, get_cpu_id)
|
||||||
|
#ifdef TRACK_SYSCALLS
|
||||||
|
SYSCALL_HANDLED(701, syscall_offload_clr_cntrs)
|
||||||
|
#endif // TRACK_SYSCALLS
|
||||||
|
|
||||||
/**** End of File ****/
|
/**** End of File ****/
|
||||||
|
|||||||
@@ -2367,8 +2367,18 @@ int write_process_vm(struct process_vm *vm, void *udst, const void *ksrc, size_t
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
va = phys_to_virt(pa);
|
if (pa < ihk_mc_get_memory_address(IHK_MC_GMA_MAP_START, 0) ||
|
||||||
memcpy(va, from, cpsize);
|
pa >= ihk_mc_get_memory_address(IHK_MC_GMA_MAP_END, 0)) {
|
||||||
|
dkprintf("%s: pa is outside of LWK memory, from: %p,"
|
||||||
|
"pa: %p, cpsize: %d\n", __FUNCTION__, from, pa, cpsize);
|
||||||
|
va = ihk_mc_map_virtual(pa, 1, PTATTR_ACTIVE);
|
||||||
|
memcpy(va, from, cpsize);
|
||||||
|
ihk_mc_unmap_virtual(va, 1, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
va = phys_to_virt(pa);
|
||||||
|
memcpy(va, from, cpsize);
|
||||||
|
}
|
||||||
|
|
||||||
from += cpsize;
|
from += cpsize;
|
||||||
to += cpsize;
|
to += cpsize;
|
||||||
|
|||||||
@@ -544,14 +544,14 @@ void ptrace_report_signal(struct thread *thread, int sig)
|
|||||||
int parent_pid;
|
int parent_pid;
|
||||||
struct siginfo info;
|
struct siginfo info;
|
||||||
|
|
||||||
dkprintf("ptrace_report_signal,pid=%d\n", thread->proc->pid);
|
dkprintf("ptrace_report_signal, tid=%d, pid=%d\n", thread->tid, thread->proc->pid);
|
||||||
|
|
||||||
mcs_rwlock_writer_lock(&proc->update_lock, &lock);
|
mcs_rwlock_writer_lock(&proc->update_lock, &lock);
|
||||||
if(!(proc->ptrace & PT_TRACED)){
|
if(!(proc->ptrace & PT_TRACED)){
|
||||||
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
proc->exit_status = sig;
|
thread->exit_status = sig;
|
||||||
/* Transition thread state */
|
/* Transition thread state */
|
||||||
proc->status = PS_TRACED;
|
proc->status = PS_TRACED;
|
||||||
thread->status = PS_TRACED;
|
thread->status = PS_TRACED;
|
||||||
@@ -569,8 +569,8 @@ void ptrace_report_signal(struct thread *thread, int sig)
|
|||||||
memset(&info, '\0', sizeof info);
|
memset(&info, '\0', sizeof info);
|
||||||
info.si_signo = SIGCHLD;
|
info.si_signo = SIGCHLD;
|
||||||
info.si_code = CLD_TRAPPED;
|
info.si_code = CLD_TRAPPED;
|
||||||
info._sifields._sigchld.si_pid = thread->proc->pid;
|
info._sifields._sigchld.si_pid = thread->tid;
|
||||||
info._sifields._sigchld.si_status = thread->proc->exit_status;
|
info._sifields._sigchld.si_status = thread->exit_status;
|
||||||
do_kill(cpu_local_var(current), parent_pid, -1, SIGCHLD, &info, 0);
|
do_kill(cpu_local_var(current), parent_pid, -1, SIGCHLD, &info, 0);
|
||||||
/* Wake parent (if sleeping in wait4()) */
|
/* Wake parent (if sleeping in wait4()) */
|
||||||
waitq_wakeup(&proc->parent->waitpid_q);
|
waitq_wakeup(&proc->parent->waitpid_q);
|
||||||
@@ -695,10 +695,10 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
int orgsig;
|
int orgsig;
|
||||||
int ptraceflag = 0;
|
int ptraceflag = 0;
|
||||||
struct mcs_rwlock_node_irqsave lock;
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
unsigned long irqstate;
|
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||||
|
|
||||||
for(w = pending->sigmask.__val[0], sig = 0; w; sig++, w >>= 1);
|
for(w = pending->sigmask.__val[0], sig = 0; w; sig++, w >>= 1);
|
||||||
dkprintf("do_signal,pid=%d,sig=%d\n", proc->pid, sig);
|
dkprintf("do_signal(): tid=%d, pid=%d, sig=%d\n", thread->tid, proc->pid, sig);
|
||||||
orgsig = sig;
|
orgsig = sig;
|
||||||
|
|
||||||
if((proc->ptrace & PT_TRACED) &&
|
if((proc->ptrace & PT_TRACED) &&
|
||||||
@@ -718,12 +718,12 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
rc = regs->gpr.rax;
|
rc = regs->gpr.rax;
|
||||||
}
|
}
|
||||||
|
|
||||||
irqstate = ihk_mc_spinlock_lock(&thread->sigcommon->lock);
|
mcs_rwlock_writer_lock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
k = thread->sigcommon->action + sig - 1;
|
k = thread->sigcommon->action + sig - 1;
|
||||||
|
|
||||||
if(k->sa.sa_handler == SIG_IGN){
|
if(k->sa.sa_handler == SIG_IGN){
|
||||||
kfree(pending);
|
kfree(pending);
|
||||||
ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate);
|
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(k->sa.sa_handler){
|
else if(k->sa.sa_handler){
|
||||||
@@ -808,7 +808,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
|
|
||||||
if(copy_to_user(sigsp, &ksigsp, sizeof ksigsp)){
|
if(copy_to_user(sigsp, &ksigsp, sizeof ksigsp)){
|
||||||
kfree(pending);
|
kfree(pending);
|
||||||
ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate);
|
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
kprintf("do_signal,write_process_vm failed\n");
|
kprintf("do_signal,write_process_vm failed\n");
|
||||||
terminate(0, sig);
|
terminate(0, sig);
|
||||||
return;
|
return;
|
||||||
@@ -827,7 +827,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
if(!(k->sa.sa_flags & SA_NODEFER))
|
if(!(k->sa.sa_flags & SA_NODEFER))
|
||||||
thread->sigmask.__val[0] |= pending->sigmask.__val[0];
|
thread->sigmask.__val[0] |= pending->sigmask.__val[0];
|
||||||
kfree(pending);
|
kfree(pending);
|
||||||
ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate);
|
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
if(regs->gpr.rflags & RFLAGS_TF){
|
if(regs->gpr.rflags & RFLAGS_TF){
|
||||||
struct siginfo info;
|
struct siginfo info;
|
||||||
|
|
||||||
@@ -853,7 +853,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
kfree(pending);
|
kfree(pending);
|
||||||
ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate);
|
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
switch (sig) {
|
switch (sig) {
|
||||||
case SIGSTOP:
|
case SIGSTOP:
|
||||||
case SIGTSTP:
|
case SIGTSTP:
|
||||||
@@ -885,7 +885,8 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
/* Wake up the parent who tried wait4 and sleeping */
|
/* Wake up the parent who tried wait4 and sleeping */
|
||||||
waitq_wakeup(&proc->parent->waitpid_q);
|
waitq_wakeup(&proc->parent->waitpid_q);
|
||||||
|
|
||||||
dkprintf("do_signal,SIGSTOP,sleeping\n");
|
dkprintf("do_signal(): pid: %d, tid: %d SIGSTOP, sleeping\n",
|
||||||
|
proc->pid, thread->tid);
|
||||||
/* Sleep */
|
/* Sleep */
|
||||||
schedule();
|
schedule();
|
||||||
dkprintf("SIGSTOP(): woken up\n");
|
dkprintf("SIGSTOP(): woken up\n");
|
||||||
@@ -899,7 +900,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
|
|
||||||
/* Update thread state in fork tree */
|
/* Update thread state in fork tree */
|
||||||
mcs_rwlock_writer_lock(&proc->update_lock, &lock);
|
mcs_rwlock_writer_lock(&proc->update_lock, &lock);
|
||||||
proc->exit_status = SIGTRAP;
|
thread->exit_status = SIGTRAP;
|
||||||
proc->status = PS_TRACED;
|
proc->status = PS_TRACED;
|
||||||
thread->status = PS_TRACED;
|
thread->status = PS_TRACED;
|
||||||
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
||||||
@@ -953,11 +954,11 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
static struct sig_pending *
|
static struct sig_pending *
|
||||||
getsigpending(struct thread *thread, int delflag){
|
getsigpending(struct thread *thread, int delflag){
|
||||||
struct list_head *head;
|
struct list_head *head;
|
||||||
ihk_spinlock_t *lock;
|
mcs_rwlock_lock_t *lock;
|
||||||
|
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||||
struct sig_pending *next;
|
struct sig_pending *next;
|
||||||
struct sig_pending *pending;
|
struct sig_pending *pending;
|
||||||
__sigset_t w;
|
__sigset_t w;
|
||||||
int irqstate;
|
|
||||||
__sigset_t x;
|
__sigset_t x;
|
||||||
int sig;
|
int sig;
|
||||||
struct k_sigaction *k;
|
struct k_sigaction *k;
|
||||||
@@ -966,8 +967,12 @@ getsigpending(struct thread *thread, int delflag){
|
|||||||
|
|
||||||
lock = &thread->sigcommon->lock;
|
lock = &thread->sigcommon->lock;
|
||||||
head = &thread->sigcommon->sigpending;
|
head = &thread->sigcommon->sigpending;
|
||||||
for(;;){
|
for(;;) {
|
||||||
irqstate = ihk_mc_spinlock_lock(lock);
|
if (delflag)
|
||||||
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
|
else
|
||||||
|
mcs_rwlock_reader_lock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
list_for_each_entry_safe(pending, next, head, list){
|
list_for_each_entry_safe(pending, next, head, list){
|
||||||
for(x = pending->sigmask.__val[0], sig = 0; x; sig++, x >>= 1);
|
for(x = pending->sigmask.__val[0], sig = 0; x; sig++, x >>= 1);
|
||||||
k = thread->sigcommon->action + sig - 1;
|
k = thread->sigcommon->action + sig - 1;
|
||||||
@@ -978,15 +983,24 @@ getsigpending(struct thread *thread, int delflag){
|
|||||||
if(!(pending->sigmask.__val[0] & w)){
|
if(!(pending->sigmask.__val[0] & w)){
|
||||||
if(delflag)
|
if(delflag)
|
||||||
list_del(&pending->list);
|
list_del(&pending->list);
|
||||||
ihk_mc_spinlock_unlock(lock, irqstate);
|
|
||||||
|
if (delflag)
|
||||||
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
|
else
|
||||||
|
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
|
||||||
return pending;
|
return pending;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock(lock, irqstate);
|
|
||||||
|
if (delflag)
|
||||||
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
|
else
|
||||||
|
mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
if(lock == &thread->sigpendinglock)
|
if(lock == &thread->sigpendinglock)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
lock = &thread->sigpendinglock;
|
lock = &thread->sigpendinglock;
|
||||||
head = &thread->sigpending;
|
head = &thread->sigpending;
|
||||||
}
|
}
|
||||||
@@ -1034,22 +1048,25 @@ check_signal(unsigned long rc, void *regs0, int num)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock(&(cpu_local_var(runq_lock)), irqstate);
|
ihk_mc_spinlock_unlock(&(cpu_local_var(runq_lock)), irqstate);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(regs != NULL && !interrupt_from_user(regs)) {
|
if(regs != NULL && !interrupt_from_user(regs)) {
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(;;){
|
for(;;){
|
||||||
pending = getsigpending(thread, 1);
|
pending = getsigpending(thread, 1);
|
||||||
if(!pending) {
|
if(!pending) {
|
||||||
dkprintf("check_signal,queue is empty\n");
|
dkprintf("check_signal,queue is empty\n");
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_signal(rc, regs, thread, pending, num);
|
do_signal(rc, regs, thread, pending, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
@@ -1063,7 +1080,8 @@ do_kill(struct thread *thread, int pid, int tid, int sig, siginfo_t *info,
|
|||||||
struct thread *tthread = NULL;
|
struct thread *tthread = NULL;
|
||||||
int i;
|
int i;
|
||||||
__sigset_t mask;
|
__sigset_t mask;
|
||||||
ihk_spinlock_t *savelock = NULL;
|
mcs_rwlock_lock_t *savelock = NULL;
|
||||||
|
struct mcs_rwlock_node mcs_rw_node;
|
||||||
struct list_head *head = NULL;
|
struct list_head *head = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
unsigned long irqstate = 0;
|
unsigned long irqstate = 0;
|
||||||
@@ -1247,7 +1265,7 @@ done:
|
|||||||
|
|
||||||
doint = 0;
|
doint = 0;
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(savelock);
|
mcs_rwlock_writer_lock_noirq(savelock, &mcs_rw_node);
|
||||||
|
|
||||||
/* Put signal event even when handler is SIG_IGN or SIG_DFL
|
/* Put signal event even when handler is SIG_IGN or SIG_DFL
|
||||||
because target ptraced thread must call ptrace_report_signal
|
because target ptraced thread must call ptrace_report_signal
|
||||||
@@ -1286,7 +1304,7 @@ done:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock_noirq(savelock);
|
mcs_rwlock_writer_unlock_noirq(savelock, &mcs_rw_node);
|
||||||
cpu_restore_interrupt(irqstate);
|
cpu_restore_interrupt(irqstate);
|
||||||
|
|
||||||
if (doint && !(mask & tthread->sigmask.__val[0])) {
|
if (doint && !(mask & tthread->sigmask.__val[0])) {
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ else
|
|||||||
irqbalance_used="no"
|
irqbalance_used="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while getopts :i:k:c:m:o:f: OPT
|
turbo=""
|
||||||
|
|
||||||
|
while getopts :ti:k:c:m:o:f: OPT
|
||||||
do
|
do
|
||||||
case ${OPT} in
|
case ${OPT} in
|
||||||
f) facility=${OPTARG}
|
f) facility=${OPTARG}
|
||||||
@@ -76,6 +78,8 @@ do
|
|||||||
;;
|
;;
|
||||||
m) mem=${OPTARG}
|
m) mem=${OPTARG}
|
||||||
;;
|
;;
|
||||||
|
t) turbo="turbo"
|
||||||
|
;;
|
||||||
*) echo "invalid option -${OPT}" >&2
|
*) echo "invalid option -${OPT}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
esac
|
esac
|
||||||
@@ -340,7 +344,7 @@ if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Set kernel arguments
|
# Set kernel arguments
|
||||||
if ! ${SBINDIR}/ihkosctl 0 kargs "hidos ksyslogd=${LOGMODE}"; then
|
if ! ${SBINDIR}/ihkosctl 0 kargs "hidos ksyslogd=${LOGMODE} $turbo"; then
|
||||||
echo "error: setting kernel arguments" >&2
|
echo "error: setting kernel arguments" >&2
|
||||||
error_exit "os_created"
|
error_exit "os_created"
|
||||||
fi
|
fi
|
||||||
@@ -374,7 +378,7 @@ if [ "$enable_mcoverlay" == "yes" ]; then
|
|||||||
fi
|
fi
|
||||||
while [ ! -e /proc/mcos0 ]
|
while [ ! -e /proc/mcos0 ]
|
||||||
do
|
do
|
||||||
sleep 1
|
sleep 0.1
|
||||||
done
|
done
|
||||||
if [ ! -e /tmp/mcos/mcos0_proc ]; then mkdir -p /tmp/mcos/mcos0_proc; fi
|
if [ ! -e /tmp/mcos/mcos0_proc ]; then mkdir -p /tmp/mcos/mcos0_proc; fi
|
||||||
if [ ! -e /tmp/mcos/mcos0_proc_upper ]; then mkdir -p /tmp/mcos/mcos0_proc_upper; fi
|
if [ ! -e /tmp/mcos/mcos0_proc_upper ]; then mkdir -p /tmp/mcos/mcos0_proc_upper; fi
|
||||||
|
|||||||
2
configure
vendored
2
configure
vendored
@@ -2922,6 +2922,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
|
|||||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||||
|
|
||||||
XCC=$CC
|
XCC=$CC
|
||||||
|
CFLAGS="$CFLAGS -ffreestanding -fno-tree-loop-distribute-patterns"
|
||||||
;;
|
;;
|
||||||
builtin-mic)
|
builtin-mic)
|
||||||
ARCH=k1om
|
ARCH=k1om
|
||||||
@@ -3912,6 +3913,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_headers="$ac_config_headers executer/config.h"
|
ac_config_headers="$ac_config_headers executer/config.h"
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ case $WITH_TARGET in
|
|||||||
ARCH=`uname -m`
|
ARCH=`uname -m`
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
XCC=$CC
|
XCC=$CC
|
||||||
|
CFLAGS="$CFLAGS -ffreestanding -fno-tree-loop-distribute-patterns"
|
||||||
;;
|
;;
|
||||||
builtin-mic)
|
builtin-mic)
|
||||||
ARCH=k1om
|
ARCH=k1om
|
||||||
@@ -286,6 +287,7 @@ AC_SUBST(ETCDIR)
|
|||||||
AC_SUBST(KMODDIR)
|
AC_SUBST(KMODDIR)
|
||||||
AC_SUBST(KERNDIR)
|
AC_SUBST(KERNDIR)
|
||||||
AC_SUBST(MANDIR)
|
AC_SUBST(MANDIR)
|
||||||
|
AC_SUBST(CFLAGS)
|
||||||
AC_SUBST(ENABLE_MCOVERLAYFS)
|
AC_SUBST(ENABLE_MCOVERLAYFS)
|
||||||
|
|
||||||
AC_SUBST(IHK_VERSION)
|
AC_SUBST(IHK_VERSION)
|
||||||
|
|||||||
@@ -1550,7 +1550,7 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_threads = ncpu + 1;
|
n_threads = ncpu;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: keep thread_data ncpu sized despite that there are only
|
* XXX: keep thread_data ncpu sized despite that there are only
|
||||||
@@ -1561,6 +1561,10 @@ int main(int argc, char **argv)
|
|||||||
* TODO: implement dynaic thread pool resizing.
|
* TODO: implement dynaic thread pool resizing.
|
||||||
*/
|
*/
|
||||||
thread_data = (struct thread_data_s *)malloc(sizeof(struct thread_data_s) * (ncpu + 1));
|
thread_data = (struct thread_data_s *)malloc(sizeof(struct thread_data_s) * (ncpu + 1));
|
||||||
|
if (!thread_data) {
|
||||||
|
fprintf(stderr, "error: allocating thread pool data\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
memset(thread_data, '\0', sizeof(struct thread_data_s) * (ncpu + 1));
|
memset(thread_data, '\0', sizeof(struct thread_data_s) * (ncpu + 1));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ OBJS += process.o copy.o waitq.o futex.o timer.o plist.o fileobj.o shmobj.o
|
|||||||
OBJS += zeroobj.o procfs.o devobj.o sysfs.o
|
OBJS += zeroobj.o procfs.o devobj.o sysfs.o
|
||||||
DEPSRCS=$(wildcard $(SRC)/*.c)
|
DEPSRCS=$(wildcard $(SRC)/*.c)
|
||||||
|
|
||||||
CFLAGS += -I$(SRC)/include -D__KERNEL__ -g
|
CFLAGS += -I$(SRC)/include -D__KERNEL__ -g -fno-omit-frame-pointer -fno-inline -fno-inline-small-functions
|
||||||
LDFLAGS += -e arch_start
|
LDFLAGS += -e arch_start
|
||||||
IHKOBJ = ihk/ihk.o
|
IHKOBJ = ihk/ihk.o
|
||||||
|
|
||||||
include $(SRC)/config/config.$(TARGET)
|
include $(SRC)/config/config.$(TARGET)
|
||||||
include $(IHKBASE)/Makefile.common
|
include @abs_builddir@/../../ihk/cokernel/Makefile.common
|
||||||
|
|
||||||
# CFLAGS += -I$(SRC)/../arch/$(IHKARCH)/kernel/include -I$(SRC)/../lib/include
|
# CFLAGS += -I$(SRC)/../arch/$(IHKARCH)/kernel/include -I$(SRC)/../lib/include
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ V ?= $(VERBOSE)
|
|||||||
KERNEL = kernel.img
|
KERNEL = kernel.img
|
||||||
KERNELS = $(addsuffix /$(KERNEL),$(addprefix $(O)/,$(BUILD_TARGET)))
|
KERNELS = $(addsuffix /$(KERNEL),$(addprefix $(O)/,$(BUILD_TARGET)))
|
||||||
|
|
||||||
SUBCMD_OPTS = V='$(V)'
|
SUBCMD_OPTS = V='$(V)' BUILD_IHK_COKERNEL=@abs_builddir@/../../ihk/cokernel
|
||||||
|
|
||||||
$(if $(O),,$(error Specify the compilation target directory))
|
$(if $(O),,$(error Specify the compilation target directory))
|
||||||
#$(if $(shell ls $(IHKBASE)/Makefile),,\
|
#$(if $(shell ls $(IHKBASE)/Makefile),,\
|
||||||
|
|||||||
@@ -32,4 +32,6 @@ extern void cpu_sysfs_setup(void);
|
|||||||
|
|
||||||
extern char *find_command_line(char *name);
|
extern char *find_command_line(char *name);
|
||||||
|
|
||||||
|
extern int num_processors;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -232,6 +232,8 @@ enum mpol_rebind_step {
|
|||||||
#include <waitq.h>
|
#include <waitq.h>
|
||||||
#include <futex.h>
|
#include <futex.h>
|
||||||
|
|
||||||
|
//#define TRACK_SYSCALLS
|
||||||
|
|
||||||
struct resource_set;
|
struct resource_set;
|
||||||
struct process_hash;
|
struct process_hash;
|
||||||
struct thread_hash;
|
struct thread_hash;
|
||||||
@@ -405,7 +407,7 @@ struct mckfd {
|
|||||||
#define SFD_NONBLOCK 04000
|
#define SFD_NONBLOCK 04000
|
||||||
|
|
||||||
struct sig_common {
|
struct sig_common {
|
||||||
ihk_spinlock_t lock;
|
mcs_rwlock_lock_t lock;
|
||||||
ihk_atomic_t use;
|
ihk_atomic_t use;
|
||||||
struct k_sigaction action[_NSIG];
|
struct k_sigaction action[_NSIG];
|
||||||
struct list_head sigpending;
|
struct list_head sigpending;
|
||||||
@@ -466,7 +468,7 @@ struct process {
|
|||||||
// V +---- |
|
// V +---- |
|
||||||
// PS_STOPPED -----+
|
// PS_STOPPED -----+
|
||||||
// (PS_TRACED)
|
// (PS_TRACED)
|
||||||
int exit_status;
|
int exit_status; // only for zombie
|
||||||
|
|
||||||
/* Store exit_status for a group of threads when stopped by SIGSTOP.
|
/* 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
|
exit_status can't be used because values of exit_status of threads
|
||||||
@@ -578,6 +580,7 @@ struct thread {
|
|||||||
// PS_TRACED
|
// PS_TRACED
|
||||||
// PS_INTERRPUTIBLE
|
// PS_INTERRPUTIBLE
|
||||||
// PS_UNINTERRUPTIBLE
|
// PS_UNINTERRUPTIBLE
|
||||||
|
int exit_status;
|
||||||
|
|
||||||
// process vm
|
// process vm
|
||||||
struct process_vm *vm;
|
struct process_vm *vm;
|
||||||
@@ -608,12 +611,20 @@ struct thread {
|
|||||||
fp_regs_struct *fp_regs;
|
fp_regs_struct *fp_regs;
|
||||||
int in_syscall_offload;
|
int in_syscall_offload;
|
||||||
|
|
||||||
|
#ifdef TRACK_SYSCALLS
|
||||||
|
int socc_enabled;
|
||||||
|
uint64_t *syscall_times;
|
||||||
|
uint32_t *syscall_cnts;
|
||||||
|
uint64_t *offload_times;
|
||||||
|
uint32_t *offload_cnts;
|
||||||
|
#endif // TRACK_SYSCALLS
|
||||||
|
|
||||||
// signal
|
// signal
|
||||||
struct sig_common *sigcommon;
|
struct sig_common *sigcommon;
|
||||||
sigset_t sigmask;
|
sigset_t sigmask;
|
||||||
stack_t sigstack;
|
stack_t sigstack;
|
||||||
struct list_head sigpending;
|
struct list_head sigpending;
|
||||||
ihk_spinlock_t sigpendinglock;
|
mcs_rwlock_lock_t sigpendinglock;
|
||||||
volatile int sigevent;
|
volatile int sigevent;
|
||||||
|
|
||||||
// gpio
|
// gpio
|
||||||
|
|||||||
@@ -754,6 +754,8 @@ void remote_flush_tlb_cpumask(struct process_vm *vm,
|
|||||||
flush_tlb();
|
flush_tlb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Flush on this core */
|
||||||
|
flush_tlb_single(addr & PAGE_MASK);
|
||||||
/* Wait for all cores */
|
/* Wait for all cores */
|
||||||
while (ihk_atomic_read(&flush_entry->pending) != 0) {
|
while (ihk_atomic_read(&flush_entry->pending) != 0) {
|
||||||
cpu_pause();
|
cpu_pause();
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ init_process(struct process *proc, struct process *parent)
|
|||||||
{
|
{
|
||||||
/* These will be filled out when changing status */
|
/* These will be filled out when changing status */
|
||||||
proc->pid = -1;
|
proc->pid = -1;
|
||||||
proc->exit_status = -1;
|
|
||||||
proc->status = PS_RUNNING;
|
proc->status = PS_RUNNING;
|
||||||
|
|
||||||
if(parent){
|
if(parent){
|
||||||
@@ -278,10 +277,10 @@ create_thread(unsigned long user_pc)
|
|||||||
dkprintf("fork(): sigshared\n");
|
dkprintf("fork(): sigshared\n");
|
||||||
|
|
||||||
ihk_atomic_set(&thread->sigcommon->use, 1);
|
ihk_atomic_set(&thread->sigcommon->use, 1);
|
||||||
ihk_mc_spinlock_init(&thread->sigcommon->lock);
|
mcs_rwlock_init(&thread->sigcommon->lock);
|
||||||
INIT_LIST_HEAD(&thread->sigcommon->sigpending);
|
INIT_LIST_HEAD(&thread->sigcommon->sigpending);
|
||||||
|
|
||||||
ihk_mc_spinlock_init(&thread->sigpendinglock);
|
mcs_rwlock_init(&thread->sigpendinglock);
|
||||||
INIT_LIST_HEAD(&thread->sigpending);
|
INIT_LIST_HEAD(&thread->sigpending);
|
||||||
|
|
||||||
thread->sigstack.ss_sp = NULL;
|
thread->sigstack.ss_sp = NULL;
|
||||||
@@ -298,6 +297,7 @@ create_thread(unsigned long user_pc)
|
|||||||
if(init_process_vm(proc, asp, vm) != 0){
|
if(init_process_vm(proc, asp, vm) != 0){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
thread->exit_status = -1;
|
||||||
|
|
||||||
cpu_set(ihk_mc_get_processor_id(), &thread->vm->address_space->cpu_set,
|
cpu_set(ihk_mc_get_processor_id(), &thread->vm->address_space->cpu_set,
|
||||||
&thread->vm->address_space->cpu_set_lock);
|
&thread->vm->address_space->cpu_set_lock);
|
||||||
@@ -441,11 +441,11 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
|
|||||||
memcpy(thread->sigcommon->action, org->sigcommon->action,
|
memcpy(thread->sigcommon->action, org->sigcommon->action,
|
||||||
sizeof(struct k_sigaction) * _NSIG);
|
sizeof(struct k_sigaction) * _NSIG);
|
||||||
ihk_atomic_set(&thread->sigcommon->use, 1);
|
ihk_atomic_set(&thread->sigcommon->use, 1);
|
||||||
ihk_mc_spinlock_init(&thread->sigcommon->lock);
|
mcs_rwlock_init(&thread->sigcommon->lock);
|
||||||
INIT_LIST_HEAD(&thread->sigcommon->sigpending);
|
INIT_LIST_HEAD(&thread->sigcommon->sigpending);
|
||||||
// TODO: copy signalfd
|
// TODO: copy signalfd
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_init(&thread->sigpendinglock);
|
mcs_rwlock_init(&thread->sigpendinglock);
|
||||||
INIT_LIST_HEAD(&thread->sigpending);
|
INIT_LIST_HEAD(&thread->sigpending);
|
||||||
thread->sigmask = org->sigmask;
|
thread->sigmask = org->sigmask;
|
||||||
|
|
||||||
@@ -1690,10 +1690,9 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
|
|||||||
range = lookup_process_memory_range(vm, fault_addr, fault_addr+1);
|
range = lookup_process_memory_range(vm, fault_addr, fault_addr+1);
|
||||||
if (range == NULL) {
|
if (range == NULL) {
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx):"
|
dkprintf("do_page_fault_process_vm(): vm: %p, addr: %p, reason: %lx):"
|
||||||
"out of range. %d\n",
|
"out of range: %d\n",
|
||||||
ihk_mc_get_processor_id(), vm,
|
vm, fault_addr0, reason, error);
|
||||||
fault_addr0, reason, error);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1723,10 +1722,18 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
|
|||||||
kprintf("if (((range->flag & VR_PROT_MASK) == VR_PROT_NONE))\n");
|
kprintf("if (((range->flag & VR_PROT_MASK) == VR_PROT_NONE))\n");
|
||||||
if (((reason & PF_WRITE) && !(reason & PF_PATCH)))
|
if (((reason & PF_WRITE) && !(reason & PF_PATCH)))
|
||||||
kprintf("if (((reason & PF_WRITE) && !(reason & PF_PATCH)))\n");
|
kprintf("if (((reason & PF_WRITE) && !(reason & PF_PATCH)))\n");
|
||||||
if (!(range->flag & VR_PROT_WRITE))
|
if (!(range->flag & VR_PROT_WRITE)) {
|
||||||
kprintf("if (!(range->flag & VR_PROT_WRITE))\n");
|
kprintf("if (!(range->flag & VR_PROT_WRITE))\n");
|
||||||
if ((reason & PF_INSTR) && !(range->flag & VR_PROT_EXEC))
|
//kprintf("setting VR_PROT_WRITE\n");
|
||||||
|
//range->flag |= VR_PROT_WRITE;
|
||||||
|
//goto cont;
|
||||||
|
}
|
||||||
|
if ((reason & PF_INSTR) && !(range->flag & VR_PROT_EXEC)) {
|
||||||
kprintf("if ((reason & PF_INSTR) && !(range->flag & VR_PROT_EXEC))\n");
|
kprintf("if ((reason & PF_INSTR) && !(range->flag & VR_PROT_EXEC))\n");
|
||||||
|
//kprintf("setting VR_PROT_EXEC\n");
|
||||||
|
//range->flag |= VR_PROT_EXEC;
|
||||||
|
//goto cont;
|
||||||
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2717,7 +2724,9 @@ redo:
|
|||||||
restore_fp_regs(next);
|
restore_fp_regs(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
ihk_mc_load_page_table(next->vm->address_space->page_table);
|
if (prev && prev->vm->address_space->page_table !=
|
||||||
|
next->vm->address_space->page_table)
|
||||||
|
ihk_mc_load_page_table(next->vm->address_space->page_table);
|
||||||
|
|
||||||
dkprintf("[%d] schedule: tlsblock_base: 0x%lX\n",
|
dkprintf("[%d] schedule: tlsblock_base: 0x%lX\n",
|
||||||
ihk_mc_get_processor_id(), next->tlsblock_base);
|
ihk_mc_get_processor_id(), next->tlsblock_base);
|
||||||
@@ -2949,6 +2958,7 @@ find_thread(int pid, int tid, struct mcs_rwlock_node_irqsave *lock)
|
|||||||
if(tid <= 0)
|
if(tid <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
mcs_rwlock_reader_lock(&thash->lock[hash], lock);
|
mcs_rwlock_reader_lock(&thash->lock[hash], lock);
|
||||||
|
retry:
|
||||||
list_for_each_entry(thread, &thash->list[hash], hash_list){
|
list_for_each_entry(thread, &thash->list[hash], hash_list){
|
||||||
if(thread->tid == tid){
|
if(thread->tid == tid){
|
||||||
if(pid <= 0)
|
if(pid <= 0)
|
||||||
@@ -2957,6 +2967,13 @@ find_thread(int pid, int tid, struct mcs_rwlock_node_irqsave *lock)
|
|||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* If no thread with pid == tid was found, then we may be looking for a
|
||||||
|
* specific thread (not the main thread of the process), try to find it
|
||||||
|
* based on tid only */
|
||||||
|
if (pid > 0 && pid == tid) {
|
||||||
|
pid = 0;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
mcs_rwlock_reader_unlock(&thash->lock[hash], lock);
|
mcs_rwlock_reader_unlock(&thash->lock[hash], lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <page.h>
|
#include <page.h>
|
||||||
#include <mman.h>
|
#include <mman.h>
|
||||||
#include <bitmap.h>
|
#include <bitmap.h>
|
||||||
|
#include <init.h>
|
||||||
|
|
||||||
//#define DEBUG_PRINT_PROCFS
|
//#define DEBUG_PRINT_PROCFS
|
||||||
|
|
||||||
|
|||||||
381
kernel/syscall.c
381
kernel/syscall.c
@@ -129,6 +129,95 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
|||||||
static void do_mod_exit(int status);
|
static void do_mod_exit(int status);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACK_SYSCALLS
|
||||||
|
|
||||||
|
#define SOCC_CLEAR 1
|
||||||
|
#define SOCC_ON 2
|
||||||
|
#define SOCC_OFF 4
|
||||||
|
#define SOCC_PRINT 8
|
||||||
|
|
||||||
|
void print_syscall_stats(struct thread *thread)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
flags = kprintf_lock();
|
||||||
|
|
||||||
|
for (i = 0; i < 300; ++i) {
|
||||||
|
if (!thread->syscall_cnts[i] &&
|
||||||
|
!thread->offload_cnts[i]) continue;
|
||||||
|
|
||||||
|
//__kprintf("(%20s): sys.cnt: %3lu (%15lukC)\n",
|
||||||
|
__kprintf("(%3d,%20s): sys.cnt: %5lu (%10lukC), offl.cnt: %5lu (%10lukC)\n",
|
||||||
|
i,
|
||||||
|
syscall_name[i],
|
||||||
|
thread->syscall_cnts[i],
|
||||||
|
(thread->syscall_times[i] /
|
||||||
|
(thread->syscall_cnts[i] ? thread->syscall_cnts[i] : 1))
|
||||||
|
/ 1000,
|
||||||
|
thread->offload_cnts[i],
|
||||||
|
(thread->offload_times[i] /
|
||||||
|
(thread->offload_cnts[i] ? thread->offload_cnts[i] : 1))
|
||||||
|
/ 1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf_unlock(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void alloc_syscall_counters(struct thread *thread)
|
||||||
|
{
|
||||||
|
thread->syscall_times = kmalloc(sizeof(*thread->syscall_times) * 300, IHK_MC_AP_NOWAIT);
|
||||||
|
thread->syscall_cnts = kmalloc(sizeof(*thread->syscall_cnts) * 300, IHK_MC_AP_NOWAIT);
|
||||||
|
thread->offload_times = kmalloc(sizeof(*thread->offload_times) * 300, IHK_MC_AP_NOWAIT);
|
||||||
|
thread->offload_cnts = kmalloc(sizeof(*thread->offload_cnts) * 300, IHK_MC_AP_NOWAIT);
|
||||||
|
|
||||||
|
if (!thread->syscall_times ||
|
||||||
|
!thread->syscall_cnts ||
|
||||||
|
!thread->offload_times ||
|
||||||
|
!thread->offload_cnts) {
|
||||||
|
kprintf("ERROR: allocating counters\n");
|
||||||
|
panic("");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(thread->syscall_times, 0, sizeof(*thread->syscall_times) * 300);
|
||||||
|
memset(thread->syscall_cnts, 0, sizeof(*thread->syscall_cnts) * 300);
|
||||||
|
memset(thread->offload_times, 0, sizeof(*thread->offload_times) * 300);
|
||||||
|
memset(thread->offload_cnts, 0, sizeof(*thread->offload_cnts) * 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
SYSCALL_DECLARE(syscall_offload_clr_cntrs)
|
||||||
|
{
|
||||||
|
int flag = (int)ihk_mc_syscall_arg0(ctx);
|
||||||
|
struct thread *thread = cpu_local_var(current);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (flag & SOCC_PRINT)
|
||||||
|
print_syscall_stats(thread);
|
||||||
|
|
||||||
|
if (flag & SOCC_CLEAR) {
|
||||||
|
for (i = 0; i < 300; ++i) {
|
||||||
|
if (!thread->syscall_cnts[i] &&
|
||||||
|
!thread->offload_cnts[i]) continue;
|
||||||
|
|
||||||
|
thread->syscall_cnts[i] = 0;
|
||||||
|
thread->syscall_times[i] = 0;
|
||||||
|
thread->offload_cnts[i] = 0;
|
||||||
|
thread->offload_times[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & SOCC_ON) {
|
||||||
|
thread->socc_enabled = 1;
|
||||||
|
}
|
||||||
|
else if (flag & SOCC_OFF) {
|
||||||
|
thread->socc_enabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif // TRACK_SYSCALLS
|
||||||
|
|
||||||
static void send_syscall(struct syscall_request *req, int cpu, int pid, struct syscall_response *res)
|
static void send_syscall(struct syscall_request *req, int cpu, int pid, struct syscall_response *res)
|
||||||
{
|
{
|
||||||
struct ikc_scd_packet packet IHK_DMA_ALIGN;
|
struct ikc_scd_packet packet IHK_DMA_ALIGN;
|
||||||
@@ -189,6 +278,10 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
|
|||||||
unsigned long irqstate;
|
unsigned long irqstate;
|
||||||
struct thread *thread = cpu_local_var(current);
|
struct thread *thread = cpu_local_var(current);
|
||||||
struct process *proc = thread->proc;
|
struct process *proc = thread->proc;
|
||||||
|
#ifdef TRACK_SYSCALLS
|
||||||
|
uint64_t t_s;
|
||||||
|
t_s = rdtsc();
|
||||||
|
#endif // TRACK_SYSCALLS
|
||||||
|
|
||||||
dkprintf("SC(%d)[%3d] sending syscall\n",
|
dkprintf("SC(%d)[%3d] sending syscall\n",
|
||||||
ihk_mc_get_processor_id(),
|
ihk_mc_get_processor_id(),
|
||||||
@@ -307,6 +400,23 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
|
|||||||
if(req->number != __NR_exit_group){
|
if(req->number != __NR_exit_group){
|
||||||
--thread->in_syscall_offload;
|
--thread->in_syscall_offload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TRACK_SYSCALLS
|
||||||
|
if (req->number < 300) {
|
||||||
|
if (!cpu_local_var(current)->offload_cnts) {
|
||||||
|
alloc_syscall_counters(cpu_local_var(current));
|
||||||
|
}
|
||||||
|
if (cpu_local_var(current)->socc_enabled) {
|
||||||
|
cpu_local_var(current)->offload_times[req->number] +=
|
||||||
|
(rdtsc() - t_s);
|
||||||
|
cpu_local_var(current)->offload_cnts[req->number]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dkprintf("offload syscall > 300?? : %d\n", req->number);
|
||||||
|
}
|
||||||
|
#endif // TRACK_SYSCALLS
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,16 +457,16 @@ static int wait_zombie(struct thread *thread, struct process *child, int *status
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_stopped(struct thread *thread, struct process *child, int *status, int options)
|
static int wait_stopped(struct thread *thread, struct process *child, struct thread *c_thread, int *status, int options)
|
||||||
{
|
{
|
||||||
dkprintf("wait_stopped,proc->pid=%d,child->pid=%d,options=%08x\n",
|
dkprintf("wait_stopped,proc->pid=%d,child->pid=%d,options=%08x\n",
|
||||||
thread->proc->pid, child->pid, options);
|
thread->proc->pid, child->pid, options);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Copy exit_status created in do_signal */
|
/* Copy exit_status created in do_signal */
|
||||||
int *exit_status = child->status == PS_STOPPED ?
|
int *exit_status = (child->status == PS_STOPPED || !c_thread) ?
|
||||||
&child->group_exit_status :
|
&child->group_exit_status :
|
||||||
&child->exit_status;
|
&c_thread->exit_status;
|
||||||
|
|
||||||
/* Skip this process because exit_status has been reaped. */
|
/* Skip this process because exit_status has been reaped. */
|
||||||
if (!*exit_status) {
|
if (!*exit_status) {
|
||||||
@@ -400,6 +510,26 @@ static int wait_continued(struct thread *thread, struct process *child, int *sta
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct thread *find_thread_of_process(struct process *child, int pid)
|
||||||
|
{
|
||||||
|
int c_found = 0;
|
||||||
|
struct mcs_rwlock_node c_lock;
|
||||||
|
struct thread *c_thread = NULL;
|
||||||
|
|
||||||
|
mcs_rwlock_reader_lock_noirq(&child->threads_lock, &c_lock);
|
||||||
|
list_for_each_entry(c_thread, &child->threads_list, siblings_list) {
|
||||||
|
if (c_thread->tid == pid) {
|
||||||
|
c_found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&child->threads_lock, &c_lock);
|
||||||
|
if (!c_found) c_thread = NULL;
|
||||||
|
|
||||||
|
return c_thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From glibc: INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL);
|
* From glibc: INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL);
|
||||||
*/
|
*/
|
||||||
@@ -415,22 +545,30 @@ do_wait(int pid, int *status, int options, void *rusage)
|
|||||||
int empty = 1;
|
int empty = 1;
|
||||||
int orgpid = pid;
|
int orgpid = pid;
|
||||||
struct mcs_rwlock_node lock;
|
struct mcs_rwlock_node lock;
|
||||||
|
struct thread *c_thread = NULL;
|
||||||
|
|
||||||
dkprintf("wait4,thread->pid=%d,pid=%d\n", thread->proc->pid, pid);
|
dkprintf("wait4(): current->proc->pid: %d, pid: %d\n", thread->proc->pid, pid);
|
||||||
|
|
||||||
rescan:
|
rescan:
|
||||||
pid = orgpid;
|
pid = orgpid;
|
||||||
|
|
||||||
mcs_rwlock_writer_lock_noirq(&thread->proc->children_lock, &lock);
|
mcs_rwlock_writer_lock_noirq(&thread->proc->children_lock, &lock);
|
||||||
list_for_each_entry_safe(child, next, &proc->children_list, siblings_list) {
|
list_for_each_entry_safe(child, next, &proc->children_list, siblings_list) {
|
||||||
|
/*
|
||||||
if (!(!!(options & __WCLONE) ^ (child->termsig == SIGCHLD))) {
|
if (!(!!(options & __WCLONE) ^ (child->termsig == SIGCHLD))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Find thread with pid == tid, this will be either the main thread
|
||||||
|
* or the one we are looking for specifically when __WCLONE is passed */
|
||||||
|
//if (options & __WCLONE)
|
||||||
|
c_thread = find_thread_of_process(child, pid);
|
||||||
|
|
||||||
if ((pid < 0 && -pid == child->pgid) ||
|
if ((pid < 0 && -pid == child->pgid) ||
|
||||||
pid == -1 ||
|
pid == -1 ||
|
||||||
(pid == 0 && pgid == child->pgid) ||
|
(pid == 0 && pgid == child->pgid) ||
|
||||||
(pid > 0 && pid == child->pid)) {
|
(pid > 0 && pid == child->pid) || c_thread != NULL) {
|
||||||
|
|
||||||
empty = 0;
|
empty = 0;
|
||||||
|
|
||||||
@@ -478,8 +616,11 @@ do_wait(int pid, int *status, int options, void *rusage)
|
|||||||
if(!(child->ptrace & PT_TRACED) &&
|
if(!(child->ptrace & PT_TRACED) &&
|
||||||
(child->signal_flags & SIGNAL_STOP_STOPPED) &&
|
(child->signal_flags & SIGNAL_STOP_STOPPED) &&
|
||||||
(options & WUNTRACED)) {
|
(options & WUNTRACED)) {
|
||||||
|
/* Find main thread of process if pid == -1 */
|
||||||
|
if (pid == -1)
|
||||||
|
c_thread = find_thread_of_process(child, child->pid);
|
||||||
/* Not ptraced and in stopped state and WUNTRACED is specified */
|
/* Not ptraced and in stopped state and WUNTRACED is specified */
|
||||||
ret = wait_stopped(thread, child, status, options);
|
ret = wait_stopped(thread, child, c_thread, status, options);
|
||||||
if(!(options & WNOWAIT)){
|
if(!(options & WNOWAIT)){
|
||||||
child->signal_flags &= ~SIGNAL_STOP_STOPPED;
|
child->signal_flags &= ~SIGNAL_STOP_STOPPED;
|
||||||
}
|
}
|
||||||
@@ -489,8 +630,15 @@ do_wait(int pid, int *status, int options, void *rusage)
|
|||||||
|
|
||||||
if((child->ptrace & PT_TRACED) &&
|
if((child->ptrace & PT_TRACED) &&
|
||||||
(child->status & (PS_STOPPED | PS_TRACED))) {
|
(child->status & (PS_STOPPED | PS_TRACED))) {
|
||||||
ret = wait_stopped(thread, child, status, options);
|
/* Find main thread of process if pid == -1 */
|
||||||
if(ret == child->pid){
|
if (pid == -1)
|
||||||
|
c_thread = find_thread_of_process(child, child->pid);
|
||||||
|
ret = wait_stopped(thread, child, c_thread, status, options);
|
||||||
|
if(c_thread && ret == child->pid){
|
||||||
|
/* Are we looking for a specific thread? */
|
||||||
|
if (pid == c_thread->tid) {
|
||||||
|
ret = c_thread->tid;
|
||||||
|
}
|
||||||
if(!(options & WNOWAIT)){
|
if(!(options & WNOWAIT)){
|
||||||
child->signal_flags &= ~SIGNAL_STOP_STOPPED;
|
child->signal_flags &= ~SIGNAL_STOP_STOPPED;
|
||||||
}
|
}
|
||||||
@@ -639,6 +787,7 @@ terminate(int rc, int sig)
|
|||||||
int n;
|
int n;
|
||||||
int *ids = NULL;
|
int *ids = NULL;
|
||||||
struct syscall_request request IHK_DMA_ALIGN;
|
struct syscall_request request IHK_DMA_ALIGN;
|
||||||
|
int exit_status;
|
||||||
|
|
||||||
// sync perf info
|
// sync perf info
|
||||||
if(proc->monitoring_event)
|
if(proc->monitoring_event)
|
||||||
@@ -655,7 +804,7 @@ terminate(int rc, int sig)
|
|||||||
// no return
|
// no return
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
proc->exit_status = ((rc & 0x00ff) << 8) | (sig & 0xff);
|
exit_status = mythread->exit_status = ((rc & 0x00ff) << 8) | (sig & 0xff);
|
||||||
proc->status = PS_EXITED;
|
proc->status = PS_EXITED;
|
||||||
mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock);
|
mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock);
|
||||||
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
mcs_rwlock_reader_unlock(&proc->threads_lock, &lock);
|
||||||
@@ -791,7 +940,7 @@ terminate(int rc, int sig)
|
|||||||
// clean up memory
|
// clean up memory
|
||||||
if(!proc->nohost){
|
if(!proc->nohost){
|
||||||
request.number = __NR_exit_group;
|
request.number = __NR_exit_group;
|
||||||
request.args[0] = proc->exit_status;
|
request.args[0] = exit_status;
|
||||||
do_syscall(&request, ihk_mc_get_processor_id(), proc->pid);
|
do_syscall(&request, ihk_mc_get_processor_id(), proc->pid);
|
||||||
proc->nohost = 1;
|
proc->nohost = 1;
|
||||||
}
|
}
|
||||||
@@ -803,6 +952,7 @@ terminate(int rc, int sig)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
proc->status = PS_ZOMBIE;
|
proc->status = PS_ZOMBIE;
|
||||||
|
proc->exit_status = exit_status;
|
||||||
|
|
||||||
dkprintf("terminate,wakeup\n");
|
dkprintf("terminate,wakeup\n");
|
||||||
|
|
||||||
@@ -813,11 +963,11 @@ terminate(int rc, int sig)
|
|||||||
|
|
||||||
memset(&info, '\0', sizeof info);
|
memset(&info, '\0', sizeof info);
|
||||||
info.si_signo = SIGCHLD;
|
info.si_signo = SIGCHLD;
|
||||||
info.si_code = (proc->exit_status & 0x7f)?
|
info.si_code = (exit_status & 0x7f)?
|
||||||
((proc->exit_status & 0x80)?
|
((exit_status & 0x80)?
|
||||||
CLD_DUMPED: CLD_KILLED): CLD_EXITED;
|
CLD_DUMPED: CLD_KILLED): CLD_EXITED;
|
||||||
info._sifields._sigchld.si_pid = proc->pid;
|
info._sifields._sigchld.si_pid = proc->pid;
|
||||||
info._sifields._sigchld.si_status = proc->exit_status;
|
info._sifields._sigchld.si_status = exit_status;
|
||||||
error = do_kill(NULL, proc->parent->pid, -1, SIGCHLD, &info, 0);
|
error = do_kill(NULL, proc->parent->pid, -1, SIGCHLD, &info, 0);
|
||||||
dkprintf("terminate,klll %d,error=%d\n",
|
dkprintf("terminate,klll %d,error=%d\n",
|
||||||
proc->termsig, error);
|
proc->termsig, error);
|
||||||
@@ -855,7 +1005,7 @@ interrupt_syscall(int pid, int tid)
|
|||||||
ihk_mc_user_context_t ctx;
|
ihk_mc_user_context_t ctx;
|
||||||
long lerror;
|
long lerror;
|
||||||
|
|
||||||
kprintf("interrupt_syscall pid=%d tid=%d\n", pid, tid);
|
dkprintf("interrupt_syscall pid=%d tid=%d\n", pid, tid);
|
||||||
ihk_mc_syscall_arg0(&ctx) = pid;
|
ihk_mc_syscall_arg0(&ctx) = pid;
|
||||||
ihk_mc_syscall_arg1(&ctx) = tid;
|
ihk_mc_syscall_arg1(&ctx) = tid;
|
||||||
|
|
||||||
@@ -1065,7 +1215,8 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* choose mapping address */
|
/* choose mapping address */
|
||||||
error = search_free_space(len, region->map_end,
|
error = search_free_space(len, region->map_end +
|
||||||
|
(fd > 0) ? PTL4_SIZE : 0,
|
||||||
PAGE_SHIFT+p2align, &addr);
|
PAGE_SHIFT+p2align, &addr);
|
||||||
if (error) {
|
if (error) {
|
||||||
ekprintf("do_mmap:search_free_space(%lx,%lx,%d) failed. %d\n",
|
ekprintf("do_mmap:search_free_space(%lx,%lx,%d) failed. %d\n",
|
||||||
@@ -1222,7 +1373,7 @@ out:
|
|||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
ihk_mc_spinlock_unlock_noirq(&thread->vm->memory_range_lock);
|
||||||
|
|
||||||
if (!error && populated_mapping) {
|
if (!error && populated_mapping && !((vrflags & VR_PROT_MASK) == VR_PROT_NONE)) {
|
||||||
error = populate_process_memory(thread->vm, (void *)addr, len);
|
error = populate_process_memory(thread->vm, (void *)addr, len);
|
||||||
if (error) {
|
if (error) {
|
||||||
ekprintf("%s: error :populate_process_memory"
|
ekprintf("%s: error :populate_process_memory"
|
||||||
@@ -1595,7 +1746,7 @@ static int ptrace_report_clone(struct thread *thread, struct thread *new, int ev
|
|||||||
|
|
||||||
/* Save reason why stopped and process state for wait4() to reap */
|
/* Save reason why stopped and process state for wait4() to reap */
|
||||||
mcs_rwlock_writer_lock_noirq(&thread->proc->update_lock, &lock);
|
mcs_rwlock_writer_lock_noirq(&thread->proc->update_lock, &lock);
|
||||||
thread->proc->exit_status = (SIGTRAP | (event << 8));
|
thread->exit_status = (SIGTRAP | (event << 8));
|
||||||
/* Transition process state */
|
/* Transition process state */
|
||||||
thread->proc->status = PS_TRACED;
|
thread->proc->status = PS_TRACED;
|
||||||
thread->status = PS_TRACED;
|
thread->status = PS_TRACED;
|
||||||
@@ -1610,24 +1761,26 @@ static int ptrace_report_clone(struct thread *thread, struct thread *new, int ev
|
|||||||
mcs_rwlock_writer_lock_noirq(&new->proc->update_lock, &updatelock);
|
mcs_rwlock_writer_lock_noirq(&new->proc->update_lock, &updatelock);
|
||||||
/* set ptrace features to new process */
|
/* set ptrace features to new process */
|
||||||
new->proc->ptrace = thread->proc->ptrace;
|
new->proc->ptrace = thread->proc->ptrace;
|
||||||
new->proc->ppid_parent = new->proc->parent; /* maybe proc */
|
if (event != PTRACE_EVENT_CLONE) {
|
||||||
|
new->proc->ppid_parent = new->proc->parent; /* maybe proc */
|
||||||
|
}
|
||||||
|
|
||||||
if ((new->proc->ptrace & PT_TRACED) && new->ptrace_debugreg == NULL) {
|
if ((new->proc->ptrace & PT_TRACED) && new->ptrace_debugreg == NULL) {
|
||||||
alloc_debugreg(new);
|
alloc_debugreg(new);
|
||||||
}
|
}
|
||||||
|
|
||||||
mcs_rwlock_writer_lock_noirq(&new->proc->parent->children_lock, &lock);
|
if (event != PTRACE_EVENT_CLONE) {
|
||||||
list_del(&new->proc->siblings_list);
|
mcs_rwlock_writer_lock_noirq(&new->proc->parent->children_lock, &lock);
|
||||||
list_add_tail(&new->proc->ptraced_siblings_list, &new->proc->parent->ptraced_children_list);
|
list_del(&new->proc->siblings_list);
|
||||||
mcs_rwlock_writer_unlock_noirq(&new->proc->parent->children_lock, &lock);
|
list_add_tail(&new->proc->ptraced_siblings_list, &new->proc->parent->ptraced_children_list);
|
||||||
|
mcs_rwlock_writer_unlock_noirq(&new->proc->parent->children_lock, &lock);
|
||||||
new->proc->parent = thread->proc->parent; /* new ptracing parent */
|
new->proc->parent = thread->proc->parent; /* new ptracing parent */
|
||||||
mcs_rwlock_writer_lock_noirq(&new->proc->parent->children_lock, &lock);
|
mcs_rwlock_writer_lock_noirq(&new->proc->parent->children_lock, &lock);
|
||||||
list_add_tail(&new->proc->siblings_list, &new->proc->parent->children_list);
|
list_add_tail(&new->proc->siblings_list, &new->proc->parent->children_list);
|
||||||
mcs_rwlock_writer_unlock_noirq(&new->proc->parent->children_lock, &lock);
|
mcs_rwlock_writer_unlock_noirq(&new->proc->parent->children_lock, &lock);
|
||||||
|
}
|
||||||
/* trace and SIGSTOP */
|
/* trace and SIGSTOP */
|
||||||
new->proc->exit_status = SIGSTOP;
|
new->exit_status = SIGSTOP;
|
||||||
new->proc->status = PS_TRACED;
|
new->proc->status = PS_TRACED;
|
||||||
new->status = PS_TRACED;
|
new->status = PS_TRACED;
|
||||||
|
|
||||||
@@ -1639,7 +1792,7 @@ static int ptrace_report_clone(struct thread *thread, struct thread *new, int ev
|
|||||||
info.si_signo = SIGCHLD;
|
info.si_signo = SIGCHLD;
|
||||||
info.si_code = CLD_TRAPPED;
|
info.si_code = CLD_TRAPPED;
|
||||||
info._sifields._sigchld.si_pid = thread->proc->pid;
|
info._sifields._sigchld.si_pid = thread->proc->pid;
|
||||||
info._sifields._sigchld.si_status = thread->proc->exit_status;
|
info._sifields._sigchld.si_status = thread->exit_status;
|
||||||
rc = do_kill(cpu_local_var(current), parent_pid, -1, SIGCHLD, &info, 0);
|
rc = do_kill(cpu_local_var(current), parent_pid, -1, SIGCHLD, &info, 0);
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
dkprintf("ptrace_report_clone,do_kill failed\n");
|
dkprintf("ptrace_report_clone,do_kill failed\n");
|
||||||
@@ -2473,16 +2626,16 @@ do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
|
|||||||
{
|
{
|
||||||
struct thread *thread = cpu_local_var(current);
|
struct thread *thread = cpu_local_var(current);
|
||||||
struct k_sigaction *k;
|
struct k_sigaction *k;
|
||||||
long irqstate;
|
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||||
ihk_mc_user_context_t ctx0;
|
ihk_mc_user_context_t ctx0;
|
||||||
|
|
||||||
irqstate = ihk_mc_spinlock_lock(&thread->sigcommon->lock);
|
mcs_rwlock_writer_lock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
k = thread->sigcommon->action + sig - 1;
|
k = thread->sigcommon->action + sig - 1;
|
||||||
if(oact)
|
if(oact)
|
||||||
memcpy(oact, k, sizeof(struct k_sigaction));
|
memcpy(oact, k, sizeof(struct k_sigaction));
|
||||||
if(act)
|
if(act)
|
||||||
memcpy(k, act, sizeof(struct k_sigaction));
|
memcpy(k, act, sizeof(struct k_sigaction));
|
||||||
ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate);
|
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
|
|
||||||
if(act){
|
if(act){
|
||||||
ihk_mc_syscall_arg0(&ctx0) = sig;
|
ihk_mc_syscall_arg0(&ctx0) = sig;
|
||||||
@@ -2654,10 +2807,10 @@ fault:
|
|||||||
|
|
||||||
SYSCALL_DECLARE(rt_sigpending)
|
SYSCALL_DECLARE(rt_sigpending)
|
||||||
{
|
{
|
||||||
int flag;
|
|
||||||
struct sig_pending *pending;
|
struct sig_pending *pending;
|
||||||
struct list_head *head;
|
struct list_head *head;
|
||||||
ihk_spinlock_t *lock;
|
mcs_rwlock_lock_t *lock;
|
||||||
|
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||||
__sigset_t w = 0;
|
__sigset_t w = 0;
|
||||||
struct thread *thread = cpu_local_var(current);
|
struct thread *thread = cpu_local_var(current);
|
||||||
sigset_t *set = (sigset_t *)ihk_mc_syscall_arg0(ctx);
|
sigset_t *set = (sigset_t *)ihk_mc_syscall_arg0(ctx);
|
||||||
@@ -2668,19 +2821,19 @@ SYSCALL_DECLARE(rt_sigpending)
|
|||||||
|
|
||||||
lock = &thread->sigcommon->lock;
|
lock = &thread->sigcommon->lock;
|
||||||
head = &thread->sigcommon->sigpending;
|
head = &thread->sigcommon->sigpending;
|
||||||
flag = ihk_mc_spinlock_lock(lock);
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
list_for_each_entry(pending, head, list){
|
list_for_each_entry(pending, head, list){
|
||||||
w |= pending->sigmask.__val[0];
|
w |= pending->sigmask.__val[0];
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
lock = &thread->sigpendinglock;
|
lock = &thread->sigpendinglock;
|
||||||
head = &thread->sigpending;
|
head = &thread->sigpending;
|
||||||
flag = ihk_mc_spinlock_lock(lock);
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
list_for_each_entry(pending, head, list){
|
list_for_each_entry(pending, head, list){
|
||||||
w |= pending->sigmask.__val[0];
|
w |= pending->sigmask.__val[0];
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
if(copy_to_user(set->__val, &w, sizeof w))
|
if(copy_to_user(set->__val, &w, sizeof w))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -3215,10 +3368,10 @@ SYSCALL_DECLARE(rt_sigtimedwait)
|
|||||||
__sigset_t wset;
|
__sigset_t wset;
|
||||||
__sigset_t nset;
|
__sigset_t nset;
|
||||||
struct timespec wtimeout;
|
struct timespec wtimeout;
|
||||||
unsigned long flag;
|
|
||||||
struct sig_pending *pending;
|
struct sig_pending *pending;
|
||||||
struct list_head *head;
|
struct list_head *head;
|
||||||
ihk_spinlock_t *lock;
|
mcs_rwlock_lock_t *lock;
|
||||||
|
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||||
int w;
|
int w;
|
||||||
int sig;
|
int sig;
|
||||||
struct timespec ats;
|
struct timespec ats;
|
||||||
@@ -3284,18 +3437,18 @@ SYSCALL_DECLARE(rt_sigtimedwait)
|
|||||||
|
|
||||||
lock = &thread->sigcommon->lock;
|
lock = &thread->sigcommon->lock;
|
||||||
head = &thread->sigcommon->sigpending;
|
head = &thread->sigcommon->sigpending;
|
||||||
flag = ihk_mc_spinlock_lock(lock);
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
list_for_each_entry(pending, head, list){
|
list_for_each_entry(pending, head, list){
|
||||||
if(pending->sigmask.__val[0] & wset)
|
if(pending->sigmask.__val[0] & wset)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(&pending->list == head){
|
if(&pending->list == head){
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
lock = &thread->sigpendinglock;
|
lock = &thread->sigpendinglock;
|
||||||
head = &thread->sigpending;
|
head = &thread->sigpending;
|
||||||
flag = ihk_mc_spinlock_lock(lock);
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
list_for_each_entry(pending, head, list){
|
list_for_each_entry(pending, head, list){
|
||||||
if(pending->sigmask.__val[0] & wset)
|
if(pending->sigmask.__val[0] & wset)
|
||||||
break;
|
break;
|
||||||
@@ -3305,25 +3458,25 @@ SYSCALL_DECLARE(rt_sigtimedwait)
|
|||||||
if(&pending->list != head){
|
if(&pending->list != head){
|
||||||
list_del(&pending->list);
|
list_del(&pending->list);
|
||||||
thread->sigmask.__val[0] = bset;
|
thread->sigmask.__val[0] = bset;
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
lock = &thread->sigcommon->lock;
|
lock = &thread->sigcommon->lock;
|
||||||
head = &thread->sigcommon->sigpending;
|
head = &thread->sigcommon->sigpending;
|
||||||
flag = ihk_mc_spinlock_lock(lock);
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
list_for_each_entry(pending, head, list){
|
list_for_each_entry(pending, head, list){
|
||||||
if(pending->sigmask.__val[0] & nset)
|
if(pending->sigmask.__val[0] & nset)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(&pending->list == head){
|
if(&pending->list == head){
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
lock = &thread->sigpendinglock;
|
lock = &thread->sigpendinglock;
|
||||||
head = &thread->sigpending;
|
head = &thread->sigpending;
|
||||||
flag = ihk_mc_spinlock_lock(lock);
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
list_for_each_entry(pending, head, list){
|
list_for_each_entry(pending, head, list){
|
||||||
if(pending->sigmask.__val[0] & nset)
|
if(pending->sigmask.__val[0] & nset)
|
||||||
break;
|
break;
|
||||||
@@ -3333,11 +3486,11 @@ SYSCALL_DECLARE(rt_sigtimedwait)
|
|||||||
if(&pending->list != head){
|
if(&pending->list != head){
|
||||||
list_del(&pending->list);
|
list_del(&pending->list);
|
||||||
thread->sigmask.__val[0] = bset;
|
thread->sigmask.__val[0] = bset;
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
do_signal(-EINTR, NULL, thread, pending, 0);
|
do_signal(-EINTR, NULL, thread, pending, 0);
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
thread->sigevent = 0;
|
thread->sigevent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3374,10 +3527,10 @@ do_sigsuspend(struct thread *thread, const sigset_t *set)
|
|||||||
{
|
{
|
||||||
__sigset_t wset;
|
__sigset_t wset;
|
||||||
__sigset_t bset;
|
__sigset_t bset;
|
||||||
unsigned long flag;
|
|
||||||
struct sig_pending *pending;
|
struct sig_pending *pending;
|
||||||
struct list_head *head;
|
struct list_head *head;
|
||||||
ihk_spinlock_t *lock;
|
mcs_rwlock_lock_t *lock;
|
||||||
|
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||||
|
|
||||||
wset = set->__val[0];
|
wset = set->__val[0];
|
||||||
wset &= ~__sigmask(SIGKILL);
|
wset &= ~__sigmask(SIGKILL);
|
||||||
@@ -3392,31 +3545,31 @@ do_sigsuspend(struct thread *thread, const sigset_t *set)
|
|||||||
|
|
||||||
lock = &thread->sigcommon->lock;
|
lock = &thread->sigcommon->lock;
|
||||||
head = &thread->sigcommon->sigpending;
|
head = &thread->sigcommon->sigpending;
|
||||||
flag = ihk_mc_spinlock_lock(lock);
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
list_for_each_entry(pending, head, list){
|
list_for_each_entry(pending, head, list){
|
||||||
if(!(pending->sigmask.__val[0] & wset))
|
if(!(pending->sigmask.__val[0] & wset))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(&pending->list == head){
|
if(&pending->list == head){
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
|
|
||||||
lock = &thread->sigpendinglock;
|
lock = &thread->sigpendinglock;
|
||||||
head = &thread->sigpending;
|
head = &thread->sigpending;
|
||||||
flag = ihk_mc_spinlock_lock(lock);
|
mcs_rwlock_writer_lock(lock, &mcs_rw_node);
|
||||||
list_for_each_entry(pending, head, list){
|
list_for_each_entry(pending, head, list){
|
||||||
if(!(pending->sigmask.__val[0] & wset))
|
if(!(pending->sigmask.__val[0] & wset))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(&pending->list == head){
|
if(&pending->list == head){
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
thread->sigevent = 0;
|
thread->sigevent = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_del(&pending->list);
|
list_del(&pending->list);
|
||||||
ihk_mc_spinlock_unlock(lock, flag);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
thread->sigmask.__val[0] = bset;
|
thread->sigmask.__val[0] = bset;
|
||||||
do_signal(-EINTR, NULL, thread, pending, 0);
|
do_signal(-EINTR, NULL, thread, pending, 0);
|
||||||
break;
|
break;
|
||||||
@@ -5183,29 +5336,37 @@ static int ptrace_attach(int pid)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
child = thread->proc;
|
child = thread->proc;
|
||||||
dkprintf("ptrace_attach,pid=%d,thread->proc->parent=%p\n", thread->proc->pid, thread->proc->parent);
|
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);
|
||||||
|
|
||||||
mcs_rwlock_writer_lock_noirq(&child->update_lock, &updatelock);
|
mcs_rwlock_writer_lock_noirq(&child->update_lock, &updatelock);
|
||||||
if (thread->proc->ptrace & PT_TRACED) {
|
|
||||||
mcs_rwlock_writer_unlock_noirq(&child->update_lock, &updatelock);
|
/* Only for the first thread of a process XXX: fix this */
|
||||||
thread_unlock(thread, &lock);
|
if (thread->tid == child->pid) {
|
||||||
error = -EPERM;
|
if (thread->proc->ptrace & PT_TRACED) {
|
||||||
goto out;
|
mcs_rwlock_writer_unlock_noirq(&child->update_lock, &updatelock);
|
||||||
|
thread_unlock(thread, &lock);
|
||||||
|
dkprintf("ptrace_attach: -EPERM\n");
|
||||||
|
error = -EPERM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parent = child->parent;
|
parent = child->parent;
|
||||||
|
/* XXX: tmp */
|
||||||
|
if (parent != proc) {
|
||||||
|
|
||||||
dkprintf("ptrace_attach,parent->pid=%d\n", parent->pid);
|
dkprintf("ptrace_attach() parent->pid=%d\n", parent->pid);
|
||||||
|
|
||||||
mcs_rwlock_writer_lock_noirq(&parent->children_lock, &childlock);
|
mcs_rwlock_writer_lock_noirq(&parent->children_lock, &childlock);
|
||||||
list_del(&child->siblings_list);
|
list_del(&child->siblings_list);
|
||||||
list_add_tail(&child->ptraced_siblings_list, &parent->ptraced_children_list);
|
list_add_tail(&child->ptraced_siblings_list, &parent->ptraced_children_list);
|
||||||
mcs_rwlock_writer_unlock_noirq(&parent->children_lock, &childlock);
|
mcs_rwlock_writer_unlock_noirq(&parent->children_lock, &childlock);
|
||||||
|
|
||||||
mcs_rwlock_writer_lock_noirq(&proc->children_lock, &childlock);
|
mcs_rwlock_writer_lock_noirq(&proc->children_lock, &childlock);
|
||||||
list_add_tail(&child->siblings_list, &proc->children_list);
|
list_add_tail(&child->siblings_list, &proc->children_list);
|
||||||
child->parent = proc;
|
child->parent = proc;
|
||||||
mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &childlock);
|
mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &childlock);
|
||||||
|
}
|
||||||
|
|
||||||
child->ptrace = PT_TRACED | PT_TRACE_EXEC;
|
child->ptrace = PT_TRACED | PT_TRACE_EXEC;
|
||||||
|
|
||||||
@@ -5227,7 +5388,7 @@ static int ptrace_attach(int pid)
|
|||||||
info.si_signo = SIGSTOP;
|
info.si_signo = SIGSTOP;
|
||||||
info.si_code = SI_USER;
|
info.si_code = SI_USER;
|
||||||
info._sifields._kill.si_pid = proc->pid;
|
info._sifields._kill.si_pid = proc->pid;
|
||||||
error = do_kill(mythread, pid, -1, SIGSTOP, &info, 2);
|
error = do_kill(mythread, -1, pid, SIGSTOP, &info, 2);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -5539,8 +5700,8 @@ SYSCALL_DECLARE(sched_setparam)
|
|||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
struct thread *thread = cpu_local_var(current);
|
struct thread *thread = cpu_local_var(current);
|
||||||
struct mcs_rwlock_node_irqsave lock;
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
|
|
||||||
struct syscall_request request1 IHK_DMA_ALIGN;
|
struct syscall_request request1 IHK_DMA_ALIGN;
|
||||||
|
int other_thread = 0;
|
||||||
|
|
||||||
dkprintf("sched_setparam: pid: %d, uparam: 0x%lx\n", pid, uparam);
|
dkprintf("sched_setparam: pid: %d, uparam: 0x%lx\n", pid, uparam);
|
||||||
|
|
||||||
@@ -5552,12 +5713,11 @@ SYSCALL_DECLARE(sched_setparam)
|
|||||||
pid = thread->proc->pid;
|
pid = thread->proc->pid;
|
||||||
|
|
||||||
if (thread->proc->pid != pid) {
|
if (thread->proc->pid != pid) {
|
||||||
|
other_thread = 1;
|
||||||
thread = find_thread(pid, pid, &lock);
|
thread = find_thread(pid, pid, &lock);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
}
|
}
|
||||||
// TODO: unlock 場所のチェック
|
|
||||||
// 何をしようとしているのか理解
|
|
||||||
thread_unlock(thread, &lock);
|
thread_unlock(thread, &lock);
|
||||||
|
|
||||||
/* Ask Linux about ownership.. */
|
/* Ask Linux about ownership.. */
|
||||||
@@ -5576,7 +5736,17 @@ SYSCALL_DECLARE(sched_setparam)
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return setscheduler(thread, thread->sched_policy, ¶m);
|
if (other_thread) {
|
||||||
|
thread = find_thread(pid, pid, &lock);
|
||||||
|
if (!thread) {
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retval = setscheduler(thread, thread->sched_policy, ¶m);
|
||||||
|
if (other_thread) {
|
||||||
|
thread_unlock(thread, &lock);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(sched_getparam)
|
SYSCALL_DECLARE(sched_getparam)
|
||||||
@@ -5856,7 +6026,7 @@ SYSCALL_DECLARE(sched_getaffinity)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dkprintf("%s() len: %d, mask: %p\n", __FUNCTION__, len, u_cpu_set);
|
dkprintf("%s() len: %d, mask: %p\n", __FUNCTION__, len, u_cpu_set);
|
||||||
if (!len)
|
if (!len || u_cpu_set == (cpu_set_t *)-1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if ((len * BITS_PER_BYTE) < __CPU_SETSIZE)
|
if ((len * BITS_PER_BYTE) < __CPU_SETSIZE)
|
||||||
@@ -6279,7 +6449,23 @@ SYSCALL_DECLARE(nanosleep)
|
|||||||
|
|
||||||
SYSCALL_DECLARE(sched_yield)
|
SYSCALL_DECLARE(sched_yield)
|
||||||
{
|
{
|
||||||
schedule();
|
struct cpu_local_var *v;
|
||||||
|
int do_schedule = 0;
|
||||||
|
long runq_irqstate;
|
||||||
|
|
||||||
|
runq_irqstate =
|
||||||
|
ihk_mc_spinlock_lock(&(get_this_cpu_local_var()->runq_lock));
|
||||||
|
v = get_this_cpu_local_var();
|
||||||
|
|
||||||
|
if (v->flags & CPU_FLAG_NEED_RESCHED || v->runq_len > 1) {
|
||||||
|
do_schedule = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ihk_mc_spinlock_unlock(&v->runq_lock, runq_irqstate);
|
||||||
|
|
||||||
|
if (do_schedule) {
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -7066,7 +7252,7 @@ SYSCALL_DECLARE(getcpu)
|
|||||||
const uintptr_t cpup = ihk_mc_syscall_arg0(ctx);
|
const uintptr_t cpup = ihk_mc_syscall_arg0(ctx);
|
||||||
const uintptr_t nodep = ihk_mc_syscall_arg1(ctx);
|
const uintptr_t nodep = ihk_mc_syscall_arg1(ctx);
|
||||||
const int cpu = ihk_mc_get_processor_id();
|
const int cpu = ihk_mc_get_processor_id();
|
||||||
const int node = 0;
|
const int node = ihk_mc_get_numa_id();
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (cpup) {
|
if (cpup) {
|
||||||
@@ -8224,6 +8410,9 @@ set_cputime(int mode)
|
|||||||
long syscall(int num, ihk_mc_user_context_t *ctx)
|
long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||||
{
|
{
|
||||||
long l;
|
long l;
|
||||||
|
#ifdef TRACK_SYSCALLS
|
||||||
|
uint64_t t_s;
|
||||||
|
#endif // TRACK_SYSCALLS
|
||||||
|
|
||||||
set_cputime(1);
|
set_cputime(1);
|
||||||
if(cpu_local_var(current)->proc->status == PS_EXITED &&
|
if(cpu_local_var(current)->proc->status == PS_EXITED &&
|
||||||
@@ -8265,6 +8454,9 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
|||||||
#endif
|
#endif
|
||||||
dkprintf("\n");
|
dkprintf("\n");
|
||||||
|
|
||||||
|
#ifdef TRACK_SYSCALLS
|
||||||
|
t_s = rdtsc();
|
||||||
|
#endif // TRACK_SYSCALLS
|
||||||
|
|
||||||
if ((0 <= num) && (num < (sizeof(syscall_table) / sizeof(syscall_table[0])))
|
if ((0 <= num) && (num < (sizeof(syscall_table) / sizeof(syscall_table[0])))
|
||||||
&& (syscall_table[num] != NULL)) {
|
&& (syscall_table[num] != NULL)) {
|
||||||
@@ -8281,8 +8473,31 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
|||||||
l = syscall_generic_forwarding(num, ctx);
|
l = syscall_generic_forwarding(num, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
check_signal(l, NULL, num);
|
if (num != __NR_sched_yield &&
|
||||||
check_need_resched();
|
num != __NR_futex) {
|
||||||
|
check_signal(l, NULL, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TRACK_SYSCALLS
|
||||||
|
if (num < 300) {
|
||||||
|
if (!cpu_local_var(current)->syscall_cnts) {
|
||||||
|
alloc_syscall_counters(cpu_local_var(current));
|
||||||
|
}
|
||||||
|
if (cpu_local_var(current)->socc_enabled) {
|
||||||
|
cpu_local_var(current)->syscall_times[num] += (rdtsc() - t_s);
|
||||||
|
cpu_local_var(current)->syscall_cnts[num]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (num != 701)
|
||||||
|
kprintf("syscall > 300?? : %d\n", num);
|
||||||
|
}
|
||||||
|
#endif // TRACK_SYSCALLS
|
||||||
|
|
||||||
|
if (num != __NR_sched_yield &&
|
||||||
|
num != __NR_futex) {
|
||||||
|
check_need_resched();
|
||||||
|
}
|
||||||
|
|
||||||
if (cpu_local_var(current)->proc->ptrace) {
|
if (cpu_local_var(current)->proc->ptrace) {
|
||||||
ptrace_syscall_exit(cpu_local_var(current));
|
ptrace_syscall_exit(cpu_local_var(current));
|
||||||
|
|||||||
Reference in New Issue
Block a user