Skip to contentSkip to conversation

performance counters 3.1 for 2.5.45 [4/4]: kernel changes

PATCH In review Mikael Pettersson 2 participants 4 messages Oct 31, 2002 – Nov 4, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 performance counters 3.1 for 2.5.45 [4/4]: kernel changes

This is part 4 of 4 of perfctr-3.1 for the 2.5.45 kernel:
kernel changes to integrate the low and high-level drivers.

/Mikael

 CREDITS                              |    1 +
 MAINTAINERS                          |    6 ++++++
 arch/i386/Kconfig                    |    1 +
 arch/i386/kernel/entry.S             |   11 +++++++++++
 arch/i386/kernel/i8259.c             |    3 +++
 arch/i386/kernel/process.c           |    9 +++++++++
 arch/i386/mach-generic/irq_vectors.h |    5 +++--
 drivers/Makefile                     |    1 +
 include/asm-i386/apic.h              |    3 +++
 include/asm-i386/processor.h         |    2 ++
 include/asm-i386/unistd.h            |    1 +
 kernel/timer.c                       |    2 ++
 12 files changed, 43 insertions(+), 2 deletions(-)
CREDITS +1 -0
diff -uN linux-2.5.45/CREDITS linux-2.5.45.perfctr-3.1/CREDITS
@@ -2402,6 +2402,7 @@
 E: [email protected]
 W: http://www.csd.uu.se/~mikpe/
 D: Miscellaneous fixes
+D: Performance-monitoring counters driver
 
 N: Reed H. Petty
 E: [email protected]
MAINTAINERS +6 -0
diff -uN linux-2.5.45/MAINTAINERS linux-2.5.45.perfctr-3.1/MAINTAINERS
@@ -1292,6 +1292,12 @@
 L:	[email protected]
 S:	Maintained
 
+PERFORMANCE-MONITORING COUNTERS DRIVER
+P:	Mikael Pettersson
+M:	[email protected]
+W:	http://www.csd.uu.se/~mikpe/linux/perfctr/
+S:	Maintained
+
 PNP SUPPORT
 P:	Adam Belay
 M:	[email protected]
arch/i386/Kconfig +1 -0
diff -uN linux-2.5.45/arch/i386/Kconfig linux-2.5.45.perfctr-3.1/arch/i386/Kconfig
@@ -1513,6 +1513,7 @@
 
 source "arch/i386/oprofile/Kconfig"
 
+source "drivers/perfctr/Kconfig"
 
 menu "Kernel hacking"
 
arch/i386/kernel/entry.S +11 -0
diff -uN linux-2.5.45/arch/i386/kernel/entry.S linux-2.5.45.perfctr-3.1/arch/i386/kernel/entry.S
@@ -347,6 +347,16 @@
 /* The include is where all of the SMP etc. interrupts come from */
 #include "entry_arch.h"
 
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PERFCTR)
+ENTRY(perfctr_interrupt)
+	pushl $LOCAL_PERFCTR_VECTOR-256
+	SAVE_ALL
+	pushl %esp
+	call do_perfctr_interrupt
+	addl $4, %esp
+	jmp ret_from_intr
+#endif
+
 ENTRY(divide_error)
 	pushl $0			# no error code
 	pushl $do_divide_error
@@ -740,6 +750,7 @@
 	.long sys_epoll_create
 	.long sys_epoll_ctl	/* 255 */
 	.long sys_epoll_wait
+	.long sys_vperfctr
 
 
 	.rept NR_syscalls-(.-sys_call_table)/4
arch/i386/kernel/i8259.c +3 -0
diff -uN linux-2.5.45/arch/i386/kernel/i8259.c linux-2.5.45.perfctr-3.1/arch/i386/kernel/i8259.c
@@ -22,6 +22,7 @@
 #include <asm/desc.h>
 #include <asm/apic.h>
 #include <asm/arch_hooks.h>
+#include <asm/perfctr.h>
 
 #include <linux/irq.h>
 
@@ -389,6 +390,8 @@
 	 * the architecture specific gates */
 	intr_init_hook();
 
+	perfctr_vector_init();
+
 	/*
 	 * Set the clock to HZ Hz, we already have a valid
 	 * vector now:
arch/i386/kernel/process.c +9 -0
diff -uN linux-2.5.45/arch/i386/kernel/process.c linux-2.5.45.perfctr-3.1/arch/i386/kernel/process.c
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+#include <linux/vperfctr.h>
 #include <linux/mc146818rtc.h>
 #include <linux/module.h>
 
@@ -240,6 +241,7 @@
 		kfree(tsk->thread.ts_io_bitmap);
 		tsk->thread.ts_io_bitmap = NULL;
 	}
+	vperfctr_exit_thread(&tsk->thread);
 }
 
 void flush_thread(void)
@@ -299,6 +301,8 @@
 	unlazy_fpu(tsk);
 	struct_cpy(&p->thread.i387, &tsk->thread.i387);
 
+	vperfctr_copy_thread(&p->thread);
+
 	if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
 		p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
 		if (!p->thread.ts_io_bitmap)
@@ -413,6 +417,8 @@
 
 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
+	vperfctr_suspend_thread(prev);
+
 	unlazy_fpu(prev_p);
 
 	/*
@@ -475,6 +481,8 @@
 			 */
 			tss->bitmap = INVALID_IO_BITMAP_OFFSET;
 	}
+
+	vperfctr_resume_thread(next);
 }
 
 asmlinkage int sys_fork(struct pt_regs regs)
@@ -685,3 +693,4 @@
 	return 0;
 }
 
