diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-20 18:54:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-20 18:54:37 -0400 |
commit | 467f9957d9283be40101d7255d06fae7e211ff4c (patch) | |
tree | 71d155ab52b3a78bc88d0c8088b09b3c37f9357a /arch | |
parent | 78f28b7c555359c67c2a0d23f7436e915329421e (diff) | |
parent | cdf8073d6b2c6c5a3cd6ce0e6c1297157f7f99ba (diff) |
Merge branch 'perfcounters-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perfcounters-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (58 commits)
perf_counter: Fix perf_copy_attr() pointer arithmetic
perf utils: Use a define for the maximum length of a trace event
perf: Add timechart help text and add timechart to "perf help"
tracing, x86, cpuidle: Move the end point of a C state in the power tracer
perf utils: Be consistent about minimum text size in the svghelper
perf timechart: Add "perf timechart record"
perf: Add the timechart tool
perf: Add a SVG helper library file
tracing, perf: Convert the power tracer into an event tracer
perf: Add a sample_event type to the event_union
perf: Allow perf utilities to have "callback" options without arguments
perf: Store trace event name/id pairs in perf.data
perf: Add a timestamp to fork events
sched_clock: Make it NMI safe
perf_counter: Fix up swcounter throttling
x86, perf_counter, bts: Optimize BTS overflow handling
perf sched: Add --input=file option to builtin-sched.c
perf trace: Sample timestamp and cpu when using record flag
perf tools: Increase MAX_EVENT_LENGTH
perf tools: Fix memory leak in read_ftrace_printk()
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_counter.c | 60 | ||||
-rw-r--r-- | arch/x86/kernel/process.c | 25 |
3 files changed, 45 insertions, 47 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 7bb676c533aa..7d5c3b0ea8da 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/cpufreq.h> | 33 | #include <linux/cpufreq.h> |
34 | #include <linux/compiler.h> | 34 | #include <linux/compiler.h> |
35 | #include <linux/dmi.h> | 35 | #include <linux/dmi.h> |
36 | #include <trace/power.h> | 36 | #include <trace/events/power.h> |
37 | 37 | ||
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
@@ -72,8 +72,6 @@ static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); | |||
72 | 72 | ||
73 | static DEFINE_PER_CPU(struct aperfmperf, old_perf); | 73 | static DEFINE_PER_CPU(struct aperfmperf, old_perf); |
74 | 74 | ||
75 | DEFINE_TRACE(power_mark); | ||
76 | |||
77 | /* acpi_perf_data is a pointer to percpu data. */ | 75 | /* acpi_perf_data is a pointer to percpu data. */ |
78 | static struct acpi_processor_performance *acpi_perf_data; | 76 | static struct acpi_processor_performance *acpi_perf_data; |
79 | 77 | ||
@@ -332,7 +330,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
332 | unsigned int next_perf_state = 0; /* Index into perf table */ | 330 | unsigned int next_perf_state = 0; /* Index into perf table */ |
333 | unsigned int i; | 331 | unsigned int i; |
334 | int result = 0; | 332 | int result = 0; |
335 | struct power_trace it; | ||
336 | 333 | ||
337 | dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); | 334 | dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); |
338 | 335 | ||
@@ -364,7 +361,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
364 | } | 361 | } |
365 | } | 362 | } |
366 | 363 | ||
367 | trace_power_mark(&it, POWER_PSTATE, next_perf_state); | 364 | trace_power_frequency(POWER_PSTATE, data->freq_table[next_state].frequency); |
368 | 365 | ||
369 | switch (data->cpu_feature) { | 366 | switch (data->cpu_feature) { |
370 | case SYSTEM_INTEL_MSR_CAPABLE: | 367 | case SYSTEM_INTEL_MSR_CAPABLE: |
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 2732e2c1e4d3..dbdf712fae9e 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c | |||
@@ -36,10 +36,10 @@ static u64 perf_counter_mask __read_mostly; | |||
36 | #define BTS_RECORD_SIZE 24 | 36 | #define BTS_RECORD_SIZE 24 |
37 | 37 | ||
38 | /* The size of a per-cpu BTS buffer in bytes: */ | 38 | /* The size of a per-cpu BTS buffer in bytes: */ |
39 | #define BTS_BUFFER_SIZE (BTS_RECORD_SIZE * 1024) | 39 | #define BTS_BUFFER_SIZE (BTS_RECORD_SIZE * 2048) |
40 | 40 | ||
41 | /* The BTS overflow threshold in bytes from the end of the buffer: */ | 41 | /* The BTS overflow threshold in bytes from the end of the buffer: */ |
42 | #define BTS_OVFL_TH (BTS_RECORD_SIZE * 64) | 42 | #define BTS_OVFL_TH (BTS_RECORD_SIZE * 128) |
43 | 43 | ||
44 | 44 | ||
45 | /* | 45 | /* |
@@ -1488,8 +1488,7 @@ void perf_counter_print_debug(void) | |||
1488 | local_irq_restore(flags); | 1488 | local_irq_restore(flags); |
1489 | } | 1489 | } |
1490 | 1490 | ||
1491 | static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc, | 1491 | static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc) |
1492 | struct perf_sample_data *data) | ||
1493 | { | 1492 | { |
1494 | struct debug_store *ds = cpuc->ds; | 1493 | struct debug_store *ds = cpuc->ds; |
1495 | struct bts_record { | 1494 | struct bts_record { |
@@ -1498,8 +1497,11 @@ static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc, | |||
1498 | u64 flags; | 1497 | u64 flags; |
1499 | }; | 1498 | }; |
1500 | struct perf_counter *counter = cpuc->counters[X86_PMC_IDX_FIXED_BTS]; | 1499 | struct perf_counter *counter = cpuc->counters[X86_PMC_IDX_FIXED_BTS]; |
1501 | unsigned long orig_ip = data->regs->ip; | ||
1502 | struct bts_record *at, *top; | 1500 | struct bts_record *at, *top; |
1501 | struct perf_output_handle handle; | ||
1502 | struct perf_event_header header; | ||
1503 | struct perf_sample_data data; | ||
1504 | struct pt_regs regs; | ||
1503 | 1505 | ||
1504 | if (!counter) | 1506 | if (!counter) |
1505 | return; | 1507 | return; |
@@ -1510,19 +1512,38 @@ static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc, | |||
1510 | at = (struct bts_record *)(unsigned long)ds->bts_buffer_base; | 1512 | at = (struct bts_record *)(unsigned long)ds->bts_buffer_base; |
1511 | top = (struct bts_record *)(unsigned long)ds->bts_index; | 1513 | top = (struct bts_record *)(unsigned long)ds->bts_index; |
1512 | 1514 | ||
1515 | if (top <= at) | ||
1516 | return; | ||
1517 | |||
1513 | ds->bts_index = ds->bts_buffer_base; | 1518 | ds->bts_index = ds->bts_buffer_base; |
1514 | 1519 | ||
1520 | |||
1521 | data.period = counter->hw.last_period; | ||
1522 | data.addr = 0; | ||
1523 | regs.ip = 0; | ||
1524 | |||
1525 | /* | ||
1526 | * Prepare a generic sample, i.e. fill in the invariant fields. | ||
1527 | * We will overwrite the from and to address before we output | ||
1528 | * the sample. | ||
1529 | */ | ||
1530 | perf_prepare_sample(&header, &data, counter, ®s); | ||
1531 | |||
1532 | if (perf_output_begin(&handle, counter, | ||
1533 | header.size * (top - at), 1, 1)) | ||
1534 | return; | ||
1535 | |||
1515 | for (; at < top; at++) { | 1536 | for (; at < top; at++) { |
1516 | data->regs->ip = at->from; | 1537 | data.ip = at->from; |
1517 | data->addr = at->to; | 1538 | data.addr = at->to; |
1518 | 1539 | ||
1519 | perf_counter_output(counter, 1, data); | 1540 | perf_output_sample(&handle, &header, &data, counter); |
1520 | } | 1541 | } |
1521 | 1542 | ||
1522 | data->regs->ip = orig_ip; | 1543 | perf_output_end(&handle); |
1523 | data->addr = 0; | ||
1524 | 1544 | ||
1525 | /* There's new data available. */ | 1545 | /* There's new data available. */ |
1546 | counter->hw.interrupts++; | ||
1526 | counter->pending_kill = POLL_IN; | 1547 | counter->pending_kill = POLL_IN; |
1527 | } | 1548 | } |
1528 | 1549 | ||
@@ -1552,13 +1573,9 @@ static void x86_pmu_disable(struct perf_counter *counter) | |||
1552 | x86_perf_counter_update(counter, hwc, idx); | 1573 | x86_perf_counter_update(counter, hwc, idx); |
1553 | 1574 | ||
1554 | /* Drain the remaining BTS records. */ | 1575 | /* Drain the remaining BTS records. */ |
1555 | if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) { | 1576 | if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) |
1556 | struct perf_sample_data data; | 1577 | intel_pmu_drain_bts_buffer(cpuc); |
1557 | struct pt_regs regs; | ||
1558 | 1578 | ||
1559 | data.regs = ®s; | ||
1560 | intel_pmu_drain_bts_buffer(cpuc, &data); | ||
1561 | } | ||
1562 | cpuc->counters[idx] = NULL; | 1579 | cpuc->counters[idx] = NULL; |
1563 | clear_bit(idx, cpuc->used_mask); | 1580 | clear_bit(idx, cpuc->used_mask); |
1564 | 1581 | ||
@@ -1619,7 +1636,6 @@ static int p6_pmu_handle_irq(struct pt_regs *regs) | |||
1619 | int idx, handled = 0; | 1636 | int idx, handled = 0; |
1620 | u64 val; | 1637 | u64 val; |
1621 | 1638 | ||
1622 | data.regs = regs; | ||
1623 | data.addr = 0; | 1639 | data.addr = 0; |
1624 | 1640 | ||
1625 | cpuc = &__get_cpu_var(cpu_hw_counters); | 1641 | cpuc = &__get_cpu_var(cpu_hw_counters); |
@@ -1644,7 +1660,7 @@ static int p6_pmu_handle_irq(struct pt_regs *regs) | |||
1644 | if (!x86_perf_counter_set_period(counter, hwc, idx)) | 1660 | if (!x86_perf_counter_set_period(counter, hwc, idx)) |
1645 | continue; | 1661 | continue; |
1646 | 1662 | ||
1647 | if (perf_counter_overflow(counter, 1, &data)) | 1663 | if (perf_counter_overflow(counter, 1, &data, regs)) |
1648 | p6_pmu_disable_counter(hwc, idx); | 1664 | p6_pmu_disable_counter(hwc, idx); |
1649 | } | 1665 | } |
1650 | 1666 | ||
@@ -1665,13 +1681,12 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
1665 | int bit, loops; | 1681 | int bit, loops; |
1666 | u64 ack, status; | 1682 | u64 ack, status; |
1667 | 1683 | ||
1668 | data.regs = regs; | ||
1669 | data.addr = 0; | 1684 | data.addr = 0; |
1670 | 1685 | ||
1671 | cpuc = &__get_cpu_var(cpu_hw_counters); | 1686 | cpuc = &__get_cpu_var(cpu_hw_counters); |
1672 | 1687 | ||
1673 | perf_disable(); | 1688 | perf_disable(); |
1674 | intel_pmu_drain_bts_buffer(cpuc, &data); | 1689 | intel_pmu_drain_bts_buffer(cpuc); |
1675 | status = intel_pmu_get_status(); | 1690 | status = intel_pmu_get_status(); |
1676 | if (!status) { | 1691 | if (!status) { |
1677 | perf_enable(); | 1692 | perf_enable(); |
@@ -1702,7 +1717,7 @@ again: | |||
1702 | 1717 | ||
1703 | data.period = counter->hw.last_period; | 1718 | data.period = counter->hw.last_period; |
1704 | 1719 | ||
1705 | if (perf_counter_overflow(counter, 1, &data)) | 1720 | if (perf_counter_overflow(counter, 1, &data, regs)) |
1706 | intel_pmu_disable_counter(&counter->hw, bit); | 1721 | intel_pmu_disable_counter(&counter->hw, bit); |
1707 | } | 1722 | } |
1708 | 1723 | ||
@@ -1729,7 +1744,6 @@ static int amd_pmu_handle_irq(struct pt_regs *regs) | |||
1729 | int idx, handled = 0; | 1744 | int idx, handled = 0; |
1730 | u64 val; | 1745 | u64 val; |
1731 | 1746 | ||
1732 | data.regs = regs; | ||
1733 | data.addr = 0; | 1747 | data.addr = 0; |
1734 | 1748 | ||
1735 | cpuc = &__get_cpu_var(cpu_hw_counters); | 1749 | cpuc = &__get_cpu_var(cpu_hw_counters); |
@@ -1754,7 +1768,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs) | |||
1754 | if (!x86_perf_counter_set_period(counter, hwc, idx)) | 1768 | if (!x86_perf_counter_set_period(counter, hwc, idx)) |
1755 | continue; | 1769 | continue; |
1756 | 1770 | ||
1757 | if (perf_counter_overflow(counter, 1, &data)) | 1771 | if (perf_counter_overflow(counter, 1, &data, regs)) |
1758 | amd_pmu_disable_counter(hwc, idx); | 1772 | amd_pmu_disable_counter(hwc, idx); |
1759 | } | 1773 | } |
1760 | 1774 | ||
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 071166a4ba83..847ab4160315 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/pm.h> | 9 | #include <linux/pm.h> |
10 | #include <linux/clockchips.h> | 10 | #include <linux/clockchips.h> |
11 | #include <linux/random.h> | 11 | #include <linux/random.h> |
12 | #include <trace/power.h> | 12 | #include <trace/events/power.h> |
13 | #include <asm/system.h> | 13 | #include <asm/system.h> |
14 | #include <asm/apic.h> | 14 | #include <asm/apic.h> |
15 | #include <asm/syscalls.h> | 15 | #include <asm/syscalls.h> |
@@ -25,9 +25,6 @@ EXPORT_SYMBOL(idle_nomwait); | |||
25 | 25 | ||
26 | struct kmem_cache *task_xstate_cachep; | 26 | struct kmem_cache *task_xstate_cachep; |
27 | 27 | ||
28 | DEFINE_TRACE(power_start); | ||
29 | DEFINE_TRACE(power_end); | ||
30 | |||
31 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | 28 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) |
32 | { | 29 | { |
33 | *dst = *src; | 30 | *dst = *src; |
@@ -299,9 +296,7 @@ static inline int hlt_use_halt(void) | |||
299 | void default_idle(void) | 296 | void default_idle(void) |
300 | { | 297 | { |
301 | if (hlt_use_halt()) { | 298 | if (hlt_use_halt()) { |
302 | struct power_trace it; | 299 | trace_power_start(POWER_CSTATE, 1); |
303 | |||
304 | trace_power_start(&it, POWER_CSTATE, 1); | ||
305 | current_thread_info()->status &= ~TS_POLLING; | 300 | current_thread_info()->status &= ~TS_POLLING; |
306 | /* | 301 | /* |
307 | * TS_POLLING-cleared state must be visible before we | 302 | * TS_POLLING-cleared state must be visible before we |
@@ -314,7 +309,6 @@ void default_idle(void) | |||
314 | else | 309 | else |
315 | local_irq_enable(); | 310 | local_irq_enable(); |
316 | current_thread_info()->status |= TS_POLLING; | 311 | current_thread_info()->status |= TS_POLLING; |
317 | trace_power_end(&it); | ||
318 | } else { | 312 | } else { |
319 | local_irq_enable(); | 313 | local_irq_enable(); |
320 | /* loop is done by the caller */ | 314 | /* loop is done by the caller */ |
@@ -372,9 +366,7 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); | |||
372 | */ | 366 | */ |
373 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) | 367 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) |
374 | { | 368 | { |
375 | struct power_trace it; | 369 | trace_power_start(POWER_CSTATE, (ax>>4)+1); |
376 | |||
377 | trace_power_start(&it, POWER_CSTATE, (ax>>4)+1); | ||
378 | if (!need_resched()) { | 370 | if (!need_resched()) { |
379 | if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) | 371 | if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) |
380 | clflush((void *)¤t_thread_info()->flags); | 372 | clflush((void *)¤t_thread_info()->flags); |
@@ -384,15 +376,13 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx) | |||
384 | if (!need_resched()) | 376 | if (!need_resched()) |
385 | __mwait(ax, cx); | 377 | __mwait(ax, cx); |
386 | } | 378 | } |
387 | trace_power_end(&it); | ||
388 | } | 379 | } |
389 | 380 | ||
390 | /* Default MONITOR/MWAIT with no hints, used for default C1 state */ | 381 | /* Default MONITOR/MWAIT with no hints, used for default C1 state */ |
391 | static void mwait_idle(void) | 382 | static void mwait_idle(void) |
392 | { | 383 | { |
393 | struct power_trace it; | ||
394 | if (!need_resched()) { | 384 | if (!need_resched()) { |
395 | trace_power_start(&it, POWER_CSTATE, 1); | 385 | trace_power_start(POWER_CSTATE, 1); |
396 | if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) | 386 | if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) |
397 | clflush((void *)¤t_thread_info()->flags); | 387 | clflush((void *)¤t_thread_info()->flags); |
398 | 388 | ||
@@ -402,7 +392,6 @@ static void mwait_idle(void) | |||
402 | __sti_mwait(0, 0); | 392 | __sti_mwait(0, 0); |
403 | else | 393 | else |
404 | local_irq_enable(); | 394 | local_irq_enable(); |
405 | trace_power_end(&it); | ||
406 | } else | 395 | } else |
407 | local_irq_enable(); | 396 | local_irq_enable(); |
408 | } | 397 | } |
@@ -414,13 +403,11 @@ static void mwait_idle(void) | |||
414 | */ | 403 | */ |
415 | static void poll_idle(void) | 404 | static void poll_idle(void) |
416 | { | 405 | { |
417 | struct power_trace it; | 406 | trace_power_start(POWER_CSTATE, 0); |
418 | |||
419 | trace_power_start(&it, POWER_CSTATE, 0); | ||
420 | local_irq_enable(); | 407 | local_irq_enable(); |
421 | while (!need_resched()) | 408 | while (!need_resched()) |
422 | cpu_relax(); | 409 | cpu_relax(); |
423 | trace_power_end(&it); | 410 | trace_power_end(0); |
424 | } | 411 | } |
425 | 412 | ||
426 | /* | 413 | /* |