Update of /cvsroot/linux-mips/linux/arch/mips64/kernel
In directory usw-pr-cvs1:/tmp/cvs-serv14748a/arch/mips64/kernel
Modified Files:
time.c
Log Message:
64-bit time fixes to make time.c match the 32-bit version.
Index: time.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips64/kernel/time.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- time.c 2 Jan 2002 19:13:41 -0000 1.1
+++ time.c 24 Apr 2002 17:26:02 -0000 1.2
@@ -39,6 +39,11 @@
extern volatile unsigned long wall_jiffies;
/*
+ * whether we emulate local_timer_interrupts for SMP machines.
+ */
+int emulate_local_timer_interrupt;
+
+/*
* By default we provide the null RTC ops
*/
static unsigned long null_rtc_get_time(void)
@@ -283,6 +288,42 @@
/*
+ * local_timer_interrupt() does profiling and process accounting
+ * on a per-CPU basis.
+ *
+ * In UP mode, it is invoked from the (global) timer_interrupt.
+ *
+ * In SMP mode, it might invoked by per-CPU timer interrupt, or
+ * a broadcasted inter-processor interrupt which itself is triggered
+ * by the global timer interrupt.
+ */
+void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ if(!user_mode(regs)) {
+ if (prof_buffer && current->pid) {
+ extern int _stext;
+ unsigned long pc = regs->cp0_epc;
+
+ pc -= (unsigned long) &_stext;
+ pc >>= prof_shift;
+ /*
+ * Dont ignore out-of-bounds pc values silently,
+ * put them into the last histogram slot, so if
+ * present, they will show up as a sharp peak.
+ */
+ if (pc > prof_len-1)
+ pc = prof_len-1;
+ atomic_inc((atomic_t *)&prof_buffer[pc]);
+ }
+ }
+
+#if defined(CONFIG_SMP)
+ /* in UP mode, update_process_times() is invoked by do_timer() */
+ update_process_times(user_mode(regs));
+#endif
+}
+
+/*
* high-level timer interrupt service routines. This function
* is set as irqaction->handler and is invoked through do_IRQ.
*/
@@ -309,24 +350,6 @@
}
- if(!user_mode(regs)) {
- if (prof_buffer && current->pid) {
- extern int _stext;
- unsigned long pc = regs->cp0_epc;
-
- pc -= (unsigned long) &_stext;
- pc >>= prof_shift;
- /*
- * Dont ignore out-of-bounds pc values silently,
- * put them into the last histogram slot, so if
- * present, they will show up as a sharp peak.
- */
- if (pc > prof_len-1)
- pc = prof_len-1;
- atomic_inc((atomic_t *)&prof_buffer[pc]);
- }
- }
-
/*
* call the generic timer interrupt handling
*/
@@ -359,6 +382,31 @@
if (!jiffies) {
timerhi = timerlo = 0;
}
+
+#if !defined(CONFIG_SMP)
+ /*
+ * In UP mode, we call local_timer_interrupt() to do profiling
+ * and process accouting.
+ *
+ * In SMP mode, local_timer_interrupt() is invoked by appropriate
+ * low-level local timer interrupt handler.
+ */
+ local_timer_interrupt(0, NULL, regs);
+
+#else /* CONFIG_SMP */
+
+ if (emulate_local_timer_interrupt) {
+ /*
+ * this is the place where we send out inter-process
+ * interrupts and let each CPU do its own profiling
+ * and process accouting.
+ *
+ * Obviously we need to call local_timer_interrupt() for
+ * the current CPU too.
+ */
+ panic("Not implemented yet!!!");
+ }
+#endif /* CONFIG_SMP */
}
asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)
@@ -377,6 +425,21 @@
do_softirq();
}
+asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+
+ irq_enter(cpu, irq);
+ kstat.irqs[cpu][irq]++;
+
+ /* we keep interrupt disabled all the time */
+ local_timer_interrupt(irq, NULL, regs);
+
+ irq_exit(cpu, irq);
+
+ if (softirq_pending(cpu))
+ do_softirq();
+}
/*
* time_init() - it does the following things.
|