public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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 ;-)




  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