Commit a4defa90 authored by David S. Miller's avatar David S. Miller

Sparc64 updates for recent preemption fixes.

parent 60f062ea
...@@ -1436,7 +1436,9 @@ ret_from_syscall: ...@@ -1436,7 +1436,9 @@ ret_from_syscall:
* %o7 for us. Check performance counter stuff too. * %o7 for us. Check performance counter stuff too.
*/ */
andn %o7, _TIF_NEWCHILD, %l0 andn %o7, _TIF_NEWCHILD, %l0
#if CONFIG_SMP || CONFIG_PREEMPT
call schedule_tail call schedule_tail
#endif
stx %l0, [%g6 + TI_FLAGS] stx %l0, [%g6 + TI_FLAGS]
andcc %l0, _TIF_PERFCTR, %g0 andcc %l0, _TIF_PERFCTR, %g0
be,pt %icc, 1f be,pt %icc, 1f
......
...@@ -107,10 +107,8 @@ void kpreempt_maybe(void) ...@@ -107,10 +107,8 @@ void kpreempt_maybe(void)
if (local_irq_count(cpu) == 0 && if (local_irq_count(cpu) == 0 &&
local_bh_count(cpu) == 0 && local_bh_count(cpu) == 0 &&
test_thread_flag(TIF_NEED_RESCHED)) { test_thread_flag(TIF_NEED_RESCHED))
current->state = TASK_RUNNING;
schedule(); schedule();
}
} }
#endif #endif
......
...@@ -620,11 +620,10 @@ asmlinkage void syscall_trace(void) ...@@ -620,11 +620,10 @@ asmlinkage void syscall_trace(void)
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; return;
current->exit_code = SIGTRAP; current->exit_code = SIGTRAP;
preempt_disable();
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
preempt_enable();
/* /*
* this isn't the same as continuing with a signal, but it will do * this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the * for normal use. strace only continues with a signal if the
......
...@@ -274,12 +274,12 @@ to_kernel: ...@@ -274,12 +274,12 @@ to_kernel:
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
ldsw [%g6 + TI_PRE_COUNT], %l5 ldsw [%g6 + TI_PRE_COUNT], %l5
brnz %l5, kern_fpucheck brnz %l5, kern_fpucheck
add %l5, 1, %l6 sethi %hi(PREEMPT_ACTIVE), %l6
stw %l6, [%g6 + TI_PRE_COUNT] stw %l6, [%g6 + TI_PRE_COUNT]
call kpreempt_maybe call kpreempt_maybe
nop nop
ba,pt %xcc, rtrap ba,pt %xcc, rtrap
stw %l5, [%g6 + TI_PRE_COUNT] stw %g0, [%g6 + TI_PRE_COUNT]
#endif #endif
kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5 kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5
brz,pt %l5, rt_continue brz,pt %l5, rt_continue
......
...@@ -713,11 +713,9 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -713,11 +713,9 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
current->exit_code = signr; current->exit_code = signr;
preempt_disable();
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
preempt_enable();
if (!(signr = current->exit_code)) if (!(signr = current->exit_code))
continue; continue;
current->exit_code = 0; current->exit_code = 0;
...@@ -771,15 +769,13 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -771,15 +769,13 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGSTOP: { case SIGSTOP: {
struct signal_struct *sig; struct signal_struct *sig;
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->parent->sig; sig = current->parent->sig;
preempt_disable();
current->state = TASK_STOPPED;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
SA_NOCLDSTOP)) SA_NOCLDSTOP))
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
preempt_enable();
continue; continue;
} }
......
...@@ -1387,11 +1387,9 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1387,11 +1387,9 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
current->exit_code = signr; current->exit_code = signr;
preempt_disable();
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
preempt_enable();
if (!(signr = current->exit_code)) if (!(signr = current->exit_code))
continue; continue;
current->exit_code = 0; current->exit_code = 0;
...@@ -1445,15 +1443,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1445,15 +1443,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case SIGSTOP: { case SIGSTOP: {
struct signal_struct *sig; struct signal_struct *sig;
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->parent->sig; sig = current->parent->sig;
preempt_disable();
current->state = TASK_STOPPED;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
SA_NOCLDSTOP)) SA_NOCLDSTOP))
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
preempt_enable();
continue; continue;
} }
case SIGQUIT: case SIGILL: case SIGTRAP: case SIGQUIT: case SIGILL: case SIGTRAP:
......
...@@ -109,6 +109,8 @@ struct thread_info { ...@@ -109,6 +109,8 @@ struct thread_info {
#define THREAD_SHIFT PAGE_SHIFT #define THREAD_SHIFT PAGE_SHIFT
#endif /* PAGE_SHIFT == 13 */ #endif /* PAGE_SHIFT == 13 */
#define PREEMPT_ACTIVE 0x4000000
/* /*
* macros/functions for gaining access to the thread information structure * macros/functions for gaining access to the thread information structure
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment