Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Andi Kleen
> If you want a uarch name, that might be the name of the core
> ( something-cove ... I can't keep track of the names of all the

GoldenCove for Sapphire Rapids/AlderLake.

But keep in mind that they're still different. Kind of like a different
distro with different patches and configuration from the same base kernel
release.

-Andi


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Peter Zijlstra
On Thu, Mar 11, 2021 at 09:09:57PM +, Luck, Tony wrote:
> >> I think the "sapphire_rapids" is the code name for the server platform.
> >
> > If that's really the case, then:
> >
> > #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F
> >
> > is wrong, those things should be uarch name, not platform name. Tony?
> 
> 0x8F is the model number of the CPU that is named Sapphire Rapids that
> goes into the Eagle Stream platform
> 
> If you want a uarch name, that might be the name of the core
> ( something-cove ... I can't keep track of the names of all the
> coves).

uarch names used to be different from that. But looking at wikipedia,
things have gone completely apeshit after skylake :-/

We used to have one microarch and then a laptop,desktop and server sku,
but now each of those has a separately named microarch, so where we had
one new name each year, we now have at least 3. No wonder I've no
sodding clue anymore.

/me stmps off to get a beer to forget all I've seen ...


RE: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Luck, Tony
>> I think the "sapphire_rapids" is the code name for the server platform.
>
> If that's really the case, then:
>
> #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F
>
> is wrong, those things should be uarch name, not platform name. Tony?

0x8F is the model number of the CPU that is named Sapphire Rapids that
goes into the Eagle Stream platform

If you want a uarch name, that might be the name of the core
( something-cove ... I can't keep track of the names of all the
coves). But that would likely lead to different confusion later if that
*cove core is used in some other CPU model number that doesn't
neatly fit into our _X, _L etc. suffix scheme)

-Tony


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Peter Zijlstra
On Thu, Mar 11, 2021 at 03:32:44PM -0500, Liang, Kan wrote:
> I think the "sapphire_rapids" is the code name for the server platform.

If that's really the case, then:

#define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F

is wrong, those things should be uarch name, not platform name. Tony?



Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Peter Zijlstra
On Thu, Mar 11, 2021 at 12:30:53PM -0800, Andi Kleen wrote:

> But what would you do with the information that the core is related
> to some other core.

Reduce mental clutter I suppose... there are simply too many variations
of all this about :-(

> In the end you need to know that Alderlake is Alderlake.

*sigh*, okay.


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Liang, Kan




On 3/11/2021 2:58 PM, Peter Zijlstra wrote:

On Thu, Mar 11, 2021 at 11:53:35AM -0500, Liang, Kan wrote:


The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
PMEM.
The "cpu_atom" PMU is similar to Tremont, but with different
event_constraints, extra_regs and number of counters.



So do these things use the same event lists as SPR and TNT?


No, there will be two new event lists on ADL. One is for Atom core, and the
other is for big core. They are different to SPR and TNT.


*sigh* how different?


The core PMU event list should be similar between SPR and the big core 
of ADL, because they both utilize the Golden Cove core. But the uncore 
PMU event list is totally different for client and server.


The Atom core of ADL utilizes the Gracemont core, which is a successor 
to Tremont. It introduces many new events. We cannot use the Tremont 
event list instead.






My desktop has: cpu/caps/pmu_name and that gives "skylake", do we want
the above to have cpu_core/caps/pmu_name give "sapphire_rapids" etc.. ?



I think current implementation should be good enough.

$ cat /sys/devices/cpu_atom/caps/pmu_name
alderlake_hybrid

"alderlake_hybrid" tells the perf tool that it's Alder Lake Hybrid system.
"cpu_atom" tells the perf tool that it's for Atom core.


Yeah, but then I have to ask Google wth those atoms and cores actually
are. Why not tell me upfront?

Since we're now working on it, we all know, but in 6 months time nobody
will remember and then we'll constantly have to look it up and curse
ourselves for not doing better.


I think the "sapphire_rapids" is the code name for the server platform.
Maybe we should use the code name of core?

$ cat /sys/devices/cpu_atom/caps/pmu_name
gracemont
$ cat /sys/devices/cpu_core/caps/pmu_name
golden_cove


Thanks,
Kan


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Andi Kleen
On Thu, Mar 11, 2021 at 08:58:32PM +0100, Peter Zijlstra wrote:
> On Thu, Mar 11, 2021 at 11:53:35AM -0500, Liang, Kan wrote:
> 
> > > > The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
> > > > PMEM.
> > > > The "cpu_atom" PMU is similar to Tremont, but with different
> > > > event_constraints, extra_regs and number of counters.
> 
> > > So do these things use the same event lists as SPR and TNT?
> > 
> > No, there will be two new event lists on ADL. One is for Atom core, and the
> > other is for big core. They are different to SPR and TNT.
> 
> *sigh* how different?

Atom and Big core event list have significant differences.

Often event lists of the same core in different SOCs are different too
because some events indicate stuff outside the core (e.g. Offcore Response
and others)

> 
> > > Is there any
> > > way to discover that, because AFAICT /proc/cpuinfo will say every CPU
> > > is 'Alderlake', and the above also doesn't give any clue.
> > > 
> > 
> > Ricardo once submitted a patch to expose the CPU type under
> > /sys/devices/system/cpu, but I don't know the latest status.
> > https://lore.kernel.org/lkml/20201003011745.7768-5-ricardo.neri-calde...@linux.intel.com/
> 
> Yeah, but that was useless, it doesn't list the Cores as
> FAM6_SAPPHIRERAPIDS nor the Atom as FAM6_ATOM_TREMONT.

It's Gracemont, not Tremont.

But what would you do with the information that the core is related
to some other core.

The event lists are tied to the Alderlake model number. You cannot
just use event lists from some other part because there are 
differences to other Golden Cove or Gracemont implementations.

For non event list usages, the model numbers also indicate a lot of things
in the SOC, so even you knew it was a somewhat similar core as Sapphire
Rapids, it wouldn't tell the complete story. Even on the cores there are
differences.

In the end you need to know that Alderlake is Alderlake.

-Andi


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Peter Zijlstra
On Thu, Mar 11, 2021 at 11:53:35AM -0500, Liang, Kan wrote:

> > > The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
> > > PMEM.
> > > The "cpu_atom" PMU is similar to Tremont, but with different
> > > event_constraints, extra_regs and number of counters.

> > So do these things use the same event lists as SPR and TNT?
> 
> No, there will be two new event lists on ADL. One is for Atom core, and the
> other is for big core. They are different to SPR and TNT.

*sigh* how different?

> > Is there any
> > way to discover that, because AFAICT /proc/cpuinfo will say every CPU
> > is 'Alderlake', and the above also doesn't give any clue.
> > 
> 
> Ricardo once submitted a patch to expose the CPU type under
> /sys/devices/system/cpu, but I don't know the latest status.
> https://lore.kernel.org/lkml/20201003011745.7768-5-ricardo.neri-calde...@linux.intel.com/

Yeah, but that was useless, it doesn't list the Cores as
FAM6_SAPPHIRERAPIDS nor the Atom as FAM6_ATOM_TREMONT.

> > My desktop has: cpu/caps/pmu_name and that gives "skylake", do we want
> > the above to have cpu_core/caps/pmu_name give "sapphire_rapids" etc.. ?
> > 
> 
> I think current implementation should be good enough.
> 
> $ cat /sys/devices/cpu_atom/caps/pmu_name
> alderlake_hybrid
> 
> "alderlake_hybrid" tells the perf tool that it's Alder Lake Hybrid system.
> "cpu_atom" tells the perf tool that it's for Atom core.

Yeah, but then I have to ask Google wth those atoms and cores actually
are. Why not tell me upfront?

Since we're now working on it, we all know, but in 6 months time nobody
will remember and then we'll constantly have to look it up and curse
ourselves for not doing better.


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Liang, Kan




On 3/11/2021 11:32 AM, Peter Zijlstra wrote:

On Thu, Mar 11, 2021 at 05:09:25PM +0100, Peter Zijlstra wrote:

On Wed, Mar 10, 2021 at 08:37:56AM -0800, kan.li...@linux.intel.com wrote:

From: Kan Liang 

Alder Lake Hybrid system has two different types of core, Golden Cove
core and Gracemont core. The Golden Cove core is registered to
"cpu_core" PMU. The Gracemont core is registered to "cpu_atom" PMU.

The difference between the two PMUs include:
- Number of GP and fixed counters
- Events
- The "cpu_core" PMU supports Topdown metrics.
   The "cpu_atom" PMU supports PEBS-via-PT.

The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
PMEM.
The "cpu_atom" PMU is similar to Tremont, but with different
event_constraints, extra_regs and number of counters.




+   /* Initialize big core specific PerfMon capabilities.*/
+   pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
+   pmu->name = "cpu_core";



+   /* Initialize Atom core specific PerfMon capabilities.*/
+   pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX];
+   pmu->name = "cpu_atom";


So do these things use the same event lists as SPR and TNT? Is there any
way to discover that, because AFAICT /proc/cpuinfo will say every CPU
is 'Alderlake', and the above also doesn't give any clue.

FWIW, ARM big.LITTLE does discriminate in its /proc/cpuinfo, but I'm not
entirely sure it's really useful. Mark said perf userspace uses
somethink akin to our CPUID, except exposed through sysfs, to find the
event lists.

My desktop has: cpu/caps/pmu_name and that gives "skylake", do we want
the above to have cpu_core/caps/pmu_name give "sapphire_rapids" etc.. ?


FWIW, "Tremont" is the only pmu_name with a capital :-( I don't suppose
we can still fix that?



The cpu/caps/pmu_name is not used for the event list.

I don't think perf tool checks the "Tremont". I think it should be OK to 
fix it. Let me post a patch.


Thanks,
Kan


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Liang, Kan




On 3/11/2021 11:53 AM, Liang, Kan wrote:



On 3/11/2021 11:09 AM, Peter Zijlstra wrote:
On Wed, Mar 10, 2021 at 08:37:56AM -0800, kan.li...@linux.intel.com 
wrote:

From: Kan Liang 

Alder Lake Hybrid system has two different types of core, Golden Cove
core and Gracemont core. The Golden Cove core is registered to
"cpu_core" PMU. The Gracemont core is registered to "cpu_atom" PMU.

The difference between the two PMUs include:
- Number of GP and fixed counters
- Events
- The "cpu_core" PMU supports Topdown metrics.
   The "cpu_atom" PMU supports PEBS-via-PT.

The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
PMEM.
The "cpu_atom" PMU is similar to Tremont, but with different
event_constraints, extra_regs and number of counters.




+    /* Initialize big core specific PerfMon capabilities.*/
+    pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
+    pmu->name = "cpu_core";



+    /* Initialize Atom core specific PerfMon capabilities.*/
+    pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX];
+    pmu->name = "cpu_atom";


So do these things use the same event lists as SPR and TNT?


No, there will be two new event lists on ADL. One is for Atom core, and 
the other is for big core. They are different to SPR and TNT.



Is there any
way to discover that, because AFAICT /proc/cpuinfo will say every CPU
is 'Alderlake', and the above also doesn't give any clue.



Ricardo once submitted a patch to expose the CPU type under 
/sys/devices/system/cpu, but I don't know the latest status.
https://lore.kernel.org/lkml/20201003011745.7768-5-ricardo.neri-calde...@linux.intel.com/ 






FWIW, ARM big.LITTLE does discriminate in its /proc/cpuinfo, but I'm not
entirely sure it's really useful. Mark said perf userspace uses
somethink akin to our CPUID, except exposed through sysfs, to find the
event lists.



Ah, I guess I misunderstood the concern. Let me try again.

Here is how perf tool find a event name via event list.

To get the correct event list file, yes, perf tool relies on the CPUID.
It will search a CPUID table in the 
tools/perf/pmu-events/arch/x86/mapfile.csv.

GenuineIntel-6-97,v1,alderlake,core
Now perf tool knows the event list file "alderlake" is for the CPUID 97.

In the event list file for the Alder Lake (CPUID 0x97), we add a new 
field "Unit" to distinguish the type of PMU.

"Unit": "cpu_core"
"Unit": "cpu_atom"

So perf can search the event name for a certain type of PMU via PMU name 
"cpu_core" or "cpu_atom".


Perf tool doesn't use the "cpu_core/caps/pmu_name" for the event list.

Thanks,
Kan


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Liang, Kan




On 3/11/2021 11:09 AM, Peter Zijlstra wrote:

On Wed, Mar 10, 2021 at 08:37:56AM -0800, kan.li...@linux.intel.com wrote:

From: Kan Liang 

Alder Lake Hybrid system has two different types of core, Golden Cove
core and Gracemont core. The Golden Cove core is registered to
"cpu_core" PMU. The Gracemont core is registered to "cpu_atom" PMU.

The difference between the two PMUs include:
- Number of GP and fixed counters
- Events
- The "cpu_core" PMU supports Topdown metrics.
   The "cpu_atom" PMU supports PEBS-via-PT.

The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
PMEM.
The "cpu_atom" PMU is similar to Tremont, but with different
event_constraints, extra_regs and number of counters.




+   /* Initialize big core specific PerfMon capabilities.*/
+   pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
+   pmu->name = "cpu_core";



+   /* Initialize Atom core specific PerfMon capabilities.*/
+   pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX];
+   pmu->name = "cpu_atom";


So do these things use the same event lists as SPR and TNT?


No, there will be two new event lists on ADL. One is for Atom core, and 
the other is for big core. They are different to SPR and TNT.



Is there any
way to discover that, because AFAICT /proc/cpuinfo will say every CPU
is 'Alderlake', and the above also doesn't give any clue.



Ricardo once submitted a patch to expose the CPU type under 
/sys/devices/system/cpu, but I don't know the latest status.

https://lore.kernel.org/lkml/20201003011745.7768-5-ricardo.neri-calde...@linux.intel.com/




FWIW, ARM big.LITTLE does discriminate in its /proc/cpuinfo, but I'm not
entirely sure it's really useful. Mark said perf userspace uses
somethink akin to our CPUID, except exposed through sysfs, to find the
event lists.



Perf tool can use the pmu name.
For perf stat -e cpu_atom/EVENT_NAME/, perf will apply the event list 
for atom.
For perf stat -e cpu_core/EVENT_NAME/, perf will apply the event list 
for the big core.
For perf stat -e EVENT_NAME, perf tool will check if the EVENT_NAME 
exists. If it's available on both event list, perf will automatically 
create two events, perf stat -e cpu_atom/EVENT_NAME/,cpu_core/EVENT_NAME/.
If the event name is only available on a certain type, e.g., atom. The 
perf tool will only apply the corresponding event, e.g., perf stat -e 
cpu_atom/EVENT_NAME/



My desktop has: cpu/caps/pmu_name and that gives "skylake", do we want
the above to have cpu_core/caps/pmu_name give "sapphire_rapids" etc.. ?



I think current implementation should be good enough.

$ cat /sys/devices/cpu_atom/caps/pmu_name
alderlake_hybrid

"alderlake_hybrid" tells the perf tool that it's Alder Lake Hybrid system.
"cpu_atom" tells the perf tool that it's for Atom core.


Thanks,
Kan


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Peter Zijlstra
On Thu, Mar 11, 2021 at 05:09:25PM +0100, Peter Zijlstra wrote:
> On Wed, Mar 10, 2021 at 08:37:56AM -0800, kan.li...@linux.intel.com wrote:
> > From: Kan Liang 
> > 
> > Alder Lake Hybrid system has two different types of core, Golden Cove
> > core and Gracemont core. The Golden Cove core is registered to
> > "cpu_core" PMU. The Gracemont core is registered to "cpu_atom" PMU.
> > 
> > The difference between the two PMUs include:
> > - Number of GP and fixed counters
> > - Events
> > - The "cpu_core" PMU supports Topdown metrics.
> >   The "cpu_atom" PMU supports PEBS-via-PT.
> > 
> > The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
> > PMEM.
> > The "cpu_atom" PMU is similar to Tremont, but with different
> > event_constraints, extra_regs and number of counters.
> > 
> 
> > +   /* Initialize big core specific PerfMon capabilities.*/
> > +   pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
> > +   pmu->name = "cpu_core";
> 
> > +   /* Initialize Atom core specific PerfMon capabilities.*/
> > +   pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX];
> > +   pmu->name = "cpu_atom";
> 
> So do these things use the same event lists as SPR and TNT? Is there any
> way to discover that, because AFAICT /proc/cpuinfo will say every CPU
> is 'Alderlake', and the above also doesn't give any clue.
> 
> FWIW, ARM big.LITTLE does discriminate in its /proc/cpuinfo, but I'm not
> entirely sure it's really useful. Mark said perf userspace uses
> somethink akin to our CPUID, except exposed through sysfs, to find the
> event lists.
> 
> My desktop has: cpu/caps/pmu_name and that gives "skylake", do we want
> the above to have cpu_core/caps/pmu_name give "sapphire_rapids" etc.. ?

