Skip to contentSkip to conversation

Performance Counters for Linux, v5

PATCH In review Ingo Molnar 2 participants 4 messages Dec 23, 2008 – Dec 25, 2008

Subsystems (12)
Documentation x86 VFS ACPI +8 more subsystems
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Performance Counters for Linux, v5

We are pleased to announce version 5 of our performance counters subsystem implementation. The Git tree can be found at:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git perfcounters/core

It's also available in tip/master at:

http://people.redhat.com/mingo/tip.git/README

The combo patch against .28-rc9 is also attached below.

There are a good deal of fundamental changes in this release:

- Support for fixed-function performance counters on x86. This is done in the way we described it earlier: the new hw counters are utilized transparently by the kernel - user-space will only notice that it can enable up to 2+3 counters on Core2 and 4+3 counters on Corei7 at once, if the event IDs match the fixed-purpose counters.

There's fixed-function counters available for: PERF_COUNT_INSTRUCTIONS, PERF_COUNT_CPU_CYCLES and PERF_COUNT_BUS_CYCLES - so using such counters wont waste generic event counters. For example, on Nehalem we can now count all the generic events at once, without round-robin scheduling of counters:

   $ ./timec -e 0,1,2,3,4,5,6 ./hackbench 20
   Time: 1.274
    Performance counter stats for '../hackbench':

      18751.819633  task clock ticks     (msecs)

       44331453557  CPU cycles           (events)
       35013178422  instructions         (events)
         121710024  cache references     (events)
          67371099  cache misses         (events)
       10869698427  branches             (events)
         725940130  branch misses        (events)
       44480332026  bus cycles           (events)

    Wall-clock time elapsed:  1497.000647 msecs

- Reshaped, more precise counter inheritance support: the final counts are now 'pulled' instead of 'pushed' by the child task. This means that we propagate the 'truly final' counts of child tasks, counted up to the last instruction they spent on a CPU before they exit.

- More accurate per task software-counters. There were bugs in the code that caused spurious zero readouts and similar noise - those problems are fixed now.

