patch-2.1.51 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: 160
- Date:
Sat Aug 16 10:00:14 1997
- Orig file:
v2.1.50/linux/arch/sparc64/kernel/process.c
- Orig date:
Mon Aug 4 16:25:37 1997
diff -u --recursive --new-file v2.1.50/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.31 1997/07/24 12:15:05 davem Exp $
+/* $Id: process.c,v 1.29 1997/07/17 02:20:40 davem Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -27,18 +27,21 @@
#include <linux/a.out.h>
#include <linux/config.h>
#include <linux/reboot.h>
+#include <linux/delay.h>
#include <asm/oplib.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/delay.h>
#include <asm/processor.h>
#include <asm/pstate.h>
#include <asm/elf.h>
#include <asm/fpumacro.h>
+#define PGTCACHE_HIGH_WATER 50
+#define PGTCACHE_LOW_WATER 25
+
#ifndef __SMP__
/*
@@ -53,6 +56,16 @@
current->priority = -100;
current->counter = -100;
for (;;) {
+ if(pgtable_cache_size > PGTCACHE_LOW_WATER) {
+ do {
+ if(pgd_quicklist)
+ free_page((unsigned long) get_pgd_fast());
+ if(pmd_quicklist)
+ free_page((unsigned long) get_pmd_fast());
+ if(pte_quicklist)
+ free_page((unsigned long) get_pte_fast());
+ } while(pgtable_cache_size > PGTCACHE_HIGH_WATER);
+ }
run_task_queue(&tq_scheduler);
schedule();
}
@@ -68,13 +81,26 @@
{
current->priority = -100;
while(1) {
+ if(pgtable_cache_size > PGTCACHE_LOW_WATER) {
+ do {
+ if(pgd_quicklist)
+ free_page((unsigned long) get_pgd_fast());
+ if(pmd_quicklist)
+ free_page((unsigned long) get_pmd_fast());
+ if(pte_quicklist)
+ free_page((unsigned long) get_pte_fast());
+ } while(pgtable_cache_size > PGTCACHE_HIGH_WATER);
+ }
if(tq_scheduler) {
lock_kernel();
run_task_queue(&tq_scheduler);
unlock_kernel();
}
+ barrier();
current->counter = -100;
- schedule();
+ if(resched_needed())
+ schedule();
+ barrier();
}
}
@@ -251,8 +277,20 @@
} while ((size -= sizeof(unsigned)));
}
-void show_regs(struct pt_regs * regs)
+#ifdef __SMP__
+static spinlock_t regdump_lock = SPIN_LOCK_UNLOCKED;
+#endif
+
+void __show_regs(struct pt_regs * regs)
{
+#ifdef __SMP__
+ unsigned long flags;
+
+ spin_lock_irqsave(®dump_lock, flags);
+ printk("CPU[%d]: local_irq_count[%ld] global_irq_count[%d]\n",
+ smp_processor_id(), local_irq_count,
+ atomic_read(&global_irq_count));
+#endif
printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x\n", regs->tstate,
regs->tpc, regs->tnpc, regs->y);
printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
@@ -268,6 +306,21 @@
regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
regs->u_regs[15]);
show_regwindow(regs);
+#ifdef __SMP__
+ spin_unlock_irqrestore(®dump_lock, flags);
+#endif
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ __show_regs(regs);
+#ifdef __SMP__
+ {
+ extern void smp_report_regs(void);
+
+ smp_report_regs();
+ }
+#endif
}
void show_regs32(struct pt_regs32 *regs)
@@ -337,12 +390,16 @@
/* 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);
get_mmu_context(current);
+ spin_unlock(&scheduler_lock);
}
current->tss.ctx = current->mm->context & 0x1fff;
spitfire_set_secondary_context (current->tss.ctx);
@@ -437,10 +494,14 @@
struct reg_window *rwin = &tp->reg_window[window];
if(copy_to_user((char *)sp, rwin, winsize))
- do_exit(SIGILL);
+ goto barf;
} while(window--);
}
current->tss.w_saved = 0;
+ return;
+barf:
+ lock_kernel();
+ do_exit(SIGILL);
}
/* Copy a Sparc thread. The fork() return value conventions
@@ -483,7 +544,7 @@
p->tss.kpc = ((unsigned long) ret_from_syscall) - 0x8;
#endif
p->tss.kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct reg_window));
- p->tss.cwp = regs->u_regs[UREG_G0];
+ p->tss.cwp = (regs->tstate + 1) & TSTATE_CWP;
if(regs->tstate & TSTATE_PRIV) {
p->tss.kregs->u_regs[UREG_FP] = p->tss.ksp;
p->tss.flags |= SPARC_FLAG_KTHREAD;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov