From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: Markus Metzger <markus.t.metzger@intel.com>
Cc: mingo@elte.hu, tglx@linutronix.de, hpa@zytor.com,
markus.t.metzger@gmail.com, linux-kernel@vger.kernel.org
Subject: Re: [patch] x86, perf_counter, bts: add bts to perf_counter
Date: Tue, 04 Aug 2009 12:24:49 +0200 [thread overview]
Message-ID: <1249381489.7924.186.camel@twins> (raw)
In-Reply-To: <20090721155648.A17047@sedona.ch.intel.com>
On Tue, 2009-07-21 at 15:56 +0200, Markus Metzger wrote:
> Implement a performance counter with:
> attr.type = PERF_TYPE_HARDWARE
> attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS
> attr.sample_period = 1
>
> using branch trace store (BTS) on x86 hardware, if available.
>
> The from and to address for each branch can be sampled using:
> PERF_SAMPLE_IP for the from address
> PERF_SAMPLE_ADDR for the to address
>
Over all looks very nice, some comments below (could be addressed in a
delta patch).
Thanks Markus!
> +static int reserve_bts_hardware(void)
> +{
> + int cpu, err = 0;
> +
> + if (!bts_available())
> + return -EOPNOTSUPP;
> +
> + get_online_cpus();
> +
> + for_each_possible_cpu(cpu) {
> + struct debug_store *ds;
> + void *buffer;
> +
> + err = -ENOMEM;
> + buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
> + if (unlikely(!buffer))
> + break;
> +
> + ds = kzalloc(sizeof(*ds), GFP_KERNEL);
> + if (unlikely(!ds)) {
> + kfree(buffer);
> + break;
> + }
> +
> + ds->bts_buffer_base = (u64)(long)buffer;
> + ds->bts_index = ds->bts_buffer_base;
> + ds->bts_absolute_maximum =
> + ds->bts_buffer_base + BTS_BUFFER_SIZE;
> + ds->bts_interrupt_threshold =
> + ds->bts_absolute_maximum - BTS_OVFL_TH;
> +
> + per_cpu(cpu_hw_counters, cpu).ds = ds;
> + err = 0;
> + }
> +
> + if (err)
> + release_bts_hardware();
> + else
{
> + for_each_online_cpu(cpu)
> + init_debug_store_on_cpu(cpu);
}
> +
> + put_online_cpus();
> +
> + return err;
> +}
> +static void intel_pmu_enable_bts(u64 config)
> +{
> + unsigned long debugctlmsr;
> +
> + debugctlmsr = get_debugctlmsr();
> +
> + debugctlmsr |= (1 << 6);
> + debugctlmsr |= (1 << 7);
> +
> + if (!(config & ARCH_PERFMON_EVENTSEL_OS))
> + debugctlmsr |= (1 << 9);
> +
> + if (!(config & ARCH_PERFMON_EVENTSEL_USR))
> + debugctlmsr |= (1 << 10);
> +
> + update_debugctlmsr(debugctlmsr);
> +}
> +
> +static void intel_pmu_disable_bts(void)
> +{
> + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
> + unsigned long debugctlmsr;
> +
> + if (!cpuc->ds)
> + return;
> +
> + debugctlmsr = get_debugctlmsr();
> +
> + debugctlmsr &= ~(1 << 6);
> + debugctlmsr &= ~(1 << 7);
> + debugctlmsr &= ~(1 << 9);
> + debugctlmsr &= ~(1 << 10);
> +
> + update_debugctlmsr(debugctlmsr);
> +}
It would be good to not use these constants but instead use something
like:
#define X86_DEBUGCTL_TR (1 << 6)
#define X86_DEBUGCTL_BTS (1 << 7)
#define X86_DEBUGCTL_BTS_OS (1 << 9)
#define X86_DEBUGCTL_BTS_USR (1 << 10)
> @@ -1077,11 +1297,16 @@ fixed_mode_idx(struct perf_counter *coun
> {
> unsigned int event;
>
> + event = hwc->config & ARCH_PERFMON_EVENT_MASK;
> +
> + if (unlikely((event ==
> + x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
> + (hwc->sample_period == 1)))
> + return X86_PMC_IDX_FIXED_BTS;
I think we should validate this combination in hw_perf_counter_init()
and fail there if sample_period != 1.
> +static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc,
> + struct perf_sample_data *data)
> +{
> + struct debug_store *ds = cpuc->ds;
> + struct bts_record {
> + u64 from;
> + u64 to;
> + u64 flags;
> + };
> + struct perf_counter *counter = cpuc->counters[X86_PMC_IDX_FIXED_BTS];
> + unsigned long orig_ip = data->regs->ip;
> + u64 at;
> +
> + if (!counter)
> + return;
> +
> + if (!ds)
> + return;
> +
> + for (at = ds->bts_buffer_base;
> + at < ds->bts_index;
> + at += sizeof(struct bts_record)) {
> + struct bts_record *rec = (struct bts_record *)(long)at;
> +
> + data->regs->ip = rec->from;
> + data->addr = rec->to;
> +
> + perf_counter_output(counter, 1, data);
> + }
> +
> + ds->bts_index = ds->bts_buffer_base;
> +
> + data->regs->ip = orig_ip;
> + data->addr = 0;
> +}
You might want to set data->sample_period to 1 as well, just in case
someone is weird enough to request PERF_SAMPLE_PERIOD on a BTS
counter ;-)
next prev parent reply other threads:[~2009-08-04 10:25 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-21 13:56 [patch] x86, perf_counter, bts: add bts to perf_counter Markus Metzger
2009-08-04 10:24 ` Peter Zijlstra [this message]
2009-08-04 11:14 ` Ingo Molnar
2009-08-04 11:35 ` Ingo Molnar
2009-08-05 11:10 ` Metzger, Markus T
2009-08-07 7:29 ` Metzger, Markus T
2009-08-07 8:21 ` Peter Zijlstra
2009-08-07 10:18 ` Metzger, Markus T
2009-08-07 10:29 ` Peter Zijlstra
2009-08-07 12:18 ` Metzger, Markus T
2009-08-07 13:05 ` Peter Zijlstra
2009-08-07 10:31 ` Ingo Molnar
2009-08-07 10:36 ` Ingo Molnar
2009-08-07 10:57 ` Metzger, Markus T
2009-08-07 11:17 ` Metzger, Markus T
2009-08-07 11:24 ` Ingo Molnar
2009-08-07 11:33 ` Ingo Molnar
2009-08-07 17:49 ` [PATCH] perf_counter: Fix a race on perf_counter_ctx Peter Zijlstra
2009-08-08 11:52 ` [tip:perfcounters/core] " tip-bot for Peter Zijlstra
2009-08-08 12:03 ` [PATCH] " Ingo Molnar
2009-08-10 12:33 ` Metzger, Markus T
2009-08-10 12:59 ` Peter Zijlstra
2009-08-10 13:46 ` Ingo Molnar
2009-08-11 6:33 ` Metzger, Markus T
2009-08-11 8:59 ` Metzger, Markus T
2009-08-18 12:49 ` Metzger, Markus T
2009-08-18 12:59 ` Peter Zijlstra
2009-08-18 12:59 ` Peter Zijlstra
2009-08-18 13:20 ` Metzger, Markus T
2009-08-18 13:37 ` Peter Zijlstra
2009-08-18 13:54 ` Metzger, Markus T
2009-08-18 14:00 ` Ingo Molnar
2009-08-18 14:15 ` Metzger, Markus T
2009-08-28 9:56 ` Metzger, Markus T
2009-09-01 11:17 ` [discuss] BTS overflow handling, was: " Metzger, Markus T
2009-09-01 13:00 ` Peter Zijlstra
2009-09-01 13:09 ` Ingo Molnar
2009-09-01 13:32 ` Metzger, Markus T
2009-09-01 13:53 ` Peter Zijlstra
2009-09-01 14:27 ` Metzger, Markus T
2009-09-01 14:35 ` Peter Zijlstra
2009-09-03 14:25 ` Metzger, Markus T
2009-08-18 14:01 ` Peter Zijlstra
2009-08-18 14:19 ` Metzger, Markus T
2009-08-09 11:10 ` [tip:perfcounters/core] " tip-bot for Peter Zijlstra
2009-08-07 11:26 ` [patch] x86, perf_counter, bts: add bts to perf_counter Ingo Molnar
2009-08-07 11:29 ` Ingo Molnar
2009-08-07 12:14 ` Metzger, Markus T
2009-08-07 11:19 ` Ingo Molnar
2009-08-07 11:34 ` Metzger, Markus T
2009-08-07 11:37 ` Metzger, Markus T
2009-08-04 11:37 ` [tip:perfcounters/urgent] x86, perf_counter, bts: Add BTS support to perfcounters tip-bot for Markus Metzger
2009-08-07 10:10 ` [tip:perfcounters/core] " tip-bot for Markus Metzger
2009-08-08 11:43 ` tip-bot for Markus Metzger
2009-08-08 11:53 ` tip-bot for Markus Metzger
-- strict thread matches above, loose matches on Subject: below --
2009-08-07 7:22 [patch] x86, perf_counter, bts: add bts to perf_counter Markus Metzger
2009-08-07 11:45 ` Peter Zijlstra
2009-08-07 11:51 ` Metzger, Markus T
2009-08-07 11:57 ` Peter Zijlstra
2009-08-07 16:39 ` Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1249381489.7924.186.camel@twins \
--to=a.p.zijlstra@chello.nl \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=markus.t.metzger@gmail.com \
--cc=markus.t.metzger@intel.com \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox