From: James S. <jsi...@us...> - 2002-04-24 17:26:06
|
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. |