diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index 31e13380758..7bd6694a343 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -84,28 +84,6 @@ dummy_perf(unsigned long vector, struct trapframe *tf) void (*perf_irq)(unsigned long, struct trapframe *) = dummy_perf; -static unsigned int ints[MAXCPU]; -SYSCTL_OPAQUE(_debug, OID_AUTO, ints, CTLFLAG_RW, &ints, sizeof(ints), "IU", - ""); - -static unsigned int clks[MAXCPU]; -#ifdef SMP -SYSCTL_OPAQUE(_debug, OID_AUTO, clks, CTLFLAG_RW, &clks, sizeof(clks), "IU", - ""); -#else -SYSCTL_INT(_debug, OID_AUTO, clks, CTLFLAG_RW, clks, 0, ""); -#endif - -#ifdef SMP -static unsigned int asts[MAXCPU]; -SYSCTL_OPAQUE(_debug, OID_AUTO, asts, CTLFLAG_RW, &asts, sizeof(asts), "IU", - ""); - -static unsigned int rdvs[MAXCPU]; -SYSCTL_OPAQUE(_debug, OID_AUTO, rdvs, CTLFLAG_RW, &rdvs, sizeof(rdvs), "IU", - ""); -#endif - SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics"); static int adjust_edges = 0; @@ -139,6 +117,8 @@ interrupt(struct trapframe *tf) td = curthread; + PCPU_INC(cnt.v_intr); + vector = tf->tf_special.ifa; next: @@ -147,28 +127,30 @@ interrupt(struct trapframe *tf) * read the vector. */ if (vector == 0) { + PCPU_INC(stats.pcs_nextints); inta = ib->ib_inta; - printf("ExtINT interrupt: vector=%u\n", (int)inta); if (inta == 15) { + PCPU_INC(stats.pcs_nstrays); __asm __volatile("mov cr.eoi = r0;; srlz.d"); goto stray; } vector = (int)inta; - } else if (vector == 15) + } else if (vector == 15) { + PCPU_INC(stats.pcs_nstrays); goto stray; + } if (vector == CLOCK_VECTOR) {/* clock interrupt */ /* CTR0(KTR_INTR, "clock interrupt"); */ itc = ia64_get_itc(); - PCPU_INC(cnt.v_intr); + PCPU_INC(stats.pcs_nclks); #ifdef EVCNT_COUNTERS clock_intr_evcnt.ev_count++; #else intrcnt[INTRCNT_CLOCK]++; #endif - clks[PCPU_GET(cpuid)]++; critical_enter(); @@ -211,17 +193,19 @@ interrupt(struct trapframe *tf) #ifdef SMP } else if (vector == ipi_vector[IPI_AST]) { - asts[PCPU_GET(cpuid)]++; + PCPU_INC(stats.pcs_nasts); CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid)); } else if (vector == ipi_vector[IPI_HIGH_FP]) { + PCPU_INC(stats.pcs_nhighfps); ia64_highfp_save_ipi(); } else if (vector == ipi_vector[IPI_RENDEZVOUS]) { - rdvs[PCPU_GET(cpuid)]++; + PCPU_INC(stats.pcs_nrdvs); CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid)); enable_intr(); smp_rendezvous_action(); disable_intr(); } else if (vector == ipi_vector[IPI_STOP]) { + PCPU_INC(stats.pcs_nstops); cpumask_t mybit = PCPU_GET(cpumask); /* Make sure IPI_STOP_HARD is mapped to IPI_STOP. */ @@ -235,6 +219,7 @@ interrupt(struct trapframe *tf) atomic_clear_int(&started_cpus, mybit); atomic_clear_int(&stopped_cpus, mybit); } else if (vector == ipi_vector[IPI_PREEMPT]) { + PCPU_INC(stats.pcs_npreempts); CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid)); __asm __volatile("mov cr.eoi = r0;; srlz.d"); enable_intr(); @@ -243,7 +228,7 @@ interrupt(struct trapframe *tf) goto stray; #endif } else { - ints[PCPU_GET(cpuid)]++; + PCPU_INC(stats.pcs_nhwints); atomic_add_int(&td->td_intr_nesting_level, 1); ia64_dispatch_intr(tf, vector); atomic_subtract_int(&td->td_intr_nesting_level, 1); diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index e578e8bb05a..8174eefdb9a 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -139,8 +139,6 @@ SYSCTL_STRING(_hw, OID_AUTO, family, CTLFLAG_RD, cpu_family, 0, extern vm_offset_t ksym_start, ksym_end; #endif -static void cpu_startup(void *); -SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); struct msgbuf *msgbufp = NULL; @@ -247,9 +245,11 @@ identifycpu(void) } static void -cpu_startup(dummy) - void *dummy; +cpu_startup(void *dummy) { + char nodename[16]; + struct pcpu *pc; + struct pcpu_stats *pcs; /* * Good {morning,afternoon,evening,night}. @@ -302,7 +302,67 @@ cpu_startup(dummy) */ ia64_probe_sapics(); ia64_mca_init(); + + /* + * Create sysctl tree for per-CPU information. + */ + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + pcs = &pc->pc_stats; + snprintf(nodename, sizeof(nodename), "cpu%u", pc->pc_cpuid); + sysctl_ctx_init(&pcs->pcs_sysctl_ctx); + pcs->pcs_sysctl_tree = SYSCTL_ADD_NODE(&pcs->pcs_sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, nodename, + CTLFLAG_RD, NULL, ""); + if (pcs->pcs_sysctl_tree == NULL) + continue; + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "nasts", CTLFLAG_RD, &pcs->pcs_nasts, + "Number of IPI_AST interrupts"); + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "nclks", CTLFLAG_RD, &pcs->pcs_nclks, + "Number of clock interrupts"); + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "nextints", CTLFLAG_RD, &pcs->pcs_nextints, + "Number of ExtINT interrupts"); + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "nhighfps", CTLFLAG_RD, &pcs->pcs_nhighfps, + "Number of IPI_HIGH_FP interrupts"); + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "nhwints", CTLFLAG_RD, &pcs->pcs_nhwints, + "Number of hardware (device) interrupts"); + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "npreempts", CTLFLAG_RD, &pcs->pcs_npreempts, + "Number of IPI_PREEMPT interrupts"); + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "nrdvs", CTLFLAG_RD, &pcs->pcs_nrdvs, + "Number of IPI_RENDEZVOUS interrupts"); + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "nstops", CTLFLAG_RD, &pcs->pcs_nstops, + "Number of IPI_STOP interrupts"); + + SYSCTL_ADD_ULONG(&pcs->pcs_sysctl_ctx, + SYSCTL_CHILDREN(pcs->pcs_sysctl_tree), OID_AUTO, + "nstrays", CTLFLAG_RD, &pcs->pcs_nstrays, + "Number of stray vectors"); + } } +SYSINIT(cpu_startup, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); void cpu_boot(int howto) diff --git a/sys/ia64/include/pcpu.h b/sys/ia64/include/pcpu.h index c63573b9992..3a258fa0f09 100644 --- a/sys/ia64/include/pcpu.h +++ b/sys/ia64/include/pcpu.h @@ -30,8 +30,24 @@ #ifndef _MACHINE_PCPU_H_ #define _MACHINE_PCPU_H_ +#include #include +struct pcpu_stats { + struct sysctl_ctx_list pcs_sysctl_ctx; + struct sysctl_oid *pcs_sysctl_tree; + + u_long pcs_nasts; /* IPI_AST counter. */ + u_long pcs_nclks; /* Clock interrupt counter. */ + u_long pcs_nextints; /* ExtINT counter. */ + u_long pcs_nhighfps; /* IPI_HIGH_FP counter. */ + u_long pcs_nhwints; /* Hardware int. counter. */ + u_long pcs_npreempts; /* IPI_PREEMPT counter. */ + u_long pcs_nrdvs; /* IPI_RENDEZVOUS counter. */ + u_long pcs_nstops; /* IPI_STOP counter. */ + u_long pcs_nstrays; /* Stray interrupt counter. */ +}; + #define PCPU_MD_FIELDS \ struct pcb pc_pcb; /* Used by IPI_STOP */ \ struct pmap *pc_current_pmap; /* active pmap */ \ @@ -39,7 +55,8 @@ uint64_t pc_clock; /* Clock counter. */ \ uint64_t pc_clockadj; /* Clock adjust. */ \ uint32_t pc_awake:1; /* CPU is awake? */ \ - uint32_t pc_acpi_id /* ACPI CPU id. */ + uint32_t pc_acpi_id; /* ACPI CPU id. */ \ + struct pcpu_stats pc_stats #ifdef _KERNEL