- ( There's a handful of updates and fixes to other areas of the perfcounters code as well, see the Git history for more details.)

The user-space ABI has not changed in an incompatible way over -v4: the extra bus cycles event type that has been added in a compatible way.

There are new timec.c and kerneltop.c versions available as well:

http://redhat.com/~mingo/perfcounters/timec.c
http://redhat.com/~mingo/perfcounters/kerneltop.c

Thanks,

Ingo, Thomas

------------------>

The latest perfcounters/core git tree can be found at:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git perfcounters/core

------------------>
Alexander van Heukelum (12):
x86: irq: fix apicinterrupts on 64 bits
x86: entry_64.S: remove whitespace at end of lines
x86: move entry_64.S register saving out of the macros
x86: clean up after: move entry_64.S register saving out of the macros
x86: introduce save_rest and restructure the PTREGSCALL macro in entry_64.S
x86: entry_64.S: factor out save_paranoid and paranoid_exit
x86: entry_64.S: split out some macro's and move common code to paranoid_exit
x86: split out some macro's and move common code to paranoid_exit, fix
x86: include ENTRY/END in entry handlers in entry_64.S
x86: KPROBE_ENTRY should be paired wth KPROBE_END
x86_64: get rid of the use of KPROBE_ENTRY / KPROBE_END
i386: get rid of the use of KPROBE_ENTRY / KPROBE_END

Cyrill Gorcunov (5):
x86: move dwarf2 related macro to dwarf2.h
x86: introduce ENTRY(KPROBE_ENTRY)_X86 assembly helpers to catch unbalanced declaration v3
x86: entry_64.S - use ENTRY to define child_rip
x86: uv bau interrupt -- use proper interrupt number
x86: entry_64.S - trivial: space, comments fixup

Dan McGee (1):
x86: remove dead IRQBALANCE code

H. Peter Anvin (4):
x86: 32 bit: interrupt stub consistency with 64 bit
x86: 32 bits: shrink and align IRQ stubs
x86: 64 bits: shrink and align IRQ stubs
x86: fix up the new IRQ code for older versions of gas

Harvey Harrison (2):
x86: use the new byteorder headers
x86: x86_32 has its own irq_regs definition

Hiroshi Shimamoto (28):
x86: signal: cosmetic unification of restore_sigcontext()
x86: signal_64.c: get_stack() doesn't need entire regs
x86: signal: cosmetic unification of signr_convert()
x86: signal: cosmetic unification of macros for setup_rt_frame()
x86: signal: cosmetic unification of NR_restart_syscall
x86: signal_64: remove unused code in __setup_rt_frame()
x86: signal_32: do save_i387_xstate() at get_sigframe()
x86: ia32_signal: do save_i387_xstate_ia32 at get_sigframe()
x86: signal_64: setup fpstate in setup_sigcontext()
x86: signal_64: make setup_sigcontext() similar
x86: signal: cosmetic unification of setup_sigcontext()
x86: signal_32: introduce retcode and rt_retcode
x86: ia32_signal: remove unnecessary padding
x86: ia32_signal: cleanup macro COPY
x86: ia32_signal: introduce COPY_SEG_CPL3
x86: ia32_signal: cleanup macro RELOAD_SEG
x86: ia32_signal: remove using temporary variable
x86: ia32_signal: change order of storing in setup_sigcontext()
x86: signal: rename COPY_SEG_STRICT to COPY_SEG_CPL3
x86: signal: cosmetic unification of including headers
x86: signal: cosmetic unification of sys_sigaltstack()
x86: signal: cosmetic unification of sys_rt_sigreturn()
x86: signal: move {setup|restore}_sigcontext()
x86: signal: cosmetic unification of __setup_sigframe() and __setup_rt_sigframe()
x86: signal: unify signal_{32|64}.c, prepare
x86: signal: unify signal_{32|64}.c
x86: signal: change type of paramter for sys_rt_sigreturn()
x86: hardirq: introduce inc_irq_stat()

Ingo Molnar (53):
x86 debug: mark early_printk.o as notrace
x86: clean up rdtsc_barrier() use
x86: clean up vget_cycles()
x86: clean up after: move entry_64.S register saving out of the macros, fix
x86: entry_64.S: rename
x86: clean up stack overflow debug check
x86: ret_from_fork - get rid of jump back
performance counters: documentation
performance counters: x86 support
x86, perfcounters: read out MSR_CORE_PERF_GLOBAL_STATUS with counters disabled
perfcounters: select ANON_INODES
perfcounters, x86: simplify disable/enable of counters perfcounters, x86: clean up debug code
perfcounters: consolidate global-disable codepaths
perf counters: restructure the API
perf counters: add support for group counters
perf counters: group counter, fixes
perf counters: hw driver API
perf counters: implement PERF_COUNT_CPU_CLOCK
perf counters: consolidate hw_perf save/restore APIs
perf counters: implement PERF_COUNT_TASK_CLOCK
perf counters: add prctl interface to disable/enable counters perf counters: clean up state transitions
perf counters: update docs
x86: implement atomic64_t on 32-bit
perfcounters: restructure x86 counter math
perfcounters: implement "counter inheritance"
perfcounters: fix task clock counter
perfcounters: add context switch counter
perfcounters: add task migrations counter
perfcounters: add nr-of-faults counter
perfcounters: fix non-intel-perfmon CPUs
perfcounters, x86: fix sw counters on non-PMC CPUs
perfcounters: fix lapic initialization
perfcounters: release CPU context when exiting task counters
perfcounters: flush on setuid exec
perfcounters: use hw_event.disable flag
perfcounters: remove warnings
perfcounters: tweak group scheduling
x86, perfcounters: rename intel_arch_perfmon.h => perf_counter.h x86, perfcounters: prepare for fixed-mode PMCs
perfcounters: add fixed-mode PMC enumeration
x86, perfcounters: refactor code for fixed-function PMCs
perfcounters: hw ops rename
perfcounters: fix task clock counter
perfcounters: pull inherited counters
perfcounters: fix init context lock
perfcounters: enable lowlevel pmc code to schedule counters
x86, perfcounters: print out the ->used bitmask
perfcounters: remove ->nr_inherited
perfcounters: generalize the counter scheduler
perfcounters: add PERF_COUNT_BUS_CYCLES
x86, perfcounters: add support for fixed-function pmcs

Jan Beulich (2):
x86: simplify X86_MPPARSE config option
x86: add two missing unwind annotations

Jaswinder Singh (1):
x86: perf_counter.c intel_perfmon_event_map and max_intel_perfmon_events should be static

Mikael Pettersson (1):
x86, signals: remove duplicated register setup code in ia32 signal delivery

Prarit Bhargava (1):
x86: warn of incorrect cpu_khz on AMD systems

Thomas Gleixner (4):
performance counters: core code
perf counters: protect them against CSTATE transitions perf counters: clean up 'raw' type API
perf counters: expand use of counter->event

Uros Bizjak (1):
x86: Implement change_bit with immediate operand as "lock xorb"

Zhaolei (1):
x86: avoid duplicate running of pud_offset and pmd_offset in one_md_table_init()

[email protected] (1):
x86: entry_64.S - use X86_EFLAGS_IF instead of hardcoded number

jia zhang (2):
x86_64: fix the check in stack_overflow_check x86, debug: remove the confusing entry in call trace

 Documentation/perf-counters.txt                |  147 ++
 arch/x86/Kconfig                               |   13 +-
 arch/x86/ia32/ia32_signal.c                    |   68 +-
 arch/x86/ia32/ia32entry.S                      |    3 +-
 arch/x86/include/asm/atomic_32.h               |  218 +++
 arch/x86/include/asm/bitops.h                  |   10 +-
 arch/x86/include/asm/byteorder.h               |   74 +-
 arch/x86/include/asm/dwarf2.h                  |   97 +-
 arch/x86/include/asm/hardirq_32.h              |    3 +
 arch/x86/include/asm/hardirq_64.h              |    2 +
 arch/x86/include/asm/hw_irq.h                  |    6 +-
 arch/x86/include/asm/intel_arch_perfmon.h      |   31 -
 arch/x86/include/asm/irq.h                     |    4 -
 arch/x86/include/asm/irq_regs_32.h             |    2 +
 arch/x86/include/asm/irq_vectors.h             |    5 +
 arch/x86/include/asm/linkage.h                 |   60 +
 arch/x86/include/asm/mach-default/entry_arch.h |    5 +
 arch/x86/include/asm/pda.h                     |    1 +
 arch/x86/include/asm/perf_counter.h            |   95 ++
 arch/x86/include/asm/syscalls.h                |    2 +-
 arch/x86/include/asm/thread_info.h             |    4 +-
 arch/x86/include/asm/tsc.h                     |    8 +-
 arch/x86/include/asm/unistd_32.h               |    1 +
 arch/x86/include/asm/unistd_64.h               |    3 +-
 arch/x86/kernel/Makefile                       |    3 +-
 arch/x86/kernel/apic.c                         |   15 +-
 arch/x86/kernel/cpu/Makefile                   |   12 +-
 arch/x86/kernel/cpu/common.c                   |    2 +
 arch/x86/kernel/cpu/perf_counter.c             |  705 ++++++++++
 arch/x86/kernel/cpu/perfctr-watchdog.c         |    2 +-
 arch/x86/kernel/entry_32.S                     |  477 ++++----
 arch/x86/kernel/entry_64.S                     | 1363 ++++++++++---------
 arch/x86/kernel/irq.c                          |    5 +
 arch/x86/kernel/irq_64.c                       |   24 +-
 arch/x86/kernel/irqinit_32.c                   |    5 +-
 arch/x86/kernel/irqinit_64.c                   |   71 +-
 arch/x86/kernel/{signal_32.c => signal.c}      |  574 ++++++---
 arch/x86/kernel/signal_64.c                    |  516 --------
 arch/x86/kernel/smp.c                          |   18 +-
 arch/x86/kernel/syscall_table_32.S             |    1 +
 arch/x86/kernel/time_64.c                      |    2 +
 arch/x86/kernel/traps.c                        |    6 +-
 arch/x86/kernel/vsyscall_64.c                  |    9 +
 arch/x86/lguest/boot.c                         |    3 +-
 arch/x86/mm/init_32.c                          |    2 +
 arch/x86/oprofile/op_model_ppro.c              |    2 +-
 drivers/acpi/processor_idle.c                  |    8 +
 drivers/char/sysrq.c                           |    2 +
 fs/exec.c                                      |    8 +
 include/linux/init_task.h                      |   11 +
 include/linux/kernel_stat.h                    |    8 +
 include/linux/linkage.h                        |    8 -
 include/linux/perf_counter.h                   |  254 ++++
 include/linux/prctl.h                          |    3 +
 include/linux/sched.h                          |   12 +-
 include/linux/syscalls.h                       |    8 +
 init/Kconfig                                   |   30 +
 kernel/Makefile                                |    1 +
 kernel/exit.c                                  |   13 +-
 kernel/fork.c                                  |    1 +
 kernel/perf_counter.c                          | 1686 ++++++++++++++++++++++++
 kernel/sched.c                                 |   76 +-
 kernel/sys.c                                   |    7 +
 kernel/sys_ni.c                                |    3 +
 64 files changed, 4943 insertions(+), 1875 deletions(-)
 create mode 100644 Documentation/perf-counters.txt
 delete mode 100644 arch/x86/include/asm/intel_arch_perfmon.h
 create mode 100644 arch/x86/include/asm/perf_counter.h
 create mode 100644 arch/x86/kernel/cpu/perf_counter.c
 rename arch/x86/kernel/{signal_32.c => signal.c} (74%)
 delete mode 100644 arch/x86/kernel/signal_64.c
 create mode 100644 include/linux/perf_counter.h
 create mode 100644 kernel/perf_counter.c
Documentation/perf-counters.txt new file +147 -0
new file mode 100644
index 0000000..fddd321
@@ -0,0 +1,147 @@
+
+Performance Counters for Linux
+------------------------------
+
+Performance counters are special hardware registers available on most modern
+CPUs. These registers count the number of certain types of hw events: such
+as instructions executed, cachemisses suffered, or branches mis-predicted -
+without slowing down the kernel or applications. These registers can also
+trigger interrupts when a threshold number of events have passed - and can
+thus be used to profile the code that runs on that CPU.
+
+The Linux Performance Counter subsystem provides an abstraction of these
+hardware capabilities. It provides per task and per CPU counters, counter
+groups, and it provides event capabilities on top of those.
+
+Performance counters are accessed via special file descriptors.
+There's one file descriptor per virtual counter used.
+
+The special file descriptor is opened via the perf_counter_open()
+system call:
+
+   int sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr,
+			     pid_t pid, int cpu, int group_fd);
+
+The syscall returns the new fd. The fd can be used via the normal
+VFS system calls: read() can be used to read the counter, fcntl()
+can be used to set the blocking mode, etc.
+
+Multiple counters can be kept open at a time, and the counters
+can be poll()ed.
+
+When creating a new counter fd, 'perf_counter_hw_event' is:
+
+/*
+ * Hardware event to monitor via a performance monitoring counter:
+ */
+struct perf_counter_hw_event {
+	s64			type;
+
+	u64			irq_period;
+	u32			record_type;
+
+	u32			disabled     :  1, /* off by default */
+				nmi	     :  1, /* NMI sampling   */
+				raw	     :  1, /* raw event type */
+				__reserved_1 : 29;
+
+	u64			__reserved_2;
+};
+
+/*
+ * Generalized performance counter event types, used by the hw_event.type
+ * parameter of the sys_perf_counter_open() syscall:
+ */
+enum hw_event_types {
+	/*
+	 * Common hardware events, generalized by the kernel:
+	 */
+	PERF_COUNT_CYCLES		=  0,
+	PERF_COUNT_INSTRUCTIONS		=  1,
+	PERF_COUNT_CACHE_REFERENCES	=  2,
+	PERF_COUNT_CACHE_MISSES		=  3,
+	PERF_COUNT_BRANCH_INSTRUCTIONS	=  4,
+	PERF_COUNT_BRANCH_MISSES	=  5,
+
+	/*
+	 * Special "software" counters provided by the kernel, even if
+	 * the hardware does not support performance counters. These
+	 * counters measure various physical and sw events of the
+	 * kernel (and allow the profiling of them as well):
+	 */
+	PERF_COUNT_CPU_CLOCK		= -1,
+	PERF_COUNT_TASK_CLOCK		= -2,
+	/*
+	 * Future software events:
+	 */
+	/* PERF_COUNT_PAGE_FAULTS	= -3,
+	   PERF_COUNT_CONTEXT_SWITCHES	= -4, */
+};
+
+These are standardized types of events that work uniformly on all CPUs
+that implements Performance Counters support under Linux. If a CPU is
+not able to count branch-misses, then the system call will return
+-EINVAL.
+
+More hw_event_types are supported as well, but they are CPU
+specific and are enumerated via /sys on a per CPU basis. Raw hw event
+types can be passed in under hw_event.type if hw_event.raw is 1.
+For example, to count "External bus cycles while bus lock signal asserted"
+events on Intel Core CPUs, pass in a 0x4064 event type value and set
+hw_event.raw to 1.
+
+'record_type' is the type of data that a read() will provide for the
+counter, and it can be one of:
+
+/*
+ * IRQ-notification data record type:
+ */
+enum perf_counter_record_type {
+	PERF_RECORD_SIMPLE		=  0,
+	PERF_RECORD_IRQ			=  1,
+	PERF_RECORD_GROUP		=  2,
+};
+
+a "simple" counter is one that counts hardware events and allows
+them to be read out into a u64 count value. (read() returns 8 on
+a successful read of a simple counter.)
+
+An "irq" counter is one that will also provide an IRQ context information:
+the IP of the interrupted context. In this case read() will return
+the 8-byte counter value, plus the Instruction Pointer address of the
+interrupted context.
+
+The parameter 'hw_event_period' is the number of events before waking up
+a read() that is blocked on a counter fd. Zero value means a non-blocking
+counter.
+
+The 'pid' parameter allows the counter to be specific to a task:
+
+ pid == 0: if the pid parameter is zero, the counter is attached to the
+ current task.
+
+ pid > 0: the counter is attached to a specific task (if the current task
+ has sufficient privilege to do so)
+
+ pid < 0: all tasks are counted (per cpu counters)
+
+The 'cpu' parameter allows a counter to be made specific to a full
+CPU:
+
+ cpu >= 0: the counter is restricted to a specific CPU
+ cpu == -1: the counter counts on all CPUs
+
+(Note: the combination of 'pid == -1' and 'cpu == -1' is not valid.)
+
+A 'pid > 0' and 'cpu == -1' counter is a per task counter that counts
+events of that task and 'follows' that task to whatever CPU the task
+gets schedule to. Per task counters can be created by any user, for
+their own tasks.
+
+A 'pid == -1' and 'cpu == x' counter is a per CPU counter that counts
+all events on CPU-x. Per CPU counters need CAP_SYS_ADMIN privilege.
+
+Group counters are created by passing in a group_fd of another counter.
+Groups are scheduled at once and can be used with PERF_RECORD_GROUP
+to record multi-dimensional timestamps.
+
arch/x86/Kconfig +3 -10
index ac22bb7..fe94490 100644
@@ -242,21 +242,13 @@ config X86_FIND_SMP_CONFIG
 	def_bool y
 	depends on X86_MPPARSE || X86_VOYAGER
 
-if ACPI
 config X86_MPPARSE
-	def_bool y
-	bool "Enable MPS table"
+	bool "Enable MPS table" if ACPI
+	default y
 	depends on X86_LOCAL_APIC
 	help
 	  For old smp systems that do not have proper acpi support. Newer systems
 	  (esp with 64bit cpus) with acpi support, MADT and DSDT will override it
-endif
-
-if !ACPI
-config X86_MPPARSE
-	def_bool y
-	depends on X86_LOCAL_APIC
-endif
 
 choice
 	prompt "Subarchitecture Type"
@@ -651,6 +643,7 @@ config X86_UP_IOAPIC
 config X86_LOCAL_APIC
 	def_bool y
 	depends on X86_64 || (X86_32 && (X86_UP_APIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH))
+	select HAVE_PERF_COUNTERS if (!M386 && !M486)
 
 config X86_IO_APIC
 	def_bool y
arch/x86/ia32/ia32_signal.c +29 -39

136 lines not on this page · raw message

arch/x86/ia32/ia32entry.S +2 -1
index 256b00b..3c14ed0 100644
@@ -823,7 +823,8 @@ ia32_sys_call_table:
 	.quad compat_sys_signalfd4
 	.quad sys_eventfd2
 	.quad sys_epoll_create1
-	.quad sys_dup3			/* 330 */
+	.quad sys_dup3				/* 330 */
 	.quad sys_pipe2
 	.quad sys_inotify_init1
