diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 13:38:34 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 13:38:34 -0400 |
| commit | 619297855aa16646246ea4b1f6e05f1b2455c808 (patch) | |
| tree | a07fe1b24c372f5eabf244555db41fdf574c1205 | |
| parent | e16b396ce314b2bcdfe6c173fe075bf8e3432368 (diff) | |
| parent | 1ef1d1c2353967e2d61ecaddf76edfd058a778b4 (diff) | |
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (30 commits)
trace, filters: Initialize the match variable in process_ops() properly
trace, documentation: Fix branch profiling location in debugfs
oprofile, s390: Cleanups
oprofile, s390: Remove hwsampler_files.c and merge it into init.c
perf: Fix tear-down of inherited group events
perf: Reorder & optimize perf_event_context to remove alignment padding on 64 bit builds
perf: Handle stopped state with tracepoints
perf: Fix the software events state check
perf, powerpc: Handle events that raise an exception without overflowing
perf, x86: Use INTEL_*_CONSTRAINT() for all PEBS event constraints
perf, x86: Clean up SandyBridge PEBS events
perf lock: Fix sorting by wait_min
perf tools: Version incorrect with some versions of grep
perf evlist: New command to list the names of events present in a perf.data file
perf script: Add support for H/W and S/W events
perf script: Add support for dumping symbols
perf script: Support custom field selection for output
perf script: Move printing of 'common' data from print_event and rename
perf tracing: Remove print_graph_cpu and print_graph_proc from trace-event-parse
perf script: Change process_event prototype
...
41 files changed, 2240 insertions, 296 deletions
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 1bc6a12f3725..7e4abebe76c0 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
| @@ -892,6 +892,7 @@ | |||
| 892 | #define PV_970 0x0039 | 892 | #define PV_970 0x0039 |
| 893 | #define PV_POWER5 0x003A | 893 | #define PV_POWER5 0x003A |
| 894 | #define PV_POWER5p 0x003B | 894 | #define PV_POWER5p 0x003B |
| 895 | #define PV_POWER7 0x003F | ||
| 895 | #define PV_970FX 0x003C | 896 | #define PV_970FX 0x003C |
| 896 | #define PV_630 0x0040 | 897 | #define PV_630 0x0040 |
| 897 | #define PV_630p 0x0041 | 898 | #define PV_630p 0x0041 |
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index ab6f6beadb57..97e0ae414940 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c | |||
| @@ -1269,6 +1269,28 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs) | |||
| 1269 | return ip; | 1269 | return ip; |
| 1270 | } | 1270 | } |
| 1271 | 1271 | ||
| 1272 | static bool pmc_overflow(unsigned long val) | ||
| 1273 | { | ||
| 1274 | if ((int)val < 0) | ||
| 1275 | return true; | ||
| 1276 | |||
| 1277 | /* | ||
| 1278 | * Events on POWER7 can roll back if a speculative event doesn't | ||
| 1279 | * eventually complete. Unfortunately in some rare cases they will | ||
| 1280 | * raise a performance monitor exception. We need to catch this to | ||
| 1281 | * ensure we reset the PMC. In all cases the PMC will be 256 or less | ||
| 1282 | * cycles from overflow. | ||
| 1283 | * | ||
| 1284 | * We only do this if the first pass fails to find any overflowing | ||
| 1285 | * PMCs because a user might set a period of less than 256 and we | ||
| 1286 | * don't want to mistakenly reset them. | ||
| 1287 | */ | ||
| 1288 | if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256)) | ||
| 1289 | return true; | ||
| 1290 | |||
| 1291 | return false; | ||
| 1292 | } | ||
| 1293 | |||
| 1272 | /* | 1294 | /* |
| 1273 | * Performance monitor interrupt stuff | 1295 | * Performance monitor interrupt stuff |
| 1274 | */ | 1296 | */ |
| @@ -1316,7 +1338,7 @@ static void perf_event_interrupt(struct pt_regs *regs) | |||
| 1316 | if (is_limited_pmc(i + 1)) | 1338 | if (is_limited_pmc(i + 1)) |
| 1317 | continue; | 1339 | continue; |
| 1318 | val = read_pmc(i + 1); | 1340 | val = read_pmc(i + 1); |
| 1319 | if ((int)val < 0) | 1341 | if (pmc_overflow(val)) |
| 1320 | write_pmc(i + 1, 0); | 1342 | write_pmc(i + 1, 0); |
| 1321 | } | 1343 | } |
| 1322 | } | 1344 | } |
diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile index 537b2d840e69..d698cddcfbdd 100644 --- a/arch/s390/oprofile/Makefile +++ b/arch/s390/oprofile/Makefile | |||
| @@ -6,4 +6,4 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ | |||
| 6 | oprofilefs.o oprofile_stats.o \ | 6 | oprofilefs.o oprofile_stats.o \ |
| 7 | timer_int.o ) | 7 | timer_int.o ) |
| 8 | 8 | ||
| 9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o | 9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o hwsampler.o |
diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c new file mode 100644 index 000000000000..3d48f4db246d --- /dev/null +++ b/arch/s390/oprofile/hwsampler.c | |||
| @@ -0,0 +1,1256 @@ | |||
| 1 | /** | ||
| 2 | * arch/s390/oprofile/hwsampler.c | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2010 | ||
| 5 | * Author: Heinz Graalfs <graalfs@de.ibm.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/smp.h> | ||
| 11 | #include <linux/errno.h> | ||
| 12 | #include <linux/workqueue.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/notifier.h> | ||
| 15 | #include <linux/cpu.h> | ||
| 16 | #include <linux/semaphore.h> | ||
| 17 | #include <linux/oom.h> | ||
| 18 | #include <linux/oprofile.h> | ||
| 19 | |||
| 20 | #include <asm/lowcore.h> | ||
| 21 | #include <asm/s390_ext.h> | ||
| 22 | |||
| 23 | #include "hwsampler.h" | ||
| 24 | |||
| 25 | #define MAX_NUM_SDB 511 | ||
| 26 | #define MIN_NUM_SDB 1 | ||
| 27 | |||
| 28 | #define ALERT_REQ_MASK 0x4000000000000000ul | ||
| 29 | #define BUFFER_FULL_MASK 0x8000000000000000ul | ||
| 30 | |||
| 31 | #define EI_IEA (1 << 31) /* invalid entry address */ | ||
| 32 | #define EI_ISE (1 << 30) /* incorrect SDBT entry */ | ||
| 33 | #define EI_PRA (1 << 29) /* program request alert */ | ||
| 34 | #define EI_SACA (1 << 23) /* sampler authorization change alert */ | ||
| 35 | #define EI_LSDA (1 << 22) /* loss of sample data alert */ | ||
| 36 | |||
| 37 | DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); | ||
| 38 | |||
| 39 | struct hws_execute_parms { | ||
| 40 | void *buffer; | ||
| 41 | signed int rc; | ||
| 42 | }; | ||
| 43 | |||
| 44 | DEFINE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); | ||
| 45 | EXPORT_PER_CPU_SYMBOL(sampler_cpu_buffer); | ||
| 46 | |||
| 47 | static DEFINE_MUTEX(hws_sem); | ||
| 48 | static DEFINE_MUTEX(hws_sem_oom); | ||
| 49 | |||
| 50 | static unsigned char hws_flush_all; | ||
| 51 | static unsigned int hws_oom; | ||
| 52 | static struct workqueue_struct *hws_wq; | ||
| 53 | |||
| 54 | static unsigned int hws_state; | ||
| 55 | enum { | ||
| 56 | HWS_INIT = 1, | ||
| 57 | HWS_DEALLOCATED, | ||
