Skip to content

Commit 467f995

Browse files
committed
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() ...
2 parents 78f28b7 + cdf8073 commit 467f995

40 files changed

+4570
-759
lines changed

Documentation/trace/power.txt

Lines changed: 0 additions & 17 deletions
This file was deleted.

arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include <linux/cpufreq.h>
3434
#include <linux/compiler.h>
3535
#include <linux/dmi.h>
36-
#include <trace/power.h>
36+
#include <trace/events/power.h>
3737

3838
#include <linux/acpi.h>
3939
#include <linux/io.h>
@@ -72,8 +72,6 @@ static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
7272

7373
static DEFINE_PER_CPU(struct aperfmperf, old_perf);
7474

75-
DEFINE_TRACE(power_mark);
76-
7775
/* acpi_perf_data is a pointer to percpu data. */
7876
static struct acpi_processor_performance *acpi_perf_data;
7977

@@ -332,7 +330,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
332330
unsigned int next_perf_state = 0; /* Index into perf table */
333331
unsigned int i;
334332
int result = 0;
335-
struct power_trace it;
336333

337334
dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu);
338335

@@ -364,7 +361,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
364361
}
365362
}
366363

367-
trace_power_mark(&it, POWER_PSTATE, next_perf_state);
364+
trace_power_frequency(POWER_PSTATE, data->freq_table[next_state].frequency);
368365

369366
switch (data->cpu_feature) {
370367
case SYSTEM_INTEL_MSR_CAPABLE:

arch/x86/kernel/cpu/perf_counter.c

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ static u64 perf_counter_mask __read_mostly;
3636
#define BTS_RECORD_SIZE 24
3737

3838
/* 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)
4040

4141
/* 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)
4343

4444

4545
/*
@@ -1488,8 +1488,7 @@ void perf_counter_print_debug(void)
14881488
local_irq_restore(flags);
14891489
}
14901490

1491-
static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc,
1492-
struct perf_sample_data *data)
1491+
static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc)
14931492
{
14941493
struct debug_store *ds = cpuc->ds;
14951494
struct bts_record {
@@ -1498,8 +1497,11 @@ static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc,
14981497
u64 flags;
14991498
};
15001499
struct perf_counter *counter = cpuc->counters[X86_PMC_IDX_FIXED_BTS];
1501-
unsigned long orig_ip = data->regs->ip;
15021500
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;
15031505

15041506
if (!counter)
15051507
return;
@@ -1510,19 +1512,38 @@ static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc,
15101512
at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
15111513
top = (struct bts_record *)(unsigned long)ds->bts_index;
15121514

1515+
if (top <= at)
1516+
return;
1517+
15131518
ds->bts_index = ds->bts_buffer_base;
15141519

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, &regs);
1531+
1532+
if (perf_output_begin(&handle, counter,
1533+
header.size * (top - at), 1, 1))
1534+
return;
1535+
15151536
for (; at < top; at++) {
1516-
data->regs->ip = at->from;
1517-
data->addr = at->to;
1537+
data.ip = at->from;
1538+
data.addr = at->to;
15181539

1519-
perf_counter_output(counter, 1, data);
1540+
perf_output_sample(&handle, &header, &data, counter);
15201541
}
15211542

1522-
data->regs->ip = orig_ip;
1523-
data->addr = 0;
1543+
perf_output_end(&handle);
15241544

15251545
/* There's new data available. */
1546+
counter->hw.interrupts++;
15261547
counter->pending_kill = POLL_IN;
15271548
}
15281549

@@ -1552,13 +1573,9 @@ static void x86_pmu_disable(struct perf_counter *counter)
15521573
x86_perf_counter_update(counter, hwc, idx);
15531574

15541575
/* Drain the remaining BTS records. */
1555-
if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
1556-
struct perf_sample_data data;
1557-
struct pt_regs regs;
1576+
if (unlikely(idx == X86_PMC_IDX_FIXED_BTS))
1577+
intel_pmu_drain_bts_buffer(cpuc);
15581578

1559-
data.regs = &regs;
1560-
intel_pmu_drain_bts_buffer(cpuc, &data);
1561-
}
15621579
cpuc->counters[idx] = NULL;
15631580
clear_bit(idx, cpuc->used_mask);
15641581

@@ -1619,7 +1636,6 @@ static int p6_pmu_handle_irq(struct pt_regs *regs)
16191636
int idx, handled = 0;
16201637
u64 val;
16211638

1622-
data.regs = regs;
16231639
data.addr = 0;
16241640

16251641
cpuc = &__get_cpu_var(cpu_hw_counters);
@@ -1644,7 +1660,7 @@ static int p6_pmu_handle_irq(struct pt_regs *regs)
16441660
if (!x86_perf_counter_set_period(counter, hwc, idx))
16451661
continue;
16461662

1647-
if (perf_counter_overflow(counter, 1, &data))
1663+
if (perf_counter_overflow(counter, 1, &data, regs))
16481664
p6_pmu_disable_counter(hwc, idx);
16491665
}
16501666

@@ -1665,13 +1681,12 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
16651681
int bit, loops;
16661682
u64 ack, status;
16671683