+cond_syscall(sys_vperfctr)
arch/i386/mach-generic/irq_vectors.h +3 -2
diff -uN linux-2.5.45/arch/i386/mach-generic/irq_vectors.h linux-2.5.45.perfctr-3.1/arch/i386/mach-generic/irq_vectors.h
@@ -56,14 +56,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
 
 #define TIMER_IRQ 0
 
drivers/Makefile +1 -0
diff -uN linux-2.5.45/drivers/Makefile linux-2.5.45.perfctr-3.1/drivers/Makefile
@@ -41,5 +41,6 @@
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_HOTPLUG_PCI)	+= hotplug/
 obj-$(CONFIG_ISDN_BOOL)		+= isdn/
+obj-$(CONFIG_PERFCTR)		+= perfctr/
 
 include $(TOPDIR)/Rules.make
include/asm-i386/apic.h +3 -0
diff -uN linux-2.5.45/include/asm-i386/apic.h linux-2.5.45.perfctr-3.1/include/asm-i386/apic.h
@@ -96,6 +96,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 */
include/asm-i386/processor.h +2 -0
diff -uN linux-2.5.45/include/asm-i386/processor.h linux-2.5.45.perfctr-3.1/include/asm-i386/processor.h
@@ -383,6 +383,8 @@
 	unsigned long		v86flags, v86mask, saved_esp0;
 /* IO permissions */
 	unsigned long	*ts_io_bitmap;
+/* performance counters */
+	struct vperfctr *vperfctr;
 };
 
 #define INIT_THREAD  {						\
include/asm-i386/unistd.h +1 -0
diff -uN linux-2.5.45/include/asm-i386/unistd.h linux-2.5.45.perfctr-3.1/include/asm-i386/unistd.h
@@ -261,6 +261,7 @@
 #define __NR_sys_epoll_create	254
 #define __NR_sys_epoll_ctl	255
 #define __NR_sys_epoll_wait	256
+#define __NR_vperfctr		257
   
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
kernel/timer.c +2 -0
diff -uN linux-2.5.45/kernel/timer.c linux-2.5.45.perfctr-3.1/kernel/timer.c
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/notifier.h>
+#include <linux/vperfctr.h>
 
 #include <asm/uaccess.h>
 
@@ -667,6 +668,7 @@
 	do_process_times(p, user, system);
 	do_it_virt(p, user);
 	do_it_prof(p);
+	vperfctr_sample_thread(&p->thread);
 }	
 
 /*
#1 lore raw
Quoted 5 lines · Mikael Pettersson

This is part 4 of 4 of perfctr-3.1 for the 2.5.45 kernel:
kernel changes to integrate the low and high-level drivers.

/Mikael

Quoted 13 lines
 CREDITS                              |    1 +
 MAINTAINERS                          |    6 ++++++
 arch/i386/Kconfig                    |    1 +
 arch/i386/kernel/entry.S             |   11 +++++++++++
 arch/i386/kernel/i8259.c             |    3 +++
 arch/i386/kernel/process.c           |    9 +++++++++
 arch/i386/mach-generic/irq_vectors.h |    5 +++--
 drivers/Makefile                     |    1 +
 include/asm-i386/apic.h              |    3 +++
 include/asm-i386/processor.h         |    2 ++
 include/asm-i386/unistd.h            |    1 +
 kernel/timer.c                       |    2 ++
 12 files changed, 43 insertions(+), 2 deletions(-)

Rather than adding yet another system call, shouldn't this be done by extending the cpu part of sysfs (or /proc)?

It looks like the operations in sys_vperfctr could be easily mapped to a RAM based file system. As it stands it reminds me of one of the old DEC graphic libraries with one API entry for all the operations, and 65 different flag values.

#2 lore raw
Quoted 3 lines · Stephen Hemminger
Quoted 2 lines · Mikael Pettersson

This is part 4 of 4 of perfctr-3.1 for the 2.5.45 kernel:
kernel changes to integrate the low and high-level drivers.

...

Quoted 3 lines

Rather than adding yet another system call, shouldn't this be done by extending the cpu part of sysfs (or /proc)?

Why?
ptrace() is a system call
fork() is a system call
write() is a system call
other arch's performance counter interfaces are system calls
...

Quoted 4 lines

It looks like the operations in sys_vperfctr could be easily mapped to a RAM based file system. As it stands it reminds me of one of the old DEC graphic libraries with one API entry for all the operations, and 65 different flag values.

There are about half a dozen operations, not 65. I could use 6 system calls, no problem, but as long as Linus is silent about this I have no reason to change it speculatively in random directions.

/Mikael

#3 lore raw
Quoted 9 lines · Mikael Pettersson
Quoted 3 lines · Stephen Hemminger
Quoted 2 lines · Mikael Pettersson

This is part 4 of 4 of perfctr-3.1 for the 2.5.45 kernel:
kernel changes to integrate the low and high-level drivers.

...

Quoted 3 lines

Rather than adding yet another system call, shouldn't this be done by extending the cpu part of sysfs (or /proc)?

Quoted 6 lines

Why?
ptrace() is a system call
fork() is a system call
write() is a system call
other arch's performance counter interfaces are system calls
...

ptrace predates /proc, and /proc is gradually superseding ptrace. Eventually it is hoped that ptrace dies.

Other architecture's added performance counters back in 2.4 before sysfs was added.

The reason to use a file system rather than a syscall is so that standard tools like sh, awk, perl, ... can be used on the data without having to build a separate command to access the data.

Linus is more likely to adopt simpler logical interfaces.