wait: Delay wake-up parent within switch context
Fujitsu: POSTK_DEBUG_TEMP_FIX_41 Refs: #1006 Change-Id: Ia98e896505ad0f6549766604ade84550eee8bd2d
This commit is contained in:
committed by
Masamichi Takagi
parent
0fdeb254b3
commit
f57b0c5d4f
@ -1306,9 +1306,7 @@ struct thread *arch_switch_context(struct thread *prev, struct thread *next)
|
||||
extern void perf_start(struct mc_perf_event *event);
|
||||
extern void perf_reset(struct mc_perf_event *event);
|
||||
struct thread *last;
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_41 */
|
||||
|
||||
/* Set up new TLS.. */
|
||||
dkprintf("[%d] arch_switch_context: tlsblock_base: 0x%lX\n",
|
||||
@ -1328,7 +1326,6 @@ struct thread *arch_switch_context(struct thread *prev, struct thread *next)
|
||||
if (likely(prev)) {
|
||||
tls_thread_switch(prev, next);
|
||||
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
|
||||
mcs_rwlock_writer_lock(&prev->proc->update_lock, &lock);
|
||||
if (prev->proc->status & (PS_DELAY_STOPPED | PS_DELAY_TRACED)) {
|
||||
switch (prev->proc->status) {
|
||||
@ -1342,11 +1339,12 @@ struct thread *arch_switch_context(struct thread *prev, struct thread *next)
|
||||
break;
|
||||
}
|
||||
mcs_rwlock_writer_unlock(&prev->proc->update_lock, &lock);
|
||||
|
||||
/* Wake up the parent who tried wait4 and sleeping */
|
||||
waitq_wakeup(&prev->proc->parent->waitpid_q);
|
||||
} else {
|
||||
mcs_rwlock_writer_unlock(&prev->proc->update_lock, &lock);
|
||||
}
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_41 */
|
||||
|
||||
last = ihk_mc_switch_context(&prev->ctx, &next->ctx, prev);
|
||||
}
|
||||
|
||||
@ -957,11 +957,7 @@ void ptrace_report_signal(struct thread *thread, int sig)
|
||||
}
|
||||
thread->exit_status = sig;
|
||||
/* Transition thread state */
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
|
||||
proc->status = PS_DELAY_TRACED;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_41 */
|
||||
proc->status = PS_TRACED;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_41 */
|
||||
thread->status = PS_TRACED;
|
||||
proc->ptrace &= ~PT_TRACE_SYSCALL;
|
||||
if (sig == SIGSTOP || sig == SIGTSTP ||
|
||||
@ -980,10 +976,6 @@ void ptrace_report_signal(struct thread *thread, int sig)
|
||||
info._sifields._sigchld.si_pid = thread->tid;
|
||||
info._sifields._sigchld.si_status = thread->exit_status;
|
||||
do_kill(cpu_local_var(current), parent_pid, -1, SIGCHLD, &info, 0);
|
||||
#ifndef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
|
||||
/* Wake parent (if sleeping in wait4()) */
|
||||
waitq_wakeup(&proc->parent->waitpid_q);
|
||||
#endif /* !POSTK_DEBUG_TEMP_FIX_41 */
|
||||
|
||||
dkprintf("ptrace_report_signal,sleeping\n");
|
||||
/* Sleep */
|
||||
|
||||
@ -1176,19 +1176,10 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
||||
/* Reap and set new signal_flags */
|
||||
proc->signal_flags = SIGNAL_STOP_STOPPED;
|
||||
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
|
||||
proc->status = PS_DELAY_STOPPED;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_41 */
|
||||
proc->status = PS_STOPPED;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_41 */
|
||||
thread->status = PS_STOPPED;
|
||||
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
||||
|
||||
#ifndef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
|
||||
/* Wake up the parent who tried wait4 and sleeping */
|
||||
waitq_wakeup(&proc->parent->waitpid_q);
|
||||
#endif /* !POSTK_DEBUG_TEMP_FIX_41 */
|
||||
|
||||
dkprintf("do_signal(): pid: %d, tid: %d SIGSTOP, sleeping\n",
|
||||
proc->pid, thread->tid);
|
||||
/* Sleep */
|
||||
@ -1205,19 +1196,10 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
||||
/* Update thread state in fork tree */
|
||||
mcs_rwlock_writer_lock(&proc->update_lock, &lock);
|
||||
thread->exit_status = SIGTRAP;
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
|
||||
proc->status = PS_DELAY_TRACED;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_41 */
|
||||
proc->status = PS_TRACED;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_41 */
|
||||
thread->status = PS_TRACED;
|
||||
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
||||
|
||||
#ifndef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
|
||||
/* Wake up the parent who tried wait4 and sleeping */
|
||||
waitq_wakeup(&thread->proc->parent->waitpid_q);
|
||||
#endif /* !POSTK_DEBUG_TEMP_FIX_41 */
|
||||
|
||||
/* Sleep */
|
||||
dkprintf("do_signal,SIGTRAP,sleeping\n");
|
||||
|
||||
|
||||
@ -1647,6 +1647,7 @@ int ihk_mc_interrupt_cpu(int cpu, int vector)
|
||||
struct thread *arch_switch_context(struct thread *prev, struct thread *next)
|
||||
{
|
||||
struct thread *last;
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
|
||||
dkprintf("[%d] schedule: tlsblock_base: 0x%lX\n",
|
||||
ihk_mc_get_processor_id(), next->tlsblock_base);
|
||||
@ -1677,6 +1678,28 @@ struct thread *arch_switch_context(struct thread *prev, struct thread *next)
|
||||
#endif
|
||||
|
||||
if (prev) {
|
||||
mcs_rwlock_writer_lock(&prev->proc->update_lock, &lock);
|
||||
if (prev->proc->status & (PS_DELAY_STOPPED | PS_DELAY_TRACED)) {
|
||||
switch (prev->proc->status) {
|
||||
case PS_DELAY_STOPPED:
|
||||
prev->proc->status = PS_STOPPED;
|
||||
break;
|
||||
case PS_DELAY_TRACED:
|
||||
prev->proc->status = PS_TRACED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mcs_rwlock_writer_unlock(&prev->proc->update_lock,
|
||||
&lock);
|
||||
|
||||
/* Wake up the parent who tried wait4 and sleeping */
|
||||
waitq_wakeup(&prev->proc->parent->waitpid_q);
|
||||
} else {
|
||||
mcs_rwlock_writer_unlock(&prev->proc->update_lock,
|
||||
&lock);
|
||||
}
|
||||
|
||||
last = ihk_mc_switch_context(&prev->ctx, &next->ctx, prev);
|
||||
}
|
||||
else {
|
||||
|
||||
@ -534,7 +534,7 @@ void ptrace_report_signal(struct thread *thread, int sig)
|
||||
}
|
||||
thread->exit_status = sig;
|
||||
/* Transition thread state */
|
||||
proc->status = PS_TRACED;
|
||||
proc->status = PS_DELAY_TRACED;
|
||||
thread->status = PS_TRACED;
|
||||
proc->ptrace &= ~PT_TRACE_SYSCALL;
|
||||
if (sig == SIGSTOP || sig == SIGTSTP ||
|
||||
@ -553,8 +553,6 @@ void ptrace_report_signal(struct thread *thread, int sig)
|
||||
info._sifields._sigchld.si_pid = thread->tid;
|
||||
info._sifields._sigchld.si_status = thread->exit_status;
|
||||
do_kill(cpu_local_var(current), parent_pid, -1, SIGCHLD, &info, 0);
|
||||
/* Wake parent (if sleeping in wait4()) */
|
||||
waitq_wakeup(&proc->parent->waitpid_q);
|
||||
|
||||
dkprintf("ptrace_report_signal,sleeping\n");
|
||||
/* Sleep */
|
||||
@ -864,13 +862,10 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
||||
/* Reap and set new signal_flags */
|
||||
proc->signal_flags = SIGNAL_STOP_STOPPED;
|
||||
|
||||
proc->status = PS_STOPPED;
|
||||
proc->status = PS_DELAY_STOPPED;
|
||||
thread->status = PS_STOPPED;
|
||||
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
||||
|
||||
/* Wake up the parent who tried wait4 and sleeping */
|
||||
waitq_wakeup(&proc->parent->waitpid_q);
|
||||
|
||||
dkprintf("do_signal(): pid: %d, tid: %d SIGSTOP, sleeping\n",
|
||||
proc->pid, thread->tid);
|
||||
/* Sleep */
|
||||
@ -887,13 +882,10 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
||||
/* Update thread state in fork tree */
|
||||
mcs_rwlock_writer_lock(&proc->update_lock, &lock);
|
||||
thread->exit_status = SIGTRAP;
|
||||
proc->status = PS_TRACED;
|
||||
proc->status = PS_DELAY_TRACED;
|
||||
thread->status = PS_TRACED;
|
||||
mcs_rwlock_writer_unlock(&proc->update_lock, &lock);
|
||||
|
||||
/* Wake up the parent who tried wait4 and sleeping */
|
||||
waitq_wakeup(&thread->proc->parent->waitpid_q);
|
||||
|
||||
/* Sleep */
|
||||
dkprintf("do_signal,SIGTRAP,sleeping\n");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user