FWIW, "Tremont" is the only pmu_name with a capital :-( I don't suppose
we can still fix that?


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Peter Zijlstra
On Wed, Mar 10, 2021 at 08:37:56AM -0800, kan.li...@linux.intel.com wrote:
> From: Kan Liang 
> 
> Alder Lake Hybrid system has two different types of core, Golden Cove
> core and Gracemont core. The Golden Cove core is registered to
> "cpu_core" PMU. The Gracemont core is registered to "cpu_atom" PMU.
> 
> The difference between the two PMUs include:
> - Number of GP and fixed counters
> - Events
> - The "cpu_core" PMU supports Topdown metrics.
>   The "cpu_atom" PMU supports PEBS-via-PT.
> 
> The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
> PMEM.
> The "cpu_atom" PMU is similar to Tremont, but with different
> event_constraints, extra_regs and number of counters.
> 

> + /* Initialize big core specific PerfMon capabilities.*/
> + pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
> + pmu->name = "cpu_core";

> + /* Initialize Atom core specific PerfMon capabilities.*/
> + pmu = _pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX];
> + pmu->name = "cpu_atom";

So do these things use the same event lists as SPR and TNT? Is there any
way to discover that, because AFAICT /proc/cpuinfo will say every CPU
is 'Alderlake', and the above also doesn't give any clue.

FWIW, ARM big.LITTLE does discriminate in its /proc/cpuinfo, but I'm not
entirely sure it's really useful. Mark said perf userspace uses
somethink akin to our CPUID, except exposed through sysfs, to find the
event lists.

My desktop has: cpu/caps/pmu_name and that gives "skylake", do we want
the above to have cpu_core/caps/pmu_name give "sapphire_rapids" etc.. ?


