Performance Counters for Linux, v5
Subsystems (12)
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.cDocumentation/perf-counters.txt new file +147 -0
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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/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
include/linux/perf_counter.h new file +254 -0
254 lines not on this page · 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
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.
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.cOnly x86 has <asm/perf_counter.h>.
Quoted 14 lines
include/linux/perf_counter.h new file +8
-0@@ -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@@ -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.
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
26c6f31fe04454177513b8b8539e8197ff897703Mon 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
@@ -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>
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.