+	.quad sys_perf_counter_open
 ia32_syscall_end:
arch/x86/include/asm/atomic_32.h +218 -0

223 lines not on this page · raw message

arch/x86/include/asm/bitops.h +9 -1
index 3600103..9fa9dcd 100644
@@ -168,7 +168,15 @@ static inline void __change_bit(int nr, volatile unsigned long *addr)
  */
 static inline void change_bit(int nr, volatile unsigned long *addr)
 {
-	asm volatile(LOCK_PREFIX "btc %1,%0" : ADDR : "Ir" (nr));
+	if (IS_IMMEDIATE(nr)) {
+		asm volatile(LOCK_PREFIX "xorb %1,%0"
+			: CONST_MASK_ADDR(nr, addr)
+			: "iq" ((u8)CONST_MASK(nr)));
+	} else {
+		asm volatile(LOCK_PREFIX "btc %1,%0"
+			: BITOP_ADDR(addr)
+			: "Ir" (nr));
+	}
 }
 
 /**
arch/x86/include/asm/byteorder.h +29 -45

105 lines not on this page · raw message

arch/x86/include/asm/dwarf2.h +66 -31

122 lines not on this page · raw message

arch/x86/include/asm/hardirq_32.h +3 -0
index 5ca135e..7a07897 100644
@@ -9,6 +9,7 @@ typedef struct {
 	unsigned long idle_timestamp;
 	unsigned int __nmi_count;	/* arch dependent */
 	unsigned int apic_timer_irqs;	/* arch dependent */
+	unsigned int apic_perf_irqs;	/* arch dependent */
 	unsigned int irq0_irqs;
 	unsigned int irq_resched_count;
 	unsigned int irq_call_count;
@@ -22,6 +23,8 @@ DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
 #define __ARCH_IRQ_STAT
 #define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member)
 
+#define inc_irq_stat(member)	(__get_cpu_var(irq_stat).member++)
+
 void ack_bad_irq(unsigned int irq);
 #include <linux/irq_cpustat.h>
 
arch/x86/include/asm/hardirq_64.h +2 -0
index 1ba381f..b5a6b5d 100644
@@ -11,6 +11,8 @@
 
 #define __ARCH_IRQ_STAT 1
 
+#define inc_irq_stat(member)	add_pda(member, 1)
+
 #define local_softirq_pending() read_pda(__softirq_pending)
 
 #define __ARCH_SET_SOFTIRQ_PENDING 1
arch/x86/include/asm/hw_irq.h +3 -3
index b97aecb..aa93e53 100644
@@ -30,6 +30,8 @@
 /* Interrupt handlers registered during init_IRQ */
 extern void apic_timer_interrupt(void);
 extern void error_interrupt(void);
+extern void perf_counter_interrupt(void);
+
 extern void spurious_interrupt(void);
 extern void thermal_interrupt(void);
 extern void reschedule_interrupt(void);
@@ -109,9 +111,7 @@ extern asmlinkage void smp_invalidate_interrupt(struct pt_regs *);
 #endif
 #endif
 
-#ifdef CONFIG_X86_32
-extern void (*const interrupt[NR_VECTORS])(void);
-#endif
+extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
 
 typedef int vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
arch/x86/include/asm/intel_arch_perfmon.h deleted +0 -31
deleted file mode 100644
index fa0fd06..0000000
@@ -1,31 +0,0 @@
-#ifndef _ASM_X86_INTEL_ARCH_PERFMON_H
-#define _ASM_X86_INTEL_ARCH_PERFMON_H
-
-#define MSR_ARCH_PERFMON_PERFCTR0		0xc1
-#define MSR_ARCH_PERFMON_PERFCTR1		0xc2
-
-#define MSR_ARCH_PERFMON_EVENTSEL0		0x186
-#define MSR_ARCH_PERFMON_EVENTSEL1		0x187
-
-#define ARCH_PERFMON_EVENTSEL0_ENABLE	(1 << 22)
-#define ARCH_PERFMON_EVENTSEL_INT	(1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS	(1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR	(1 << 16)
-
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL	(0x3c)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK	(0x00 << 8)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX (0)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
-	(1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
-
-union cpuid10_eax {
-	struct {
-		unsigned int version_id:8;
-		unsigned int num_counters:8;
-		unsigned int bit_width:8;
-		unsigned int mask_length:8;
-	} split;
-	unsigned int full;
-};
-
-#endif /* _ASM_X86_INTEL_ARCH_PERFMON_H */
arch/x86/include/asm/irq.h +0 -4
index bae0eda..28e409f 100644
@@ -31,10 +31,6 @@ static inline int irq_canonicalize(int irq)
 # endif
 #endif
 
-#ifdef CONFIG_IRQBALANCE
-extern int irqbalance_disable(char *str);
-#endif
-
 #ifdef CONFIG_HOTPLUG_CPU
 #include <linux/cpumask.h>
 extern void fixup_irqs(cpumask_t map);
arch/x86/include/asm/irq_regs_32.h +2 -0
index af2f02d..86afd74 100644
@@ -9,6 +9,8 @@
 
 #include <asm/percpu.h>
 
+#define ARCH_HAS_OWN_IRQ_REGS
+
 DECLARE_PER_CPU(struct pt_regs *, irq_regs);
 
 static inline struct pt_regs *get_irq_regs(void)
arch/x86/include/asm/irq_vectors.h +5 -0
index 0005adb..b8d277f 100644
@@ -87,6 +87,11 @@
 #define LOCAL_TIMER_VECTOR	0xef
 
 /*
+ * Performance monitoring interrupt vector:
+ */
+#define LOCAL_PERF_VECTOR	0xee
+
+/*
  * First APIC vector available to drivers: (vectors 0x30-0xee) we
  * start at 0x31(0x41) to spread out vectors evenly between priority
  * levels. (0x80 is the syscall vector)
arch/x86/include/asm/linkage.h +60 -0

65 lines not on this page · raw message

arch/x86/include/asm/mach-default/entry_arch.h +5 -0
index 6b1add8..ad31e5d 100644
@@ -25,10 +25,15 @@ BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
  * a much simpler SMP time architecture:
  */
 #ifdef CONFIG_X86_LOCAL_APIC
+
 BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
 BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
 BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
 
+#ifdef CONFIG_PERF_COUNTERS
+BUILD_INTERRUPT(perf_counter_interrupt, LOCAL_PERF_VECTOR)
+#endif
+
 #ifdef CONFIG_X86_MCE_P4THERMAL
 BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
 #endif
arch/x86/include/asm/pda.h +1 -0
index 2fbfff8..90a8d9d 100644
@@ -30,6 +30,7 @@ struct x8664_pda {
 	short isidle;
 	struct mm_struct *active_mm;
 	unsigned apic_timer_irqs;
+	unsigned apic_perf_irqs;
 	unsigned irq0_irqs;
 	unsigned irq_resched_count;
 	unsigned irq_call_count;
arch/x86/include/asm/perf_counter.h new file +95 -0

95 lines not on this page · raw message

arch/x86/include/asm/syscalls.h +1 -1
index 87803da..3a5252c 100644
@@ -33,7 +33,7 @@ asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
 			     struct old_sigaction __user *);
 asmlinkage int sys_sigaltstack(unsigned long);
 asmlinkage unsigned long sys_sigreturn(unsigned long);
-asmlinkage int sys_rt_sigreturn(unsigned long);
+asmlinkage int sys_rt_sigreturn(struct pt_regs);
 
 /* kernel/ioport.c */
 asmlinkage long sys_iopl(unsigned long);
arch/x86/include/asm/thread_info.h +3 -1
index e44d379..810bf26 100644
@@ -80,6 +80,7 @@ struct thread_info {
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_SECCOMP		8	/* secure computing */
 #define TIF_MCE_NOTIFY		10	/* notify userspace of an MCE */
+#define TIF_PERF_COUNTERS	11	/* notify perf counter work */
 #define TIF_NOTSC		16	/* TSC is not accessible in userland */
 #define TIF_IA32		17	/* 32bit process */
 #define TIF_FORK		18	/* ret_from_fork */
@@ -103,6 +104,7 @@ struct thread_info {
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_MCE_NOTIFY		(1 << TIF_MCE_NOTIFY)
+#define _TIF_PERF_COUNTERS	(1 << TIF_PERF_COUNTERS)
 #define _TIF_NOTSC		(1 << TIF_NOTSC)
 #define _TIF_IA32		(1 << TIF_IA32)
 #define _TIF_FORK		(1 << TIF_FORK)
@@ -135,7 +137,7 @@ struct thread_info {
 
 /* Only used for 64 bit */
 #define _TIF_DO_NOTIFY_MASK						\
-	(_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME)
+	(_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_PERF_COUNTERS|_TIF_NOTIFY_RESUME)
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW							\
arch/x86/include/asm/tsc.h +1 -7
index 9cd83a8..38ae163 100644
@@ -34,8 +34,6 @@ static inline cycles_t get_cycles(void)
 
 static __always_inline cycles_t vget_cycles(void)
 {
-	cycles_t cycles;
-
 	/*
 	 * We only do VDSOs on TSC capable CPUs, so this shouldnt
 	 * access boot_cpu_data (which is not VDSO-safe):
@@ -44,11 +42,7 @@ static __always_inline cycles_t vget_cycles(void)
 	if (!cpu_has_tsc)
 		return 0;
 #endif
-	rdtsc_barrier();
-	cycles = (cycles_t)__native_read_tsc();
-	rdtsc_barrier();
-
-	return cycles;
+	return (cycles_t)__native_read_tsc();
 }
 
 extern void tsc_init(void);
arch/x86/include/asm/unistd_32.h +1 -0
index f2bba78..7e47658 100644
@@ -338,6 +338,7 @@
 #define __NR_dup3		330
 #define __NR_pipe2		331
 #define __NR_inotify_init1	332
+#define __NR_perf_counter_open	333
 
 #ifdef __KERNEL__
 
arch/x86/include/asm/unistd_64.h +2 -1
index d2e415e..53025fe 100644
@@ -653,7 +653,8 @@ __SYSCALL(__NR_dup3, sys_dup3)
 __SYSCALL(__NR_pipe2, sys_pipe2)
 #define __NR_inotify_init1			294
 __SYSCALL(__NR_inotify_init1, sys_inotify_init1)
-
+#define __NR_perf_counter_open		295
+__SYSCALL(__NR_perf_counter_open, sys_perf_counter_open)
 
 #ifndef __NO_STUBS
 #define __ARCH_WANT_OLD_READDIR
arch/x86/kernel/Makefile +2 -1
index b62a766..3d4346a 100644
@@ -12,6 +12,7 @@ CFLAGS_REMOVE_tsc.o = -pg
 CFLAGS_REMOVE_rtc.o = -pg
 CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
 CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_early_printk.o = -pg
 endif
 
 #
@@ -23,7 +24,7 @@ CFLAGS_vsyscall_64.o	:= $(PROFILING) -g0 $(nostackp)
 CFLAGS_hpet.o		:= $(nostackp)
 CFLAGS_tsc.o		:= $(nostackp)
 
-obj-y			:= process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
+obj-y			:= process_$(BITS).o signal.o entry_$(BITS).o
 obj-y			+= traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y			+= time_$(BITS).o ioport.o ldt.o
 obj-y			+= setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
arch/x86/kernel/apic.c +5 -10
index 16f9487..4f859ac 100644
@@ -31,6 +31,7 @@
 #include <linux/dmi.h>
 #include <linux/dmar.h>
 
+#include <asm/perf_counter.h>
 #include <asm/atomic.h>
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -783,11 +784,7 @@ static void local_apic_timer_interrupt(void)
 	/*
 	 * the NMI deadlock-detector uses this.
 	 */
-#ifdef CONFIG_X86_64
-	add_pda(apic_timer_irqs, 1);
-#else
-	per_cpu(irq_stat, cpu).apic_timer_irqs++;
-#endif
+	inc_irq_stat(apic_timer_irqs);
 
 	evt->event_handler(evt);
 }
@@ -1147,6 +1144,7 @@ void __cpuinit setup_local_APIC(void)
 		apic_write(APIC_ESR, 0);
 	}
 #endif
+	perf_counters_lapic_init(0);
 
 	preempt_disable();
 
@@ -1695,14 +1693,11 @@ void smp_spurious_interrupt(struct pt_regs *regs)
 	if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
 		ack_APIC_irq();
 
-#ifdef CONFIG_X86_64
-	add_pda(irq_spurious_count, 1);
-#else
+	inc_irq_stat(irq_spurious_count);
+
 	/* see sw-dev-man vol 3, chapter 7.4.13.5 */
 	printk(KERN_INFO "spurious APIC interrupt on CPU#%d, "
 	       "should never happen.\n", smp_processor_id());
-	__get_cpu_var(irq_stat).irq_spurious_count++;
-#endif
 	irq_exit();
 }
 
arch/x86/kernel/cpu/Makefile +7 -5
index 82ec607..89e5336 100644
@@ -1,5 +1,5 @@
 #
-# Makefile for x86-compatible CPU details and quirks
+# Makefile for x86-compatible CPU details, features and quirks
 #
 
 obj-y			:= intel_cacheinfo.o addon_cpuid_features.o
@@ -16,11 +16,13 @@ obj-$(CONFIG_CPU_SUP_CENTAUR_64)	+= centaur_64.o
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32)	+= transmeta.o
 obj-$(CONFIG_CPU_SUP_UMC_32)		+= umc.o
 
-obj-$(CONFIG_X86_MCE)	+= mcheck/
-obj-$(CONFIG_MTRR)	+= mtrr/
-obj-$(CONFIG_CPU_FREQ)	+= cpufreq/
+obj-$(CONFIG_PERF_COUNTERS)		+= perf_counter.o
 
-obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o
+obj-$(CONFIG_X86_MCE)			+= mcheck/
+obj-$(CONFIG_MTRR)			+= mtrr/
+obj-$(CONFIG_CPU_FREQ)			+= cpufreq/
+
+obj-$(CONFIG_X86_LOCAL_APIC)		+= perfctr-watchdog.o
 
 quiet_cmd_mkcapflags = MKCAP   $@
       cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@
arch/x86/kernel/cpu/common.c +2 -0
index b9c9ea0..ad331b4 100644
@@ -17,6 +17,7 @@
 #include <asm/mmu_context.h>
 #include <asm/mtrr.h>
 #include <asm/mce.h>
+#include <asm/perf_counter.h>
 #include <asm/pat.h>
 #include <asm/asm.h>
 #include <asm/numa.h>
@@ -750,6 +751,7 @@ void __init identify_boot_cpu(void)
 #else
 	vgetcpu_set_mode();
 #endif
+	init_hw_perf_counters();
 }
 
 void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)