1668-
data.regs = regs;
16691684
data.addr = 0;
16701685

16711686
cpuc = &__get_cpu_var(cpu_hw_counters);
16721687

16731688
perf_disable();
1674-
intel_pmu_drain_bts_buffer(cpuc, &data);
1689+
intel_pmu_drain_bts_buffer(cpuc);
16751690
status = intel_pmu_get_status();
16761691
if (!status) {
16771692
perf_enable();
@@ -1702,7 +1717,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
17021717

17031718
data.period = counter->hw.last_period;
17041719

1705-
if (perf_counter_overflow(counter, 1, &data))
1720+
if (perf_counter_overflow(counter, 1, &data, regs))
17061721
intel_pmu_disable_counter(&counter->hw, bit);
17071722
}
17081723

@@ -1729,7 +1744,6 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
17291744
int idx, handled = 0;
17301745
u64 val;
17311746

1732-
data.regs = regs;
17331747
data.addr = 0;
17341748

17351749
cpuc = &__get_cpu_var(cpu_hw_counters);
@@ -1754,7 +1768,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
17541768
if (!x86_perf_counter_set_period(counter, hwc, idx))
17551769
continue;
17561770

1757-
if (perf_counter_overflow(counter, 1, &data))
1771+
if (perf_counter_overflow(counter, 1, &data, regs))
17581772
amd_pmu_disable_counter(hwc, idx);
17591773
}
17601774

arch/x86/kernel/process.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <linux/pm.h>
1010
#include <linux/clockchips.h>
1111
#include <linux/random.h>
12-
#include <trace/power.h>
12+
#include <trace/events/power.h>
1313
#include <asm/system.h>
1414
#include <asm/apic.h>
1515
#include <asm/syscalls.h>
@@ -25,9 +25,6 @@ EXPORT_SYMBOL(idle_nomwait);
2525

2626
struct kmem_cache *task_xstate_cachep;
2727

28-
DEFINE_TRACE(power_start);
29-
DEFINE_TRACE(power_end);
30-
3128
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
3229
{
3330
*dst = *src;
@@ -299,9 +296,7 @@ static inline int hlt_use_halt(void)
299296
void default_idle(void)
300297
{
301298
if (hlt_use_halt()) {
302-
struct power_trace it;
303-
304-
trace_power_start(&it, POWER_CSTATE, 1);
299+
trace_power_start(POWER_CSTATE, 1);
305300
current_thread_info()->status &= ~TS_POLLING;
306301
/*
307302
* TS_POLLING-cleared state must be visible before we
@@ -314,7 +309,6 @@ void default_idle(void)
314309
else
315310
local_irq_enable();
316311
current_thread_info()->status |= TS_POLLING;
317-
trace_power_end(&it);
318312
} else {
319313
local_irq_enable();
320314
/* loop is done by the caller */
@@ -372,9 +366,7 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
372366
*/
373367
void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
374368
{
375-
struct power_trace it;
376-
377-
trace_power_start(&it, POWER_CSTATE, (ax>>4)+1);
369+
trace_power_start(POWER_CSTATE, (ax>>4)+1);
378370
if (!need_resched()) {
379371
if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
380372
clflush((void *)&current_thread_info()->flags);
@@ -384,15 +376,13 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
384376
if (!need_resched())
385377
__mwait(ax, cx);
386378
}
387-
trace_power_end(&it);
388379
}
389380

390381
/* Default MONITOR/MWAIT with no hints, used for default C1 state */
391382
static void mwait_idle(void)
392383
{
393-
struct power_trace it;
394384
if (!need_resched()) {
395-
trace_power_start(&it, POWER_CSTATE, 1);
385+
trace_power_start(POWER_CSTATE, 1);
396386
if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
397387
clflush((void *)&current_thread_info()->flags);
398388

@@ -402,7 +392,6 @@ static void mwait_idle(void)
402392
__sti_mwait(0, 0);
403393
else
404394
local_irq_enable();
405-
trace_power_end(&it);
406395
} else
407396
local_irq_enable();
408397
}
@@ -414,13 +403,11 @@ static void mwait_idle(void)
414403
*/
415404
static void poll_idle(void)
416405
{
417-
struct power_trace it;
418-
419-
trace_power_start(&it, POWER_CSTATE, 0);
406+
trace_power_start(POWER_CSTATE, 0);
420407
local_irq_enable();
421408
while (!need_resched())
422409
cpu_relax();
423-
trace_power_end(&it);
410+
trace_power_end(0);
424411
}
425412

426413
/*

drivers/cpuidle/cpuidle.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/cpuidle.h>
1818
#include <linux/ktime.h>
1919
#include <linux/hrtimer.h>
20+
#include <trace/events/power.h>
2021

2122
#include "cpuidle.h"
2223

@@ -91,6 +92,7 @@ static void cpuidle_idle_call(void)
9192
/* give the governor an opportunity to reflect on the outcome */
9293
if (cpuidle_curr_governor->reflect)
9394
cpuidle_curr_governor->reflect(dev);
95+
trace_power_end(0);
9496
}
9597

9698
/**

0 commit comments

Comments
 (0)