linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Yan, Zheng" <zheng.z.yan@intel.com>
To: Stephane Eranian <eranian@google.com>
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
	mingo@elte.hu, andi@firstfloor.org
Subject: Re: [PATCH] perf/x86: fix SNB-EP CBO and PCU uncore PMU filter management
Date: Tue, 21 Aug 2012 16:00:25 +0800	[thread overview]
Message-ID: <50334019.6040803@intel.com> (raw)
In-Reply-To: <20120820162237.GA9295@quad>

On 08/21/2012 12:22 AM, Stephane Eranian wrote:
> The existing code had a bug whereby it would refuse to
> measure two events in a group for either CBO or PCU PMUs,
> if one of the events was using a filter. This was due to
> the fact that the kernel assumed all CBO and PCU events
> were using filters, and thus would detect false positive
> conflicts between attr->config1 values.
>     
> This patch fixes the problem by introducing the extra_reg
> event mapping tables for both CBO and PCU PMUs. Those
> tables associate an event code+umask with extra (filter)
> register. We used the same approach for the offcore_response
> core PMU event.
>     
> With this patch applied, it is possible to measure, for
> instance, CBO unc_c_tor_inserts:opcode:pcirdcur with
> unc_c_clockticks in the same group.

Thank you for fixing this.

> 
> The filter for both CBO and PCU are more complex than what the
> current code support. Each filter is sub-divided into event
> specific filters. For now, we consider the filter as one single
> MSR value. We lose a bit of flexibility and force multiplexing
> when this is not really necessary in HW. We could later create
> the notion of virtual filters that would be aggregated at the
> last step (wrmsrl). But I think this is good enough for now.
> 

Actually there are codes that handle similar case properly. See how
the ZDP_CTL_FVC register is handled in nhmex_mbox_get/put_shared_reg().
Do you like to update this patch or I will update it later.

Acked-by: Yan, Zheng <zheng.z.yan@intel.com>

Regards
Yan, Zheng

> Signed-off-by: Stephane Eranian <eranian@google.com>
> ---
> 
> diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
> index 0a55710..cd2c930 100644
> --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
> +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
> @@ -224,29 +224,86 @@ static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
>  		wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
>  }
>  
> -static int snbep_uncore_hw_config(struct intel_uncore_box *box, struct perf_event *event)
> +static int uncore_pmu_extra_regs(struct intel_uncore_box *box,
> +				 struct perf_event *event)
> +{
> +	struct hw_perf_event_extra *reg;
> +	struct extra_reg *er = box->pmu->type->extra_regs;
> +
> +	if (!er)
> +		return 0;
> +
> +	reg = &event->hw.extra_reg;
> +
> +	for (; er->msr; er++) {
> +		if (er->event != (event->attr.config & er->config_mask))
> +			continue;
> +
> +		if (event->attr.config1 & ~er->valid_mask)
> +			return -EINVAL;
> +
> +		reg->idx = er->idx;
> +		reg->config = event->attr.config1;
> +		reg->reg = er->msr;
> +		break;
> +	}
> +	return 0;
> +}
> +
> +
> +static int snbep_cbo_extra_regs(struct intel_uncore_box *box,
> +				struct perf_event *event)
>  {
> +#define SNBEP_CBO_TIDEN_MASK		(1ULL<< 19)
> +#define SNBEP_CBO_FILT_CIDTID_MASK	0xfULL
> +
>  	struct hw_perf_event *hwc = &event->hw;
> -	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
> +	struct hw_perf_event_extra *reg = &hwc->extra_reg;
> +	u64 config1 = event->attr.config1;
>  
> -	if (box->pmu->type == &snbep_uncore_cbox) {
> -		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
> -			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
> -		reg1->config = event->attr.config1 &
> -			SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK;
> -	} else {
> -		if (box->pmu->type == &snbep_uncore_pcu) {
> -			reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
> -			reg1->config = event->attr.config1 & SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK;
> -		} else {
> -			return 0;
> -		}
> +	/*
> +	 * if extra_reg not set via the snbep_uncore_cbo_extra_regs[]
> +	 * then we need to check whether or not the tid_en bit is set
> +	 * in the config. If so, then we do need to enable the cbo filter
> +	 */
> +	if (reg->idx == EXTRA_REG_NONE
> +	    && (event->attr.config & SNBEP_CBO_TIDEN_MASK)) {
> +		/*
> +		 * validate that only the core-id/thread-id
> +		 * bits are set, otherwise we must go through
> +		 * the snbep_uncore_cbo_extra_regs[] table
> +		 */
> +		if (config1 & ~SNBEP_CBO_FILT_CIDTID_MASK)
> +			return -EINVAL;
> +
> +		reg->idx = 0;
> +		reg->config = config1 & SNBEP_CBO_FILT_CIDTID_MASK;
> +		reg->reg = SNBEP_C0_MSR_PMON_BOX_FILTER;
>  	}
> -	reg1->idx = 0;
> +	/*
> +	 * adjust the cbo index
> +	 */
> +	if (reg->idx != EXTRA_REG_NONE)
> +		reg->reg += SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
>  
>  	return 0;
>  }
>  
> +static int snbep_uncore_hw_config(struct intel_uncore_box *box, struct perf_event *event)
> +{
> +	struct intel_uncore_type *type = box->pmu->type;
> +	int ret;
> +
> +	ret = uncore_pmu_extra_regs(box, event);
> +	if (ret)
> +		return ret;
> +
> +	if (type == &snbep_uncore_cbox)
> +		ret = snbep_cbo_extra_regs(box, event);
> +
> +	return ret;
> +}
> +
>  static struct attribute *snbep_uncore_formats_attr[] = {
>  	&format_attr_event.attr,
>  	&format_attr_umask.attr,
> @@ -444,6 +501,41 @@ static struct intel_uncore_type snbep_uncore_ubox = {
>  	.format_group	= &snbep_uncore_ubox_format_group,
>  };
>  
> +#define CBO_EVENT_EXTRA_REG(a) \
> +	UNC_EXTRA_REG(a, \
> +		      SNBEP_C0_MSR_PMON_BOX_FILTER, \
> +		      ARCH_PERFMON_EVENTSEL_EVENT, \
> +		      SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK, \
> +		      0)
> +
> +#define CBO_EVTUM_EXTRA_REG(a) \
> +	UNC_EXTRA_REG(a, \
> +		      SNBEP_C0_MSR_PMON_BOX_FILTER, \
> +		      INTEL_ARCH_EVENT_MASK, \
> +		      SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK, \
> +		      0)
> +
> +static struct extra_reg snbep_uncore_cbo_extra_regs[] __read_mostly =
> +{
> +	CBO_EVENT_EXTRA_REG(0x0034), /* LLC_LOOKUP */
> +	CBO_EVTUM_EXTRA_REG(0x0135), /* TOR_INSERTS.OPCODE */
> +	CBO_EVTUM_EXTRA_REG(0x0335), /* TOR_INSERTS.MISS_OPCODE */
> +	CBO_EVTUM_EXTRA_REG(0x4135), /* TOR_INSERTS.NID_OPCODE */
> +	CBO_EVTUM_EXTRA_REG(0x4335), /* TOR_INSERTS.NID_MISS_OPCODE */
> +	CBO_EVTUM_EXTRA_REG(0x4435), /* TOR_INSERTS.NID_EVICTION */
> +	CBO_EVTUM_EXTRA_REG(0x4835), /* TOR_INSERTS.NID_ALL */
> +	CBO_EVTUM_EXTRA_REG(0x4a35), /* TOR_INSERTS.NID_MISS_ALL */
> +	CBO_EVTUM_EXTRA_REG(0x5035), /* TOR_INSERTS.NID_WB */
> +	CBO_EVTUM_EXTRA_REG(0x0136), /* TOR_OCCUPANCY.OPCODE */
> +	CBO_EVTUM_EXTRA_REG(0x0336), /* TOR_OCCUPANCY.MISS_OPCODE */
> +	CBO_EVTUM_EXTRA_REG(0x4136), /* TOR_OCCUPANCY.NID_OPCODE */
> +	CBO_EVTUM_EXTRA_REG(0x4336), /* TOR_OCCUPANCY.NID_MISS_OPCODE */
> +	CBO_EVTUM_EXTRA_REG(0x4436), /* TOR_OCCUPANCY.NID_EVICTION */
> +	CBO_EVTUM_EXTRA_REG(0x4836), /* TOR_OCCUPANCY.NID_ALL */
> +	CBO_EVTUM_EXTRA_REG(0x4a36), /* TOR_OCCUPANCY.NID_MISS_ALL */
> +	EVENT_EXTRA_END
> +};
> +
>  static struct intel_uncore_type snbep_uncore_cbox = {
>  	.name			= "cbox",
>  	.num_counters		= 4,
> @@ -458,6 +550,23 @@ static struct intel_uncore_type snbep_uncore_cbox = {
>  	.constraints		= snbep_uncore_cbox_constraints,
>  	.ops			= &snbep_uncore_msr_ops,
>  	.format_group		= &snbep_uncore_cbox_format_group,
> +	.extra_regs		= snbep_uncore_cbo_extra_regs,
> +};
> +
> +#define PCU_EVENT_EXTRA_REG(a) \
> +	UNC_EXTRA_REG(a, \
> +		      SNBEP_PCU_MSR_PMON_BOX_FILTER, \
> +		      ARCH_PERFMON_EVENTSEL_EVENT, \
> +		      0xffffffff, \
> +		      0)
> +
> +static struct extra_reg snbep_uncore_pcu_extra_regs[] __read_mostly =
> +{
> +	PCU_EVENT_EXTRA_REG(0xb), /* FREQ_BAND0_CYCLES */
> +	PCU_EVENT_EXTRA_REG(0xc), /* FREQ_BAND1_CYCLES */
> +	PCU_EVENT_EXTRA_REG(0xd), /* FREQ_BAND2_CYCLES */
> +	PCU_EVENT_EXTRA_REG(0xe), /* FREQ_BAND3_CYCLES */
> +	EVENT_EXTRA_END
>  };
>  
>  static struct intel_uncore_type snbep_uncore_pcu = {
> @@ -472,6 +581,7 @@ static struct intel_uncore_type snbep_uncore_pcu = {
>  	.num_shared_regs	= 1,
>  	.ops			= &snbep_uncore_msr_ops,
>  	.format_group		= &snbep_uncore_pcu_format_group,
> +	.extra_regs		= snbep_uncore_pcu_extra_regs,
>  };
>  
>  static struct intel_uncore_type *snbep_msr_uncores[] = {
> diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
> index 5b81c18..37d8732 100644
> --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
> +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
> @@ -369,6 +369,7 @@ struct intel_uncore_type {
>  	struct intel_uncore_pmu *pmus;
>  	struct intel_uncore_ops *ops;
>  	struct uncore_event_desc *event_descs;
> +	struct extra_reg *extra_regs;
>  	const struct attribute_group *attr_groups[3];
>  };
>  
> @@ -428,6 +429,14 @@ struct uncore_event_desc {
>  	const char *config;
>  };
>  
> +#define UNC_EXTRA_REG(e, ms, m, vm, i) {\
> +	.event = (e),		\
> +	.msr = (ms),		\
> +	.config_mask = (m),	\
> +	.valid_mask = (vm),	\
> +	.idx = i\
> +	}
> +
>  #define INTEL_UNCORE_EVENT_DESC(_name, _config)			\
>  {								\
>  	.attr	= __ATTR(_name, 0444, uncore_event_show, NULL),	\
> 


  reply	other threads:[~2012-08-21  8:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-20 16:22 [PATCH] perf/x86: fix SNB-EP CBO and PCU uncore PMU filter management Stephane Eranian
2012-08-21  8:00 ` Yan, Zheng [this message]
2012-08-21 10:46 ` Peter Zijlstra
2012-08-21 11:45   ` Stephane Eranian
  -- strict thread matches above, loose matches on Subject: below --
2012-10-22  6:02 Yan, Zheng
2012-10-22  6:14 Yan, Zheng

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=50334019.6040803@intel.com \
    --to=zheng.z.yan@intel.com \
    --cc=andi@firstfloor.org \
    --cc=eranian@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=peterz@infradead.org \
    /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;
as well as URLs for NNTP newsgroup(s).