arch/x86/kernel/cpu/perf_counter.c new file +705 -0

705 lines not on this page · raw message

arch/x86/kernel/cpu/perfctr-watchdog.c +1 -1
index 9abd48b..d6f5b9f 100644
@@ -20,7 +20,7 @@
 #include <linux/kprobes.h>
 
 #include <asm/apic.h>
-#include <asm/intel_arch_perfmon.h>
+#include <asm/perf_counter.h>
 
 struct nmi_watchdog_ctlblk {
 	unsigned int cccr_msr;
arch/x86/kernel/entry_32.S +249 -228

532 lines not on this page · raw message

arch/x86/kernel/entry_64.S +729 -634

524 lines not on this page · raw message

arch/x86/kernel/irq.c +5 -0
index d1d4dc5..d92bc71 100644

Lines of this file are not shown. View the raw message.

arch/x86/kernel/irq_64.c +10 -14
index 60eb84e..1d3d0e7 100644

Lines of this file are not shown. View the raw message.

arch/x86/kernel/irqinit_32.c +4 -1
index 845aa98..6a33b5e 100644

Lines of this file are not shown. View the raw message.

arch/x86/kernel/irqinit_64.c +5 -66

71 lines not on this page · raw message

arch/x86/kernel/signal.c renamed from arch/x86/kernel/signal_32.c +388 -186

574 lines not on this page · raw message

arch/x86/kernel/signal_64.c deleted +0 -516

516 lines not on this page · raw message

arch/x86/kernel/smp.c +3 -15
index 18f9b19..d18537c 100644

Lines of this file are not shown. View the raw message.

arch/x86/kernel/syscall_table_32.S +1 -0
index d44395f..496726d 100644

Lines of this file are not shown. View the raw message.

arch/x86/kernel/time_64.c +2 -0
index cb19d65..418a095 100644

Lines of this file are not shown. View the raw message.

arch/x86/kernel/traps.c +1 -5
index 04d242a..d815293 100644

Lines of this file are not shown. View the raw message.

arch/x86/kernel/vsyscall_64.c +9 -0
index 0b8b669..ebf2f12 100644

Lines of this file are not shown. View the raw message.

arch/x86/lguest/boot.c +2 -1
index a5d8e1a..50a7792 100644

Lines of this file are not shown. View the raw message.

arch/x86/mm/init_32.c +2 -0
index c483f42..3ffed25 100644

Lines of this file are not shown. View the raw message.

arch/x86/oprofile/op_model_ppro.c +1 -1
index e9f80c7..07c9145 100644

Lines of this file are not shown. View the raw message.

drivers/acpi/processor_idle.c +8 -0
index 5f8d746..a3e66a3 100644

Lines of this file are not shown. View the raw message.

drivers/char/sysrq.c +2 -0
index ce0d9da..52146c2 100644

Lines of this file are not shown. View the raw message.

fs/exec.c +8 -0
index ec5df9a..d5165d8 100644

Lines of this file are not shown. View the raw message.

include/linux/init_task.h +11 -0
index 23fd890..467cff5 100644

Lines of this file are not shown. View the raw message.

include/linux/kernel_stat.h +8 -0
index 4a145ca..1b2e324 100644

Lines of this file are not shown. View the raw message.

include/linux/linkage.h +0 -8
index 9fd1f85..fee9e59 100644

Lines of this file are not shown. View the raw message.

include/linux/perf_counter.h new file +254 -0

254 lines not on this page · raw message

include/linux/prctl.h +3 -0
index 48d887e..b00df4c 100644

Lines of this file are not shown. View the raw message.

include/linux/sched.h +11 -1
index 55e30d1..2e15be8 100644

Lines of this file are not shown. View the raw message.

include/linux/syscalls.h +8 -0
index 04fb47b..a549678 100644

Lines of this file are not shown. View the raw message.

init/Kconfig +30 -0
index f763762..7d147a3 100644

Lines of this file are not shown. View the raw message.

kernel/Makefile +1 -0
index 19fad00..1f184a1 100644

Lines of this file are not shown. View the raw message.

kernel/exit.c +9 -4
index 2d8be7e..101b7ee 100644

Lines of this file are not shown. View the raw message.

kernel/fork.c +1 -0
index 495da2e..e207860 100644

Lines of this file are not shown. View the raw message.

kernel/perf_counter.c new file +1686 -0

1,686 lines not on this page · raw message

kernel/sched.c +73 -3

76 lines not on this page · raw message

kernel/sys.c +7 -0
index 31deba8..0f66633 100644

Lines of this file are not shown. View the raw message.

kernel/sys_ni.c +3 -0
index e14a232..4be8bbc 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

#1 lore raw

Hi Ingo,

Currently, -tip tree can't build on my ia64 box.
because..

Quoted 8 lines
 create mode 100644 Documentation/perf-counters.txt
 delete mode 100644 arch/x86/include/asm/intel_arch_perfmon.h
 create mode 100644 arch/x86/include/asm/perf_counter.h
 create mode 100644 arch/x86/kernel/cpu/perf_counter.c
 rename arch/x86/kernel/{signal_32.c => signal.c} (74%)
 delete mode 100644 arch/x86/kernel/signal_64.c
 create mode 100644 include/linux/perf_counter.h
 create mode 100644 kernel/perf_counter.c

Only x86 has <asm/perf_counter.h>.

Quoted 14 lines
include/linux/perf_counter.h new file +8 -0
new file mode 100644
index 0000000..ec77d16
@@ -0,0 +1,254 @@
+/*
+ *  Performance counters:
+ *
+ *   Copyright(C) 2008, Thomas Gleixner <[email protected]>
+ *   Copyright(C) 2008, Red Hat, Inc., Ingo Molnar
+ *
+ *  Data type definitions, declarations, prototypes.
+ *

include/linux/perf_counter.h line 18

Quoted 10 lines
include/linux/perf_counter.h new file +10 -0
+ *  Started by: Thomas Gleixner and Ingo Molnar
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+#ifndef _LINUX_PERF_COUNTER_H
+#define _LINUX_PERF_COUNTER_H
+
+#include <asm/atomic.h>
+#include <asm/perf_counter.h>
+

<linux/perf_counter.h> depend on <asm/perf_counter.h>.

include/linux/sched.h struct sched_param { · line 77

Quoted 12 lines
include/linux/sched.h +1 -0
index 55e30d1..2e15be8 100644
@@ -71,6 +71,7 @@ struct sched_param {
 #include <linux/fs_struct.h>
 #include <linux/compiler.h>
 #include <linux/completion.h>
+#include <linux/perf_counter.h>
 #include <linux/pid.h>
 #include <linux/percpu.h>
 #include <linux/topology.h>

<linux/sched.h> depend on <linux/perf_counter.h>

Oops, sched.h depend on <asm/perf_counter.h>, but non x86 doesn't have it.

#2 lore raw
Quoted 15 lines · KOSAKI Motohiro

Hi Ingo,

Currently, -tip tree can't build on my ia64 box.
because..

Quoted 8 lines
 create mode 100644 Documentation/perf-counters.txt
 delete mode 100644 arch/x86/include/asm/intel_arch_perfmon.h
 create mode 100644 arch/x86/include/asm/perf_counter.h
 create mode 100644 arch/x86/kernel/cpu/perf_counter.c
 rename arch/x86/kernel/{signal_32.c => signal.c} (74%)
 delete mode 100644 arch/x86/kernel/signal_64.c
 create mode 100644 include/linux/perf_counter.h
 create mode 100644 kernel/perf_counter.c
Quoted 1 line

Only x86 has <asm/perf_counter.h>.

thanks - the fix below resolves it, right?

Ingo

Quoted 1 line

From 26c6f31fe04454177513b8b8539e8197ff897703 Mon Sep 17 00:00:00 2001

From: Ingo Molnar <[email protected]>
Date: Thu, 25 Dec 2008 09:02:11 +0100
Subject: [PATCH] perfcounters: include asm/perf_counter.h only if CONFIG_PERF_COUNTERS=y

Impact: build fix on ia64

KOSAKI Motohiro reported that -tip doesnt build on ia64 because asm/perf_counter.h only exists on x86 for now. Fix it.

---
 include/linux/perf_counter.h |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
include/linux/perf_counter.h +4 -1
index ec77d16..cc3a75a 100644
@@ -14,7 +14,10 @@
 #define _LINUX_PERF_COUNTER_H
 
 #include <asm/atomic.h>
-#include <asm/perf_counter.h>
+
+#ifdef CONFIG_PERF_COUNTERS
+# include <asm/perf_counter.h>
+#endif
 
 #include <linux/list.h>
 #include <linux/mutex.h>
Acked-by Tested-by
#3 lore raw
Quoted 18 lines · KOSAKI Motohiro
Quoted 16 lines

Hi Ingo,

Currently, -tip tree can't build on my ia64 box.
because..

Quoted 8 lines
 create mode 100644 Documentation/perf-counters.txt
 delete mode 100644 arch/x86/include/asm/intel_arch_perfmon.h
 create mode 100644 arch/x86/include/asm/perf_counter.h
 create mode 100644 arch/x86/kernel/cpu/perf_counter.c
 rename arch/x86/kernel/{signal_32.c => signal.c} (74%)
 delete mode 100644 arch/x86/kernel/signal_64.c
 create mode 100644 include/linux/perf_counter.h
 create mode 100644 kernel/perf_counter.c
Quoted 5 lines
Quoted 1 line

Only x86 has <asm/perf_counter.h>.

thanks - the fix below resolves it, right?

Ingo

ok.
Now, my box boot successfully.

thanks.