Microstate accounting, IA64 support

From: Peter Chubb
Date: Thu Mar 10 2005 - 23:36:33 EST


Microstate Accounting:
Add suppoort for IA64.


linux-2.6-ustate/arch/ia64/Kconfig | 25 +++++++++++++++
linux-2.6-ustate/arch/ia64/kernel/entry.S | 44 +++++++++++++++++++++++++++
linux-2.6-ustate/arch/ia64/kernel/irq_ia64.c | 21 +++++++++++-
linux-2.6-ustate/arch/ia64/kernel/ivt.S | 8 +++-
linux-2.6-ustate/include/asm-ia64/msa.h | 33 ++++++++++++++++++++
linux-2.6-ustate/include/asm-ia64/unistd.h | 1
7 files changed, 129 insertions(+), 5 deletions(-)

Index: linux-2.6-ustate/arch/ia64/Kconfig
===================================================================
--- linux-2.6-ustate.orig/arch/ia64/Kconfig 2005-03-10 09:13:01.780632777 +1100
+++ linux-2.6-ustate/arch/ia64/Kconfig 2005-03-10 09:16:14.593655619 +1100
@@ -302,6 +302,31 @@
little bigger and slows down execution a bit, but it is generally
a good idea to turn this on. If you're unsure, say Y.

+config MICROSTATE
+ bool "Microstate accounting"
+ help
+ This option causes the kernel to keep very accurate track of
+ how long your threads spend on the runqueues, running, or asleep or
+ stopped. It will slow down your kernel.
+ Times are reported in /proc/pid/msa and through a new msa()
+ system call.
+choice
+ depends on MICROSTATE
+ prompt "Microstate timing source"
+ default MICROSTATE_ITC
+ help
+ On IA64 one can use two timeing sources for the microstate
+ accounting; the on-chip interval counter, or Linux's
+ time-of-day clock. The first is very cheap; the other is
+ more accurate on SMP systems.
+
+config MICROSTATE_ITC
+ bool "Use on-chip ITC for microstate timing"
+
+config MICROSTATE_TOD
+ bool "Use time-of-day clock for microstate timings"
+endchoice
+
config IA64_PALINFO
tristate "/proc/pal support"
help
Index: linux-2.6-ustate/include/asm-ia64/msa.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-ustate/include/asm-ia64/msa.h 2005-03-10 09:16:14.594632174 +1100
@@ -0,0 +1,33 @@
+/************************************************************************
+ * asm-ia64/msa.h
+ *
+ * Provide an architecture-specific clock.
+ */
+
+#ifndef _ASM_IA64_MSA_H
+#define _ASM_IA64_MSA_H
+
+#include <asm/processor.h>
+#include <asm/timex.h>
+#include <asm/smp.h>
+
+
+# if defined(CONFIG_MICROSTATE_ITC)
+# define MSA_NOW(now) do { now = (clk_t)get_cycles(); } while (0)
+
+# define MSA_TO_NSEC(clk) ((1000000000*clk) / cpu_data(smp_processor_id())->itc_freq)
+
+# elif defined(CONFIG_MICROSTATE_TOD)
+static inline void msa_now(clk_t *nsp) {
+ struct timeval tv;
+ do_gettimeofday(&tv);
+ *nsp = tv.tv_sec * 1000000 + tv.tv_usec;
+}
+# define MSA_NOW(x) msa_now(&x)
+# define MSA_TO_NSEC(clk) ((clk) * 1000)
+
+# else
+# include <asm-generic/msa.h>
+# endif
+
+#endif /* _ASM_IA64_MSA_H */
Microstate Accounting: Track time in system calls for IA64

arch/ia64/kernel/entry.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
arch/ia64/kernel/ivt.S | 8 ++++++--
2 files changed, 50 insertions(+), 2 deletions(-)

Index: linux-2.6-ustate/arch/ia64/kernel/entry.S
===================================================================
--- linux-2.6-ustate.orig/arch/ia64/kernel/entry.S 2005-03-10 09:13:01.149778160 +1100
+++ linux-2.6-ustate/arch/ia64/kernel/entry.S 2005-03-10 09:16:15.157128068 +1100
@@ -589,6 +589,46 @@
.ret4: br.cond.sptk ia64_leave_kernel
END(ia64_strace_leave_kernel)

