public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Lin Ming <ming.m.lin@intel.com>
To: Stephane Eranian <eranian@google.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Ingo Molnar <mingo@elte.hu>, Andi Kleen <andi@firstfloor.org>,
	lkml <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 -tip] perf: x86, add SandyBridge support
Date: Tue, 01 Mar 2011 16:45:41 +0800	[thread overview]
Message-ID: <1298969141.4937.94.camel@minggr.sh.intel.com> (raw)
In-Reply-To: <AANLkTi=eUnZqT3MF7Y8ONrnGh-7MoZJsefisWFR10p7d@mail.gmail.com>

On Tue, 2011-03-01 at 15:43 +0800, Stephane Eranian wrote:
> On Mon, Feb 28, 2011 at 10:15 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> > On Mon, 2011-02-28 at 15:22 +0800, Lin Ming wrote:
> >> This patch adds basic SandyBridge support, including hardware cache
> >> events and PEBS events support.
> >>
> >> LLC-* hareware cache events don't work for now, it depends on the
> >> offcore patches.
> >
> > What's the status of those, Stephane reported some problems last I
> > remember?
> >
> I tried the trick I mentioned and it seems to work.
> 
> Something like below with hwc->extra_alloc.
> Could probably find a better name for that field.

Stephane,

I'll integrate below changes to the offcore patches, OK?

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index f152930..ac1d100 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -906,7 +906,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
 	int free_slot;
 	int found;
 
-	if (!x86_pmu.percore_constraints)
+	if (!x86_pmu.percore_constraints || hwc->extra_alloc)
 		return NULL;
 
 	for (c = x86_pmu.percore_constraints; c->cmask; c++) {
@@ -931,6 +931,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
 				if (hwc->extra_config == era->extra_config) {
 					era->ref++;
 					cpuc->percore_used = 1;
+					hwc->extra_alloc = 1;
 					c = NULL;
 				}
 				/* else conflict */
@@ -945,6 +946,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
 			era->extra_reg = hwc->extra_reg;
 			era->extra_config = hwc->extra_config;
 			cpuc->percore_used = 1;
+			hwc->extra_alloc = 1;
 			c = NULL;
 		}
 		raw_spin_unlock(&pc->lock);
@@ -998,6 +1000,7 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
 			    era->extra_config == hwc->extra_config &&
 			    era->extra_reg == er->msr) {
 				era->ref--;
+				hwc->extra_alloc = 0;
 				break;
 			}
 		}
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f531ce3..dbbf33a 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -546,6 +546,7 @@ struct hw_perf_event {
 			int		last_cpu;
 			unsigned int	extra_reg;
 			u64		extra_config;
+			int		extra_alloc;
 		};
 		struct { /* software */
 			struct hrtimer	hrtimer;


> 
> static struct event_constraint *
> intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
> {
>         struct hw_perf_event *hwc = &event->hw;
>         unsigned int e = hwc->config & ARCH_PERFMON_EVENTSEL_EVENT;
>         struct event_constraint *c;
>         struct intel_percore *pc;
>         struct er_account *era;
>         int i;
>         int free_slot;
>         int found;
> 
>         if (!x86_pmu.percore_constraints)
>                 return NULL;
> 
>         if (hwc->extra_alloc)
>                 return NULL;
> 
>         for (c = x86_pmu.percore_constraints; c->cmask; c++) {
>                 if (e != c->code)
>                         continue;
> 
>                 /*
>                  * Allocate resource per core.
>                  */
>                 c = NULL;
>                 pc = cpuc->per_core;
>                 if (!pc)
>                         break;
>                 c = &emptyconstraint;
>                 raw_spin_lock(&pc->lock);
>                 free_slot = -1;
>                 found = 0;
>                 for (i = 0; i < MAX_EXTRA_REGS; i++) {
>                         era = &pc->regs[i];
>                         if (era->ref > 0 && hwc->extra_reg == era->extra_reg) {
>                                 /* Allow sharing same config */
>                                 if (hwc->extra_config == era->extra_config) {
>                                         era->ref++;
>                                         cpuc->percore_used = 1;
>                                         hwc->extra_alloc = 1;
>                                         c = NULL;
>                                 }
>                                 /* else conflict */
>                                 found = 1;
>                                 break;
>                         } else if (era->ref == 0 && free_slot == -1)
>                                 free_slot = i;
>                 }
>                 if (!found && free_slot != -1) {
>                         era = &pc->regs[free_slot];
>                         era->ref = 1;
>                         era->extra_reg = hwc->extra_reg;
>                         era->extra_config = hwc->extra_config;
>                         cpuc->percore_used = 1;
>                         hwc->extra_alloc = 1;
>                         c = NULL;
>                 }
>                 raw_spin_unlock(&pc->lock);
>                 return c;
>         }
> 
>         return NULL;
> }
> 
> static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
>                                         struct perf_event *event)
> {
>         struct extra_reg *er;
>         struct intel_percore *pc;
>         struct er_account *era;
>         struct hw_perf_event *hwc = &event->hw;
>         int i, allref;
> 
>         if (!cpuc->percore_used)
>                 return;
> 
>         for (er = x86_pmu.extra_regs; er->msr; er++) {
>                 if (er->event != (hwc->config & er->config_mask))
>                         continue;
> 
>                 pc = cpuc->per_core;
>                 raw_spin_lock(&pc->lock);
>                 for (i = 0; i < MAX_EXTRA_REGS; i++) {
>                         era = &pc->regs[i];
>                         if (era->ref > 0 &&
>                             era->extra_config == hwc->extra_config &&
>                             era->extra_reg == er->msr) {
>                                 era->ref--;
>                                 hwc->extra_alloc = 0;
>                                 break;
>                         }
>                 }
>                 allref = 0;
>                 for (i = 0; i < MAX_EXTRA_REGS; i++)
>                         allref += pc->regs[i].ref;
>                 if (allref == 0)
>                         cpuc->percore_used = 0;
>                 raw_spin_unlock(&pc->lock);
>                 break;
>         }
> }
> 
> >
> >>  #define INTEL_EVENT_CONSTRAINT(c, n) \
> >>       EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
> >> +#define INTEL_EVENT_CONSTRAINT2(c, n)        \
> >> +     EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
> >
> > That's a particularly bad name, how about something like
> >
> > INTEL_UEVENT_CONSTRAINT or somesuch.
> >
> >> @@ -702,7 +738,13 @@ static void intel_ds_init(void)
> >>                       printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
> >>                       x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
> >>                       x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
> >> -                     x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
> >> +                     switch (boot_cpu_data.x86_model) {
> >> +                     case 42: /* SandyBridge */
> >> +                             x86_pmu.pebs_constraints = intel_snb_pebs_events;
> >> +                             break;
> >> +                     default:
> >> +                             x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
> >> +                     }
> >>                       break;
> >>
> >>               default:
> >
> > We already have this massive model switch right after this function,
> > might as well move the pebs constraint assignment there.
> >



  parent reply	other threads:[~2011-03-01  8:45 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-28  7:22 [PATCH v2 -tip] perf: x86, add SandyBridge support Lin Ming
2011-02-28  8:20 ` Stephane Eranian
2011-02-28  8:51   ` Lin Ming
2011-02-28  9:02     ` Stephane Eranian
2011-02-28 14:03       ` Lin Ming
2011-02-28 14:28         ` Lin Ming
2011-02-28  9:08     ` Ingo Molnar
2011-02-28 14:02       ` Lin Ming
2011-02-28 14:13         ` Stephane Eranian
2011-02-28  9:15 ` Peter Zijlstra
2011-02-28 12:25   ` Stephane Eranian
2011-02-28 14:33     ` Lin Ming
2011-02-28 14:43       ` Stephane Eranian
2011-02-28 14:52         ` Lin Ming
2011-02-28 14:55           ` Stephane Eranian
2011-02-28 14:21   ` Lin Ming
2011-02-28 14:24     ` Peter Zijlstra
2011-02-28 14:45       ` Lin Ming
2011-02-28 14:46         ` Stephane Eranian
2011-02-28 14:56   ` Lin Ming
2011-02-28 15:11     ` Peter Zijlstra
2011-03-01  0:32       ` Lin Ming
2011-03-01  7:43   ` Stephane Eranian
2011-03-01  8:21     ` Lin Ming
2011-03-01  8:45     ` Lin Ming [this message]
2011-03-01  8:57       ` Stephane Eranian
2011-03-01  9:39         ` Stephane Eranian
2011-03-01 15:07           ` Lin Ming
2011-03-01 15:09             ` Stephane Eranian
2011-03-01 15:18               ` Lin Ming

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=1298969141.4937.94.camel@minggr.sh.intel.com \
    --to=ming.m.lin@intel.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=andi@firstfloor.org \
    --cc=eranian@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /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