Re: [PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-11 Thread Peter Zijlstra
On Wed, Mar 10, 2021 at 08:37:56AM -0800, kan.li...@linux.intel.com wrote:
> @@ -4059,6 +4099,34 @@ tfa_get_event_constraints(struct cpu_hw_events *cpuc, 
> int idx,
>   return c;
>  }
>  
> +static struct event_constraint *
> +adl_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
> +   struct perf_event *event)
> +{
> + struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
> +
> + if (pmu->cpu_type == INTEL_HYBRID_TYPE_CORE)
> + return spr_get_event_constraints(cpuc, idx, event);
> + else if (pmu->cpu_type == INTEL_HYBRID_TYPE_ATOM)
> + return tnt_get_event_constraints(cpuc, idx, event);
> +
> + WARN_ON(1);
> + return 
> +}
> +
> +static int adl_hw_config(struct perf_event *event)
> +{
> + struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
> +
> + if (pmu->cpu_type == INTEL_HYBRID_TYPE_CORE)
> + return hsw_hw_config(event);
> + else if (pmu->cpu_type == INTEL_HYBRID_TYPE_ATOM)
> + return intel_pmu_hw_config(event);
> +
> + WARN_ON(1);
> + return -EOPNOTSUPP;
> +}
> +
>  /*
>   * Broadwell:
>   *

> @@ -5266,6 +5342,84 @@ static const struct attribute_group *attr_update[] = {
>   NULL,
>  };
>  
> +EVENT_ATTR_STR_HYBRID(slots, slots_hybrid,   
> "event=0x00,umask=0x4", INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(topdown-retiring,  td_retiring_hybrid, 
> "event=0xc2,umask=0x0;event=0x00,umask=0x80", INTEL_HYBRID_TYPE_ATOM 
> | INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(topdown-bad-spec,  td_bad_spec_hybrid, 
> "event=0x73,umask=0x0;event=0x00,umask=0x81", INTEL_HYBRID_TYPE_ATOM 
> | INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(topdown-fe-bound,  td_fe_bound_hybrid, 
> "event=0x71,umask=0x0;event=0x00,umask=0x82", INTEL_HYBRID_TYPE_ATOM 
> | INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(topdown-be-bound,  td_be_bound_hybrid, 
> "event=0x74,umask=0x0;event=0x00,umask=0x83", INTEL_HYBRID_TYPE_ATOM 
> | INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(topdown-heavy-ops, td_heavy_ops_hybrid,
> "event=0x00,umask=0x84", INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(topdown-br-mispredict, td_br_mispredict_hybrid,
> "event=0x00,umask=0x85", INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(topdown-fetch-lat, td_fetch_lat_hybrid,
> "event=0x00,umask=0x86", INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(topdown-mem-bound, td_mem_bound_hybrid,
> "event=0x00,umask=0x87", INTEL_HYBRID_TYPE_CORE);
> +
> +static struct attribute *adl_hybrid_events_attrs[] = {
> + EVENT_PTR(slots_hybrid),
> + EVENT_PTR(td_retiring_hybrid),
> + EVENT_PTR(td_bad_spec_hybrid),
> + EVENT_PTR(td_fe_bound_hybrid),
> + EVENT_PTR(td_be_bound_hybrid),
> + EVENT_PTR(td_heavy_ops_hybrid),
> + EVENT_PTR(td_br_mispredict_hybrid),
> + EVENT_PTR(td_fetch_lat_hybrid),
> + EVENT_PTR(td_mem_bound_hybrid),
> + NULL,
> +};
> +
> +/* Must be in IDX order */
> +EVENT_ATTR_STR_HYBRID(mem-loads, mem_ld_adl_hybrid, 
> "event=0xd0,umask=0x5,ldlat=3;event=0xcd,umask=0x1,ldlat=3", 
> INTEL_HYBRID_TYPE_ATOM | INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(mem-stores, mem_st_adl_hybrid, 
> "event=0xd0,umask=0x6;event=0xcd,umask=0x2", INTEL_HYBRID_TYPE_ATOM | 
> INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(mem-loads-aux, mem_ld_aux_hybrid, 
> "event=0x03,umask=0x82", INTEL_HYBRID_TYPE_CORE);
> +
> +static struct attribute *adl_hybrid_mem_attrs[] = {
> + EVENT_PTR(mem_ld_adl_hybrid),
> + EVENT_PTR(mem_st_adl_hybrid),
> + EVENT_PTR(mem_ld_aux_hybrid),
> + NULL,
> +};
> +
> +EVENT_ATTR_STR_HYBRID(tx-start, tx_start_adl_hybrid, "event=0xc9,umask=0x1", 
> INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(tx-commit, tx_commit_adl_hybrid, 
> "event=0xc9,umask=0x2", INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(tx-abort, tx_abort_adl_hybrid, "event=0xc9,umask=0x4", 
> INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(tx-conflict, tx_conflict_adl_hybrid, 
> "event=0x54,umask=0x1", INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(cycles-t, cycles_t_adl_hybrid, "event=0x3c,in_tx=1", 
> INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(cycles-ct, cycles_ct_adl_hybrid, 
> "event=0x3c,in_tx=1,in_tx_cp=1", INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(tx-capacity-read, tx_capacity_read_adl_hybrid, 
> "event=0x54,umask=0x80", INTEL_HYBRID_TYPE_CORE);
> +EVENT_ATTR_STR_HYBRID(tx-capacity-write, tx_capacity_write_adl_hybrid, 
> "event=0x54,umask=0x2", INTEL_HYBRID_TYPE_CORE);
> +
> +static struct attribute *adl_hybrid_tsx_attrs[] = {
> + EVENT_PTR(tx_start_adl_hybrid),
> + EVENT_PTR(tx_abort_adl_hybrid),
> + EVENT_PTR(tx_commit_adl_hybrid),
> + EVENT_PTR(tx_capacity_read_adl_hybrid),
> + EVENT_PTR(tx_capacity_write_adl_hybrid),
> + 

[PATCH V2 20/25] perf/x86/intel: Add Alder Lake Hybrid support

2021-03-10 Thread kan . liang
From: Kan Liang 

Alder Lake Hybrid system has two different types of core, Golden Cove
core and Gracemont core. The Golden Cove core is registered to
"cpu_core" PMU. The Gracemont core is registered to "cpu_atom" PMU.

The difference between the two PMUs include:
- Number of GP and fixed counters
- Events
- The "cpu_core" PMU supports Topdown metrics.
  The "cpu_atom" PMU supports PEBS-via-PT.

The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without
PMEM.
The "cpu_atom" PMU is similar to Tremont, but with different
event_constraints, extra_regs and number of counters.

The mem-loads AUX event workaround only applies to the Golden Cove core.

Users may disable all CPUs of the same CPU type on the command line or
in the BIOS. For this case, perf still initializes a PMU for the CPU
type, but will not register the PMU. The PMU will only be registered
when any corresponding CPU is online.

Reviewed-by: Andi Kleen 
Signed-off-by: Kan Liang 
---
 arch/x86/events/intel/core.c | 248 ++-
 arch/x86/events/intel/ds.c   |   7 ++
 arch/x86/events/perf_event.h |   7 ++
 3 files changed, 261 insertions(+), 1 deletion(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 8ac948a..568e100 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2076,6 +2076,14 @@ static struct extra_reg intel_tnt_extra_regs[] 
__read_mostly = {
EVENT_EXTRA_END
 };
 
+static struct extra_reg intel_grt_extra_regs[] __read_mostly = {
+   /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+   INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3full, 
RSP_0),
+   INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x3full, 
RSP_1),
+   INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x5d0),
+   EVENT_EXTRA_END
+};
+
 #define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */
 #define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */
 #define KNL_MCDRAM_LOCAL   BIT_ULL(21)
@@ -2430,6 +2438,16 @@ static int icl_set_topdown_event_period(struct 
perf_event *event)
return 0;
 }
 
+static int adl_set_topdown_event_period(struct perf_event *event)
+{
+   struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
+
+   if (pmu->cpu_type != INTEL_HYBRID_TYPE_CORE)
+   return 0;
+
+   return icl_set_topdown_event_period(event);
+}
+
 static inline u64 icl_get_metrics_event_value(u64 metric, u64 slots, int idx)
 {
u32 val;
@@ -2570,6 +2588,17 @@ static u64 icl_update_topdown_event(struct perf_event 
*event)
 x86_pmu.num_topdown_events - 
1);
 }
 
+static u64 adl_update_topdown_event(struct perf_event *event)
+{
+   struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
+
+   if (pmu->cpu_type != INTEL_HYBRID_TYPE_CORE)
+   return 0;
+
+   return icl_update_topdown_event(event);
+}
+
+
 static void intel_pmu_read_topdown_event(struct perf_event *event)
 {
struct cpu_hw_events *cpuc = this_cpu_ptr(_hw_events);
@@ -3658,6 +3687,17 @@ static inline bool is_mem_loads_aux_event(struct 
perf_event *event)
return (event->attr.config & INTEL_ARCH_EVENT_MASK) == 
X86_CONFIG(.event=0x03, .umask=0x82);
 }
 
+static inline bool require_mem_loads_aux_event(struct perf_event *event)
+{
+   if (!(x86_pmu.flags & PMU_FL_MEM_LOADS_AUX))
+   return false;
+
+   if (is_hybrid())
+   return hybrid_pmu(event->pmu)->cpu_type == 
INTEL_HYBRID_TYPE_CORE;
+
+   return true;
+}
+
 static inline bool intel_pmu_has_cap(struct perf_event *event, int idx)
 {
union perf_capabilities *intel_cap;
@@ -3782,7 +3822,7 @@ static int intel_pmu_hw_config(struct perf_event *event)
 * event. The rule is to simplify the implementation of the check.
 * That's because perf cannot have a complete group at the moment.
 */
-   if (x86_pmu.flags & PMU_FL_MEM_LOADS_AUX &&
+   if (require_mem_loads_aux_event(event) &&
(event->attr.sample_type & PERF_SAMPLE_DATA_SRC) &&
is_mem_loads_event(event)) {
struct perf_event *leader = event->group_leader;
@@ -4059,6 +4099,34 @@ tfa_get_event_constraints(struct cpu_hw_events *cpuc, 
int idx,
return c;
 }
 
+static struct event_constraint *
+adl_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event)
+{
+   struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
+
+   if (pmu->cpu_type == INTEL_HYBRID_TYPE_CORE)
+   return spr_get_event_constraints(cpuc, idx, event);
+   else if (pmu->cpu_type == INTEL_HYBRID_TYPE_ATOM)
+   return tnt_get_event_constraints(cpuc, idx, event);
+
+   WARN_ON(1);
+   return 
+}
+
+static int adl_hw_config(struct perf_event *event)
+{
+   struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
+
+   if (pmu->cpu_type ==