patch-2.1.127 linux/arch/sparc64/kernel/process.c
Next file: linux/arch/sparc64/kernel/psycho.c
Previous file: linux/arch/sparc64/kernel/irq.c
Back to the patch index
Back to the overall index
- Lines: 106
- Date:
Tue Oct 27 09:52:20 1998
- Orig file:
v2.1.126/linux/arch/sparc64/kernel/process.c
- Orig date:
Mon Oct 5 13:13:38 1998
diff -u --recursive --new-file v2.1.126/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.75 1998/09/23 02:05:15 davem Exp $
+/* $Id: process.c,v 1.82 1998/10/19 21:52:23 davem Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -71,13 +71,16 @@
{
current->priority = 0;
while(1) {
+ struct task_struct *p;
+
check_pgt_cache();
run_task_queue(&tq_scheduler);
- barrier();
current->counter = 0;
- if(current->need_resched)
+ if (current->need_resched != 0 ||
+ ((p = init_task.next_run) != NULL &&
+ (p->processor == smp_processor_id() ||
+ (p->tss.flags & SPARC_FLAG_NEWCHILD) != 0)))
schedule();
- barrier();
}
}
@@ -386,12 +389,32 @@
else
current->tss.utraps[0]--;
}
+
+ /* Turn off performance counters if on. */
+ if (current->tss.flags & SPARC_FLAG_PERFCTR) {
+ current->tss.user_cntd0 =
+ current->tss.user_cntd1 = NULL;
+ current->tss.pcr_reg = 0;
+ current->tss.flags &= ~(SPARC_FLAG_PERFCTR);
+ write_pcr(0);
+ }
}
void flush_thread(void)
{
+ if (!(current->tss.flags & SPARC_FLAG_KTHREAD))
+ flush_user_windows();
current->tss.w_saved = 0;
+ /* Turn off performance counters if on. */
+ if (current->tss.flags & SPARC_FLAG_PERFCTR) {
+ current->tss.user_cntd0 =
+ current->tss.user_cntd1 = NULL;
+ current->tss.pcr_reg = 0;
+ current->tss.flags &= ~(SPARC_FLAG_PERFCTR);
+ write_pcr(0);
+ }
+
/* No new signal delivery by default. */
current->tss.new_signal = 0;
current->tss.fpsaved[0] = 0;
@@ -399,18 +422,14 @@
/* Now, this task is no longer a kernel thread. */
current->tss.current_ds = USER_DS;
if(current->tss.flags & SPARC_FLAG_KTHREAD) {
- extern spinlock_t scheduler_lock;
-
current->tss.flags &= ~SPARC_FLAG_KTHREAD;
/* exec_mmap() set context to NO_CONTEXT, here is
* where we grab a new one.
*/
- spin_lock(&scheduler_lock);
current->mm->cpu_vm_mask = 0;
activate_context(current);
current->mm->cpu_vm_mask = (1UL<<smp_processor_id());
- spin_unlock(&scheduler_lock);
}
if (current->tss.flags & SPARC_FLAG_32BIT)
__asm__ __volatile__("stxa %%g0, [%0] %1"
@@ -524,7 +543,6 @@
current->tss.w_saved = 0;
return;
barf:
- lock_kernel();
do_exit(SIGILL);
}
@@ -552,7 +570,19 @@
p->tss.kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct reg_window));
p->tss.cwp = (regs->tstate + 1) & TSTATE_CWP;
p->tss.fpsaved[0] = 0;
+ p->mm->segments = (void *) 0;
if(regs->tstate & TSTATE_PRIV) {
+ /* Special case, if we are spawning a kernel thread from
+ * a userspace task (via KMOD, NFS, or similar) we must
+ * disable performance counters in the child because the
+ * address space and protection realm are changing.
+ */
+ if (current->tss.flags & SPARC_FLAG_PERFCTR) {
+ p->tss.user_cntd0 =
+ p->tss.user_cntd1 = NULL;
+ p->tss.pcr_reg = 0;
+ p->tss.flags &= ~(SPARC_FLAG_PERFCTR);
+ }
p->tss.kregs->u_regs[UREG_FP] = p->tss.ksp;
p->tss.flags |= (SPARC_FLAG_KTHREAD | SPARC_FLAG_NEWCHILD);
p->tss.current_ds = KERNEL_DS;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov