--- linux-2.4.9-ac3-perfctr/CREDITS.~1~ Tue Aug 28 14:19:26 2001 +++ linux-2.4.9-ac3-perfctr/CREDITS Tue Aug 28 14:20:40 2001 @@ -2280,6 +2280,7 @@ E: mikpe@csd.uu.se W: http://www.csd.uu.se/~mikpe/ D: Miscellaneous fixes +D: Performance-monitoring counters driver N: Reed H. Petty E: rhp@draper.net --- linux-2.4.9-ac3-perfctr/Documentation/Configure.help.~1~ Tue Aug 28 14:19:26 2001 +++ linux-2.4.9-ac3-perfctr/Documentation/Configure.help Tue Aug 28 14:20:40 2001 @@ -3694,6 +3694,72 @@ If unsure, say N. +Performance-monitoring counters support +CONFIG_PERFCTR + This driver provides access to the performance-monitoring counter + registers available in some (but not all) modern processors. + These special-purpose registers can be programmed to count low-level + performance-related events which occur during program execution, + such as cache misses, pipeline stalls, etc. + + The driver supports most x86-class processors known to have + performance-monitoring counters: Intel Pentium to Pentium III, + AMD K7, Cyrix 6x86MX/MII/III, VIA Cyrix III / C3, and WinChip C6/2/3. + + On processors which have a time-stamp counter but no performance- + monitoring counters, such as the AMD K6 family, the driver supports + plain cycle-count performance measurements only. + + On WinChip C6/2/3 processors the performance-monitoring counters + cannot be used unless the time-stamp counter has been disabled. + Please read for further information. + + You can safely say Y here, even if you intend to run the kernel + on a processor without performance-monitoring counters. + + You can also say M here to compile the driver as a module; the + module will be called `perfctr.o'. + +Additional internal consistency checks +CONFIG_PERFCTR_DEBUG + This option enables additional internal consistency checking in + the perfctr driver. The scope of these checks is unspecified and + may vary between different versions of the driver. + + Enabling this option will reduce performance, so say N unless you + are debugging the driver. + +Init-time hardware tests +CONFIG_PERFCTR_INIT_TESTS + This option makes the driver run additional hardware tests + during initialisation. This is not necessary for normal + operation, but it can be useful during driver development. + + If unsure, say N. + +Virtual performance counters support +CONFIG_PERFCTR_VIRTUAL + The processor's performance-monitoring counters are special-purpose + global registers. This option adds support for virtual per-process + performance-monitoring counters which only run when the process + to which they belong is executing. This improves the accuracy of + performance measurements by reducing "noise" from other processes. + + Say Y. + +Global performance counters support +CONFIG_PERFCTR_GLOBAL + This option adds driver support for global-mode (system-wide) + performance-monitoring counters. In this mode, the driver allows + each performance-monitoring counter on each processor to be + controlled and read. The driver provides a sampling timer to + maintain 64-bit accumulated event counts. + + Global-mode performance counters cannot be used if some process + is currently using virtual-mode performance counters, and vice versa. + + Say Y. + VGA text console CONFIG_VGA_CONSOLE Saying Y here will allow you to use Linux in text mode through a --- linux-2.4.9-ac3-perfctr/Documentation/ioctl-number.txt.~1~ Sat Jul 21 11:47:30 2001 +++ linux-2.4.9-ac3-perfctr/Documentation/ioctl-number.txt Tue Aug 28 14:20:40 2001 @@ -187,5 +187,7 @@ 0xB1 00-1F PPPoX 0xCB 00-1F CBM serial IEC bus in development: +0xD0 all performance counters in development: + 0xFE 00-9F Logical Volume Manager --- linux-2.4.9-ac3-perfctr/MAINTAINERS.~1~ Tue Aug 28 14:19:26 2001 +++ linux-2.4.9-ac3-perfctr/MAINTAINERS Tue Aug 28 14:20:40 2001 @@ -1144,6 +1144,12 @@ L: linux-net@vger.kernel.org S: Maintained +PERFORMANCE-MONITORING COUNTERS DRIVER +P: Mikael Pettersson +M: mikpe@csd.uu.se +W: http://www.csd.uu.se/~mikpe/linux/perfctr/ +S: Maintained + PNP SUPPORT P: Tom Lees M: tom@lpsg.demon.co.uk --- linux-2.4.9-ac3-perfctr/Makefile.~1~ Tue Aug 28 14:19:26 2001 +++ linux-2.4.9-ac3-perfctr/Makefile Tue Aug 28 14:20:40 2001 @@ -191,6 +191,7 @@ DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o +DRIVERS-$(CONFIG_KPERFCTR) += drivers/perfctr/kperfctr.o DRIVERS := $(DRIVERS-y) --- linux-2.4.9-ac3-perfctr/arch/i386/config.in.~1~ Tue Aug 28 14:19:26 2001 +++ linux-2.4.9-ac3-perfctr/arch/i386/config.in Tue Aug 28 14:20:40 2001 @@ -218,6 +218,7 @@ fi source drivers/pci/Config.in +source drivers/perfctr/Config.in bool 'EISA support' CONFIG_EISA --- linux-2.4.9-ac3-perfctr/arch/i386/kernel/i8259.c.~1~ Tue Aug 28 14:19:26 2001 +++ linux-2.4.9-ac3-perfctr/arch/i386/kernel/i8259.c Tue Aug 28 14:20:40 2001 @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -487,6 +488,10 @@ /* IPI vectors for APIC spurious and error interrupts */ set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); +#endif + +#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_KPERFCTR) + set_intr_gate(LOCAL_PERFCTR_VECTOR, perfctr_interrupt); #endif /* --- linux-2.4.9-ac3-perfctr/arch/i386/kernel/irq.c.~1~ Tue Aug 28 14:19:26 2001 +++ linux-2.4.9-ac3-perfctr/arch/i386/kernel/irq.c Tue Aug 28 14:20:40 2001 @@ -43,6 +43,7 @@ #include #include #include +#include @@ -171,6 +172,13 @@ for (j = 0; j < smp_num_cpus; j++) p += sprintf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]); + p += sprintf(p, "\n"); +#endif +#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_KPERFCTR) + p += sprintf(p, "PMC: "); + for (j = 0; j < smp_num_cpus; j++) + p += sprintf(p, "%10u ", + apic_lvtpc_irqs[cpu_logical_map(j)]); p += sprintf(p, "\n"); #endif p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); --- linux-2.4.9-ac3-perfctr/arch/i386/kernel/process.c.~1~ Tue Aug 28 14:19:26 2001 +++ linux-2.4.9-ac3-perfctr/arch/i386/kernel/process.c Tue Aug 28 14:20:40 2001 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -514,7 +515,7 @@ */ void exit_thread(void) { - /* nothing to do ... */ + perfctr_exit_thread(¤t->thread); } void flush_thread(void) @@ -596,6 +597,8 @@ unlazy_fpu(current); struct_cpy(&p->thread.i387, ¤t->thread.i387); + perfctr_copy_thread(&p->thread); + return 0; } @@ -678,6 +681,8 @@ *next = &next_p->thread; struct tss_struct *tss = init_tss + smp_processor_id(); + perfctr_suspend_thread(prev); + unlazy_fpu(prev_p); /* @@ -733,6 +738,8 @@ */ tss->bitmap = INVALID_IO_BITMAP_OFFSET; } + + perfctr_resume_thread(next); } asmlinkage int sys_fork(struct pt_regs regs) --- linux-2.4.9-ac3-perfctr/drivers/Makefile.~1~ Tue Aug 28 14:19:28 2001 +++ linux-2.4.9-ac3-perfctr/drivers/Makefile Tue Aug 28 14:20:40 2001 @@ -47,4 +47,7 @@ subdir-$(CONFIG_BLUEZ) += bluetooth +mod-subdirs += perfctr +subdir-$(CONFIG_KPERFCTR) += perfctr + include $(TOPDIR)/Rules.make --- linux-2.4.9-ac3-perfctr/fs/proc/base.c.~1~ Sat Jul 21 11:47:33 2001 +++ linux-2.4.9-ac3-perfctr/fs/proc/base.c Tue Aug 28 14:20:40 2001 @@ -23,6 +23,7 @@ #include #include #include +#include /* * For hysterical raisins we keep the same inumbers as in the old procfs. @@ -520,6 +521,7 @@ PROC_PID_STATM, PROC_PID_MAPS, PROC_PID_CPU, + PROC_PID_PERFCTR, PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */ }; @@ -539,6 +541,9 @@ E(PROC_PID_CWD, "cwd", S_IFLNK|S_IRWXUGO), E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO), E(PROC_PID_EXE, "exe", S_IFLNK|S_IRWXUGO), +#ifdef CONFIG_PERFCTR_VIRTUAL + E(PROC_PID_PERFCTR, "perfctr", PERFCTR_PROC_PID_MODE), +#endif {0,0,NULL,0} }; #undef E @@ -898,6 +903,11 @@ inode->i_op = &proc_mem_inode_operations; inode->i_fop = &proc_mem_operations; break; +#ifdef CONFIG_PERFCTR_VIRTUAL + case PROC_PID_PERFCTR: + perfctr_set_proc_pid_ops(inode); + break; +#endif default: printk("procfs: impossible type (%d)",p->type); iput(inode); --- linux-2.4.9-ac3-perfctr/include/asm-i386/apic.h.~1~ Tue Aug 28 14:19:33 2001 +++ linux-2.4.9-ac3-perfctr/include/asm-i386/apic.h Tue Aug 28 14:20:40 2001 @@ -91,6 +91,9 @@ #define NMI_LOCAL_APIC 2 #define NMI_INVALID 3 +extern struct pm_dev *nmi_pmdev; +extern unsigned int nmi_perfctr_msr; + #endif /* CONFIG_X86_LOCAL_APIC */ #endif /* __ASM_APIC_H */ --- linux-2.4.9-ac3-perfctr/include/asm-i386/hw_irq.h.~1~ Tue Aug 28 14:19:33 2001 +++ linux-2.4.9-ac3-perfctr/include/asm-i386/hw_irq.h Tue Aug 28 14:20:40 2001 @@ -49,14 +49,15 @@ * sources per level' errata. */ #define LOCAL_TIMER_VECTOR 0xef +#define LOCAL_PERFCTR_VECTOR 0xee /* - * First APIC vector available to drivers: (vectors 0x30-0xee) + * First APIC vector available to drivers: (vectors 0x30-0xed) * we start at 0x31 to spread out vectors evenly between priority * levels. (0x80 is the syscall vector) */ #define FIRST_DEVICE_VECTOR 0x31 -#define FIRST_SYSTEM_VECTOR 0xef +#define FIRST_SYSTEM_VECTOR 0xee extern int irq_vector[NR_IRQS]; #define IO_APIC_VECTOR(irq) irq_vector[irq] --- linux-2.4.9-ac3-perfctr/include/asm-i386/processor.h.~1~ Tue Aug 28 14:19:33 2001 +++ linux-2.4.9-ac3-perfctr/include/asm-i386/processor.h Tue Aug 28 14:20:40 2001 @@ -362,6 +362,11 @@ unsigned long __cacheline_filler[5]; }; +/* + * Virtual per-process performance-monitoring counters. + */ +struct vperfctr; /* opaque; no need to depend on */ + struct thread_struct { unsigned long esp0; unsigned long eip; @@ -381,6 +386,8 @@ /* IO permissions */ int ioperm; unsigned long io_bitmap[IO_BITMAP_SIZE+1]; +/* performance counters */ + struct vperfctr *perfctr; }; #define INIT_THREAD { \ @@ -390,7 +397,8 @@ 0, 0, 0, \ { { 0, }, }, /* 387 state */ \ 0,0,0,0,0,0, \ - 0,{~0,} /* io permissions */ \ + 0,{~0,}, /* io permissions */ \ + NULL, /* performance counters */ \ } #define INIT_MMAP \ --- linux-2.4.9-ac3-perfctr/kernel/timer.c.~1~ Tue Aug 28 14:19:34 2001 +++ linux-2.4.9-ac3-perfctr/kernel/timer.c Tue Aug 28 14:20:40 2001 @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -570,6 +571,7 @@ do_process_times(p, user, system); do_it_virt(p, user); do_it_prof(p); + perfctr_sample_thread(&p->thread); } /*