kernel-ark/kernel
Stephane Eranian 90151c35b1 perf_events: Fix event scheduling issues introduced by transactional API
The transactional API patch between the generic and model-specific
code introduced several important bugs with event scheduling, at
least on X86. If you had pinned events, e.g., watchdog,  and were
over-committing the PMU, you would get bogus counts. The bug was
showing up on Intel CPU because events would move around more
often that on AMD. But the problem also existed on AMD, though
harder to expose.

The issues were:

 - group_sched_in() was missing a cancel_txn() in the error path

 - cpuc->n_added was not properly maintained, leading to missing
   actions in hw_perf_enable(), i.e., n_running being 0. You cannot
   update n_added until you know the transaction has succeeded. In
   case of failed transaction n_added was not adjusted back.

 - in case of failed transactions, event_sched_out() was called
   and eventually invoked x86_disable_event() to touch the HW reg.
   But with transactions, on X86, event_sched_in() does not touch
   HW registers, it simply collects events into a list. Thus, you
   could end up calling x86_disable_event() on a counter which
   did not correspond to the current event when idx != -1.

The patch modifies the generic and X86 code to avoid all those problems.

First, we keep track of the number of events added last. In case the
transaction fails, we substract them from n_added. This approach is
necessary (as opposed to delaying updates to n_added) because not all
event updates use the transaction API, e.g., single events.

Second, we encapsulate the event_sched_in() and event_sched_out() in
group_sched_in() inside the transaction. That makes the operations
symmetrical and you can also detect that you are inside a transaction
and skip the HW reg access by checking cpuc->group_flag.

With this patch, you can now overcommit the PMU even with pinned
system-wide events present and still get valid counts.

Signed-off-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1274796225.5882.1389.camel@twins>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-05-31 08:46:10 +02:00
..
debug x86, kgdb, init: Add early and late debug states 2010-05-20 21:04:29 -05:00
gcov
irq genirq: Clear CPU mask in affinity_hint when none is provided 2010-05-12 11:23:34 +02:00
power PM / Hibernate: Fix block_io.c printk warning 2010-05-10 23:08:18 +02:00
time Merge branch 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2010-05-19 17:11:10 -07:00
trace perf_events, trace: Fix perf_trace_destroy(), mutex went missing 2010-05-31 08:46:09 +02:00
.gitignore
acct.c Merge branch 'next' into for-linus 2010-05-18 08:57:00 +10:00
async.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
audit_tree.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
audit_watch.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
audit.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
audit.h
auditfilter.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
auditsc.c audit: preface audit printk with audit 2010-04-05 13:19:45 -07:00
backtracetest.c
bounds.c kbuild: move bounds.h to include/generated 2009-12-12 13:08:14 +01:00
capability.c sched: Remove remaining USER_SCHED code 2010-04-02 20:12:00 +02:00
cgroup_freezer.c Freezer / cgroup freezer: Update stale locking comments 2010-05-10 23:18:47 +02:00
cgroup.c cgroups: make cftype.unregister_event() void-returning 2010-05-27 09:12:44 -07:00
compat.c cpumask: fix compat getaffinity 2010-05-19 11:48:18 -07:00
configs.c
cpu.c CPU: Avoid using unititialized error variable in disable_nonboot_cpus() 2010-05-30 09:06:00 -07:00
cpuset.c cpusets: new round-robin rotor for SLAB allocations 2010-05-27 09:12:44 -07:00
cred.c umh: creds: kill subprocess_info->cred logic 2010-05-27 09:12:45 -07:00
delayacct.c
dma.c
early_res.c x86: Do not free zero sized per cpu areas 2010-03-29 18:55:40 +02:00
elfcore.c elf coredump: add extended numbering support 2010-03-06 11:26:46 -08:00
exec_domain.c
exit.c proc: turn signal_struct->count into "int nr_threads" 2010-05-27 09:12:47 -07:00
extable.c
fork.c Revert "cpusets: randomize node rotor used in cpuset_mem_spread_node()" 2010-05-30 09:00:03 -07:00
freezer.c
futex_compat.c futex: Protect pid lookup in compat code with RCU 2009-12-09 14:22:14 +01:00
futex.c futex: Handle futex value corruption gracefully 2010-02-03 15:13:22 +01:00
groups.c security: remove dead hook task_setgroups 2010-04-12 12:19:18 +10:00
hrtimer.c hrtimer: Avoid double seqlock 2010-05-26 16:15:37 +02:00
hung_task.c
hw_breakpoint.c hw_breakpoints: Fix percpu build failure 2010-05-04 08:39:36 +02:00
itimer.c
kallsyms.c kdb: core for kgdb back end (2 of 2) 2010-05-20 21:04:21 -05:00
Kconfig.freezer
Kconfig.hz
Kconfig.locks mutex: Better control mutex adaptive spinning config 2009-12-03 11:50:11 +01:00
Kconfig.preempt
kexec.c kexec: fix OOPS in crash_kernel_shrink 2010-05-11 17:33:42 -07:00
kfifo.c kfifo: Don't use integer as NULL pointer 2010-02-16 15:11:08 -08:00
kmod.c call_usermodehelper: UMH_WAIT_EXEC ignores kernel_thread() failure 2010-05-27 09:12:45 -07:00
kprobes.c kprobes: Move enable/disable_kprobe() out from debugfs code 2010-05-08 18:08:30 +02:00
ksysfs.c sysfs: add struct file* to bin_attr callbacks 2010-05-21 09:37:31 -07:00
kthread.c cpuset: fix the problem that cpuset_mem_spread_node() returns an offline node 2010-03-24 16:31:21 -07:00
latencytop.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
lockdep_internals.h lockdep: No need to disable preemption in debug atomic ops 2010-05-04 05:38:16 +02:00
lockdep_proc.c lockstat: Make lockstat counting per cpu 2010-04-06 00:15:37 +02:00
lockdep_states.h
lockdep.c lockdep: Add novalidate class for dev->mutex conversion 2010-05-21 09:37:30 -07:00
Makefile Move kernel/kgdb.c to kernel/debug/debug_core.c 2010-05-20 21:04:18 -05:00
module.c Revert "module: drop the lock while waiting for module to complete initialization." 2010-05-25 16:48:30 -07:00
mutex-debug.c
mutex-debug.h locking: Implement new raw_spinlock 2009-12-14 23:55:32 +01:00
mutex.c mutex: Fix optimistic spinning vs. BKL 2010-05-19 08:18:44 +02:00
mutex.h
notifier.c sched: Use lockdep-based checking on rcu_dereference() 2010-02-25 10:34:26 +01:00
ns_cgroup.c
nsproxy.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
padata.c kernel/: convert cpu notifier to return encapsulate errno value 2010-05-27 09:12:48 -07:00
panic.c panic: call console_verbose() in panic 2010-05-27 09:12:53 -07:00
params.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2010-03-12 16:04:50 -08:00
perf_event.c perf_events: Fix event scheduling issues introduced by transactional API 2010-05-31 08:46:10 +02:00
pid_namespace.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
pid.c pids: increase pid_max based on num_possible_cpus 2010-05-27 09:12:51 -07:00
pm_qos_params.c PM: PM QOS update fix 2010-05-17 00:21:03 +02:00
posix-cpu-timers.c posix-cpu-timers: avoid "task->signal != NULL" checks 2010-05-27 09:12:46 -07:00
posix-timers.c posix_timer: Fix error path in timer_create 2010-05-27 22:38:15 +02:00
printk.c printk,kdb: capture printk() when in kdb shell 2010-05-20 21:04:27 -05:00
profile.c numa: in-kernel profiling: use cpu_to_mem() for per cpu allocations 2010-05-27 09:12:57 -07:00
ptrace.c ptrace: PTRACE_GETFDPIC: fix the unsafe usage of child->mm 2010-05-27 09:12:44 -07:00
range.c x86: Change range end to start+size 2010-02-10 17:47:17 -08:00
rcupdate.c rcu: slim down rcutiny by removing rcu_scheduler_active and friends 2010-05-10 11:08:34 -07:00
rcutiny_plugin.h rcu: slim down rcutiny by removing rcu_scheduler_active and friends 2010-05-10 11:08:34 -07:00
rcutiny.c rcu: remove all rcu head initializations, except on_stack initializations 2010-05-11 16:10:47 -07:00
rcutorture.c Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2010-05-18 08:27:54 -07:00
rcutree_plugin.h rcu: remove all rcu head initializations, except on_stack initializations 2010-05-11 16:10:47 -07:00
rcutree_trace.c rcu: reduce the number of spurious RCU_SOFTIRQ invocations 2010-05-10 11:08:35 -07:00
rcutree.c rcu: remove all rcu head initializations, except on_stack initializations 2010-05-11 16:10:47 -07:00
rcutree.h rcu: reduce the number of spurious RCU_SOFTIRQ invocations 2010-05-10 11:08:35 -07:00
relay.c kernel/: convert cpu notifier to return encapsulate errno value 2010-05-27 09:12:48 -07:00
res_counter.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
resource.c resource: shared I/O region support 2010-05-11 12:01:10 -07:00
rtmutex_common.h
rtmutex-debug.c sched: Convert pi_lock to raw_spinlock 2009-12-14 23:55:33 +01:00
rtmutex-debug.h
rtmutex-tester.c
rtmutex.c rtmutes: Convert rtmutex.lock to raw_spinlock 2009-12-14 23:55:33 +01:00
rtmutex.h
rwsem.c
sched_clock.c blkio: fix for modular blk-cgroup build 2010-04-15 08:54:59 +02:00
sched_cpupri.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
sched_cpupri.h sched: Convert cpupri lock to raw_spinlock 2009-12-14 23:55:33 +01:00
sched_debug.c proc_sched_show_task(): use get_nr_threads() 2010-05-27 09:12:47 -07:00
sched_fair.c sched: replace migration_thread with cpu_stop 2010-05-06 18:49:21 +02:00
sched_features.h sched: Remove ASYM_GRAN feature 2010-03-11 18:32:53 +01:00
sched_idletask.c sched: Cure load average vs NO_HZ woes 2010-04-23 11:02:02 +02:00
sched_rt.c sched: Add enqueue/dequeue flags 2010-04-02 20:12:05 +02:00
sched_stats.h
sched.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client 2010-05-30 08:56:39 -07:00
seccomp.c
semaphore.c
signal.c exit: change zap_other_threads() to count sub-threads 2010-05-27 09:12:46 -07:00
slow-work-debugfs.c SLOW_WORK: Move slow_work's proc file to debugfs 2009-12-01 08:20:31 -08:00
slow-work.c slow-work: use get_ref wrapper instead of directly calling get_ref 2010-03-29 09:13:30 -07:00
slow-work.h SLOW_WORK: CONFIG_SLOW_WORK_PROC should be CONFIG_SLOW_WORK_DEBUG 2010-03-29 09:14:47 -07:00
smp.c kernel/: convert cpu notifier to return encapsulate errno value 2010-05-27 09:12:48 -07:00
softirq.c kernel/: convert cpu notifier to return encapsulate errno value 2010-05-27 09:12:48 -07:00
softlockup.c softlockup: Stop spurious softlockup messages due to overflow 2010-03-21 19:30:13 +01:00
spinlock.c locking: Cleanup the name space completely 2009-12-14 23:55:33 +01:00
srcu.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
stacktrace.c
stop_machine.c stop_machine: Move local variable closer to the usage site in cpu_stop_cpu_callback() 2010-05-18 00:17:44 +02:00
sys_ni.c Add generic sys_ipc wrapper 2010-03-12 15:52:32 -08:00
sys.c kmod: add init function to usermodehelper 2010-05-27 09:12:44 -07:00
sysctl_binary.c sysctl: don't use own implementation of hex_to_bin() 2010-05-25 08:07:05 -07:00
sysctl_check.c ipv4 05/05: add sysctl to accept packets with local source addresses 2009-12-03 12:14:38 -08:00
sysctl.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2010-05-25 16:59:51 -07:00
taskstats.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
test_kprobes.c
time.c timekeeping: Fix timezone update 2010-05-24 11:50:38 +02:00
timeconst.pl
timer.c Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2010-05-28 10:16:27 -07:00
tracepoint.c tracing: Let tracepoints have data passed to tracepoint callbacks 2010-05-14 09:50:34 -04:00
tsacct.c mm: clean up mm_counter 2010-03-06 11:26:23 -08:00
uid16.c
up.c
user_namespace.c kref: remove kref_set 2010-05-21 09:37:29 -07:00
user-return-notifier.c core: Clean up user return notifers use of per_cpu 2009-12-02 10:22:59 +01:00
user.c sched: Remove a stale comment 2010-05-10 08:48:39 +02:00
utsname_sysctl.c
utsname.c
wait.c
workqueue.c kernel/: convert cpu notifier to return encapsulate errno value 2010-05-27 09:12:48 -07:00