+#ifdef CONFIG_MICROSTATE
+/*
+ * preserve input registers,
+ * and r8
+ */
+GLOBAL_ENTRY(invoke_msa_end_syscall)
+ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
+ alloc loc1=ar.pfs,8,4,0,0
+ mov loc0=rp
+ .body
+ ;;
+ mov loc2=ret0
+ mov loc3=ret2
+ br.call.sptk.many rp=msa_end_syscall
+1: mov rp=loc0
+ mov ret0=loc2
+ mov ret2=loc3
+ mov ar.pfs=loc1
+ br.ret.sptk.many rp
+END(invoke_msa_end_syscall)
+/*
+ * Preserves in0-7, and all callee-save registers.
+ */
+GLOBAL_ENTRY(invoke_msa_start_syscall)
+ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
+ alloc loc1=ar.pfs,8,4,0,0
+ mov loc0=rp
+ .body
+ mov loc2=r3
+ mov loc3=r15
+ ;;
+ br.call.sptk.many rp=msa_start_syscall
+1: mov r15=loc3
+ mov r3=loc2
+ mov ar.pfs=loc1
+ mov rp=loc0
+ br.ret.sptk.many rp
+END(invoke_msa_start_syscall)
+#endif /* CONFIG_MICROSTATE */
+
GLOBAL_ENTRY(ia64_ret_from_clone)
PT_REGS_UNWIND_INFO(0)
{ /*
@@ -671,6 +711,10 @@
*/
ENTRY(ia64_leave_syscall)
PT_REGS_UNWIND_INFO(0)
+#ifdef CONFIG_MICROSTATE
+ br.call.sptk.many rp=invoke_msa_end_syscall
+1:
+#endif
/*
* work.need_resched etc. mustn't get changed by this CPU before it returns to
* user- or fsys-mode, hence we disable interrupts early on.
Index: linux-2.6-ustate/arch/ia64/kernel/ivt.S
===================================================================
--- linux-2.6-ustate.orig/arch/ia64/kernel/ivt.S 2005-03-10 09:13:01.150754715 +1100
+++ linux-2.6-ustate/arch/ia64/kernel/ivt.S 2005-03-10 09:16:15.159081178 +1100
@@ -739,8 +739,12 @@
// p10==true means out registers are more than 8 or r15's Nat is true
(p10) br.cond.spnt.many ia64_ret_from_syscall
;;
- movl r16=sys_call_table
-
+#ifdef CONFIG_MICROSTATE
+ // at this point, providing we preserve in0-7, r3, r15
+ // we're OK.
+ br.call.sptk.many rp=invoke_msa_start_syscall
+#endif /* CONFIG_MICROSTATE */
+1: movl r16=sys_call_table
adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024
movl r2=ia64_ret_from_syscall
;;
Microstate accounting: Hook in the msa system call for IA64.

arch/ia64/kernel/entry.S | 2 +-
include/asm-ia64/unistd.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)

Index: linux-2.6-ustate/include/asm-ia64/unistd.h
===================================================================
--- linux-2.6-ustate.orig/include/asm-ia64/unistd.h 2005-03-10 09:13:00.452517795 +1100
+++ linux-2.6-ustate/include/asm-ia64/unistd.h 2005-03-10 09:16:15.738178513 +1100
@@ -263,6 +263,7 @@
#define __NR_add_key 1271
#define __NR_request_key 1272
#define __NR_keyctl 1273
+#define __NR_msa 1274

#ifdef __KERNEL__

Index: linux-2.6-ustate/arch/ia64/kernel/entry.S
===================================================================
--- linux-2.6-ustate.orig/arch/ia64/kernel/entry.S 2005-03-10 09:16:15.157128068 +1100
+++ linux-2.6-ustate/arch/ia64/kernel/entry.S 2005-03-10 09:16:15.740131624 +1100
@@ -1621,7 +1621,7 @@
data8 sys_add_key
data8 sys_request_key
data8 sys_keyctl
- data8 sys_ni_syscall
+ data8 sys_msa
data8 sys_ni_syscall // 1275
data8 sys_ni_syscall
data8 sys_ni_syscall
Microstate accounting: Account for time in Interrupt handlers, IA64 code.

arch/ia64/kernel/irq_ia64.c | 21 +++++++++++++++++++--
1 files changed, 19 insertions(+), 2 deletions(-)

Index: linux-2.6-ustate/arch/ia64/kernel/irq_ia64.c
===================================================================
--- linux-2.6-ustate.orig/arch/ia64/kernel/irq_ia64.c 2005-03-10 09:12:59.798225857 +1100
+++ linux-2.6-ustate/arch/ia64/kernel/irq_ia64.c 2005-03-10 09:16:16.304580629 +1100
@@ -104,7 +104,7 @@
ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
{
unsigned long saved_tpr;
-
+ ia64_vector oldvector;
#if IRQ_DEBUG
{
unsigned long bsp, sp;
@@ -143,6 +143,9 @@
irq_enter();
saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
ia64_srlz_d();
+
+ msa_start_irq(local_vector_to_irq(vector));
+
while (vector != IA64_SPURIOUS_INT_VECTOR) {
if (!IS_RESCHEDULE(vector)) {
ia64_setreg(_IA64_REG_CR_TPR, vector);
@@ -157,14 +160,28 @@
ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
}
ia64_eoi();
- vector = ia64_get_ivr();
+ oldvector = vector;
+ vector = ia64_get_ivr();
+ msa_continue_irq(local_vector_to_irq(oldvector),
+ local_vector_to_irq(vector));
}
+
+
/*
* This must be done *after* the ia64_eoi(). For example, the keyboard softirq
* handler needs to be able to wait for further keyboard interrupts, which can't
* come through until ia64_eoi() has been done.
*/
irq_exit();
+
+ /*
+ * This should really be done after the irq_exit, but if new
+ * interrupts come in while running the softIRQs, the
+ * microstate accounting system loses track of what
+ * state it's meant to return to.
+ */
+ msa_finish_irq(local_vector_to_irq(vector));
+
}

#ifdef CONFIG_HOTPLUG_CPU
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/