diff mbox series

[RFC,5/7] perf pmu: Support matching by sysid

Message ID 1579876505-113251-6-git-send-email-john.garry@huawei.com (mailing list archive)
State New, archived
Headers show
Series perf pmu-events: Support event aliasing for system PMUs | expand

Commit Message

John Garry Jan. 24, 2020, 2:35 p.m. UTC
Match system or uncore PMU aliases by system id, SYSID.

We use a SYSID read from sysfs or from an env variable to match against
uncore or system PMU events.

For x86, they want to match uncore events with cpuid - this still works
fine for x86 as it would not have system event tables for uncore PMUs.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 tools/perf/util/pmu.c | 105 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 94 insertions(+), 11 deletions(-)

Comments

Jiri Olsa Feb. 10, 2020, 12:07 p.m. UTC | #1
On Fri, Jan 24, 2020 at 10:35:03PM +0800, John Garry wrote:

SNIP

> +		fclose(file);
> +		pr_debug("gets failed for file %s\n", path);
> +		free(buf);
> +		return NULL;
> +	}
> +	fclose(file);
> +
> +	/* Remove any whitespace, this could be from ACPI HID */
> +	s = strlen(buf);
> +	for (i = 0; i < s; i++) {
> +		if (buf[i] == ' ') {
> +			buf[i] = 0;
> +			break;
> +		};
> +	}
> +
> +	return buf;
> +}
> +
> +static char *perf_pmu__getsysid(void)
> +{
> +	char *sysid;
> +	static bool printed;
> +
> +	sysid = getenv("PERF_SYSID");
> +	if (sysid)
> +		sysid = strdup(sysid);
> +
> +	if (!sysid)
> +		sysid = get_sysid_str();
> +	if (!sysid)
> +		return NULL;
> +
> +	if (!printed) {
> +		pr_debug("Using SYSID %s\n", sysid);
> +		printed = true;
> +	}
> +	return sysid;
> +}

this part is getting complicated and AFAIK we have no tests for it

if you could think of any tests that'd be great.. perhaps we could
load 'our' json test files and check appropriate events/aliasses
via in pmu object.. or via parse_events interface.. those test aliases
would have to be part of perf, but we have tests compiled in anyway

thanks,
jirka
John Garry Feb. 10, 2020, 4:22 p.m. UTC | #2
Hi jirka,

> 
>> +		fclose(file);
>> +		pr_debug("gets failed for file %s\n", path);
>> +		free(buf);
>> +		return NULL;
>> +	}
>> +	fclose(file);
>> +
>> +	/* Remove any whitespace, this could be from ACPI HID */
>> +	s = strlen(buf);
>> +	for (i = 0; i < s; i++) {
>> +		if (buf[i] == ' ') {
>> +			buf[i] = 0;
>> +			break;
>> +		};
>> +	}
>> +
>> +	return buf;
>> +}
>> +

I have another series to add kernel support for a system identifier 
sysfs entry, which I sent after this series:

https://lore.kernel.org/linux-acpi/1580210059-199540-1-git-send-email-john.garry@huawei.com/

It is different to what I am relying on here - it uses a kernel soc 
driver for firmware ACPI PPTT identifier. Progress is somewhat blocked 
at the moment however and I may have to use a different method:

https://lore.kernel.org/linux-acpi/20200128123415.GB36168@bogus/

>> +static char *perf_pmu__getsysid(void)
>> +{
>> +	char *sysid;
>> +	static bool printed;
>> +
>> +	sysid = getenv("PERF_SYSID");
>> +	if (sysid)
>> +		sysid = strdup(sysid);
>> +
>> +	if (!sysid)
>> +		sysid = get_sysid_str();
>> +	if (!sysid)
>> +		return NULL;
>> +
>> +	if (!printed) {
>> +		pr_debug("Using SYSID %s\n", sysid);
>> +		printed = true;
>> +	}
>> +	return sysid;
>> +}
> 
> this part is getting complicated and AFAIK we have no tests for it
> 
> if you could think of any tests that'd be great.. Perhaps we could
> load 'our' json test files and check appropriate events/aliasses
> via in pmu object.. or via parse_events interface.. those test aliases
> would have to be part of perf, but we have tests compiled in anyway

Sorry, I don't fully follow.

Are you suggesting that we could load the specific JSONs tables for a 
system from the host filesystem?

Thanks,
John
Jiri Olsa Feb. 11, 2020, 1:47 p.m. UTC | #3
On Mon, Feb 10, 2020 at 04:22:56PM +0000, John Garry wrote:
> Hi jirka,
> 
> > 
> > > +		fclose(file);
> > > +		pr_debug("gets failed for file %s\n", path);
> > > +		free(buf);
> > > +		return NULL;
> > > +	}
> > > +	fclose(file);
> > > +
> > > +	/* Remove any whitespace, this could be from ACPI HID */
> > > +	s = strlen(buf);
> > > +	for (i = 0; i < s; i++) {
> > > +		if (buf[i] == ' ') {
> > > +			buf[i] = 0;
> > > +			break;
> > > +		};
> > > +	}
> > > +
> > > +	return buf;
> > > +}
> > > +
> 
> I have another series to add kernel support for a system identifier sysfs
> entry, which I sent after this series:
> 
> https://lore.kernel.org/linux-acpi/1580210059-199540-1-git-send-email-john.garry@huawei.com/
> 
> It is different to what I am relying on here - it uses a kernel soc driver
> for firmware ACPI PPTT identifier. Progress is somewhat blocked at the
> moment however and I may have to use a different method:
> 
> https://lore.kernel.org/linux-acpi/20200128123415.GB36168@bogus/

I'll try to check ;-)

> 
> > > +static char *perf_pmu__getsysid(void)
> > > +{
> > > +	char *sysid;
> > > +	static bool printed;
> > > +
> > > +	sysid = getenv("PERF_SYSID");
> > > +	if (sysid)
> > > +		sysid = strdup(sysid);
> > > +
> > > +	if (!sysid)
> > > +		sysid = get_sysid_str();
> > > +	if (!sysid)
> > > +		return NULL;
> > > +
> > > +	if (!printed) {
> > > +		pr_debug("Using SYSID %s\n", sysid);
> > > +		printed = true;
> > > +	}
> > > +	return sysid;
> > > +}
> > 
> > this part is getting complicated and AFAIK we have no tests for it
> > 
> > if you could think of any tests that'd be great.. Perhaps we could
> > load 'our' json test files and check appropriate events/aliasses
> > via in pmu object.. or via parse_events interface.. those test aliases
> > would have to be part of perf, but we have tests compiled in anyway
> 
> Sorry, I don't fully follow.
> 
> Are you suggesting that we could load the specific JSONs tables for a system
> from the host filesystem?

I wish to see some test for all this.. I can only think about having
'test' json files compiled with perf and 'perf test' that looks them
up and checks that all is in the proper place

jirka
John Garry Feb. 11, 2020, 3:07 p.m. UTC | #4
On 11/02/2020 13:47, Jiri Olsa wrote:

Hi Jirka,

>>>> +
>>>> +	return buf;
>>>> +}
>>>> +
>>
>> I have another series to add kernel support for a system identifier sysfs
>> entry, which I sent after this series:
>>
>> https://lore.kernel.org/linux-acpi/1580210059-199540-1-git-send-email-john.garry@huawei.com/
>>
>> It is different to what I am relying on here - it uses a kernel soc driver
>> for firmware ACPI PPTT identifier. Progress is somewhat blocked at the
>> moment however and I may have to use a different method:
>>
>> https://lore.kernel.org/linux-acpi/20200128123415.GB36168@bogus/
> 
> I'll try to check ;-)

Summary is that there exists an ACPI firmware field which we could 
expose to userspace via sysfs - this would provide the system id. 
However there is a proposal to deprecate it in the ACPI standard and, as 
such, would prefer that we don't add kernel support for it at this stage.

So I am evaluating the alternative in the meantime, which again is some 
firmware method which should allow us to expose a system id to userspace 
via sysfs. Unfortunately this is arm specific. However, other archs can 
still provide their own method, maybe a soc driver:

Documentation/ABI/testing/sysfs-devices-soc#n15

> 
>>
>>>> +static char *perf_pmu__getsysid(void)
>>>> +{
>>>> +	char *sysid;
>>>> +	static bool printed;
>>>> +
>>>> +	sysid = getenv("PERF_SYSID");
>>>> +	if (sysid)
>>>> +		sysid = strdup(sysid);
>>>> +
>>>> +	if (!sysid)
>>>> +		sysid = get_sysid_str();
>>>> +	if (!sysid)
>>>> +		return NULL;
>>>> +
>>>> +	if (!printed) {
>>>> +		pr_debug("Using SYSID %s\n", sysid);
>>>> +		printed = true;
>>>> +	}
>>>> +	return sysid;
>>>> +}
>>>
>>> this part is getting complicated and AFAIK we have no tests for it
>>>
>>> if you could think of any tests that'd be great.. Perhaps we could
>>> load 'our' json test files and check appropriate events/aliasses
>>> via in pmu object.. or via parse_events interface.. those test aliases
>>> would have to be part of perf, but we have tests compiled in anyway
>>
>> Sorry, I don't fully follow.
>>
>> Are you suggesting that we could load the specific JSONs tables for a system
>> from the host filesystem?
> 
> I wish to see some test for all this.. I can only think about having
> 'test' json files compiled with perf and 'perf test' that looks them
> up and checks that all is in the proper place

OK, let me consider this part for perf test support.

Thanks,
John
John Garry Feb. 12, 2020, 10:08 a.m. UTC | #5
On 11/02/2020 15:07, John Garry wrote:
> On 11/02/2020 13:47, Jiri Olsa wrote:
> 
> Hi Jirka,
> 
>>>>> +
>>>>> +    return buf;
>>>>> +}
>>>>> +
>>>
>>> I have another series to add kernel support for a system identifier 
>>> sysfs
>>> entry, which I sent after this series:
>>>
>>> https://lore.kernel.org/linux-acpi/1580210059-199540-1-git-send-email-john.garry@huawei.com/ 
>>>
>>>
>>> It is different to what I am relying on here - it uses a kernel soc 
>>> driver
>>> for firmware ACPI PPTT identifier. Progress is somewhat blocked at the
>>> moment however and I may have to use a different method:
>>>
>>> https://lore.kernel.org/linux-acpi/20200128123415.GB36168@bogus/
>>
>> I'll try to check ;-)
> 
> Summary is that there exists an ACPI firmware field which we could 
> expose to userspace via sysfs - this would provide the system id. 
> However there is a proposal to deprecate it in the ACPI standard and, as 
> such, would prefer that we don't add kernel support for it at this stage.
> 
> So I am evaluating the alternative in the meantime, which again is some 
> firmware method which should allow us to expose a system id to userspace 
> via sysfs. Unfortunately this is arm specific. However, other archs can 
> still provide their own method, maybe a soc driver:
> 
> Documentation/ABI/testing/sysfs-devices-soc#n15
> 
>>
>>>
>>>>> +static char *perf_pmu__getsysid(void)
>>>>> +{
>>>>> +    char *sysid;
>>>>> +    static bool printed;
>>>>> +
>>>>> +    sysid = getenv("PERF_SYSID");
>>>>> +    if (sysid)
>>>>> +        sysid = strdup(sysid);
>>>>> +
>>>>> +    if (!sysid)
>>>>> +        sysid = get_sysid_str();
>>>>> +    if (!sysid)
>>>>> +        return NULL;
>>>>> +
>>>>> +    if (!printed) {
>>>>> +        pr_debug("Using SYSID %s\n", sysid);
>>>>> +        printed = true;
>>>>> +    }
>>>>> +    return sysid;
>>>>> +}
>>>>
>>>> this part is getting complicated and AFAIK we have no tests for it
>>>>
>>>> if you could think of any tests that'd be great.. Perhaps we could
>>>> load 'our' json test files and check appropriate events/aliasses
>>>> via in pmu object.. or via parse_events interface.. those test aliases
>>>> would have to be part of perf, but we have tests compiled in anyway
>>>
>>> Sorry, I don't fully follow.
>>>
>>> Are you suggesting that we could load the specific JSONs tables for a 
>>> system
>>> from the host filesystem?
>>
>> I wish to see some test for all this.. I can only think about having
>> 'test' json files compiled with perf and 'perf test' that looks them
>> up and checks that all is in the proper place
> 
> OK, let me consider this part for perf test support.

I will note that perf test has many issues on my arm64 board:

do] password for john:
  1: vmlinux symtab matches kallsyms                       : Skip
  2: Detect openat syscall event                           : FAILED!
  3: Detect openat syscall event on all cpus               : FAILED!
  4: Read samples using the mmap interface                 : FAILED!
  5: Test data source output                               : Ok
  6: Parse event definition strings                        : FAILED!
  7: Simple expression parser                              : Ok
  8: PERF_RECORD_* events & perf_sample fields             : Ok
  9: Parse perf pmu format                                 : Ok
10: DSO data read                                         : Ok
11: DSO data cache                                        : Ok
12: DSO data reopen                                       : Ok
13: Roundtrip evsel->name                                 : Ok
14: Parse sched tracepoints fields                        : FAILED!
15: syscalls:sys_enter_openat event fields                : FAILED!
16: Setup struct perf_event_attr                          : Skip
17: Match and link multiple hists                         : Ok
18: 'import perf' in python                               : Ok
21: Breakpoint accounting                                 : Ok
22: Watchpoint                                            :
22.1: Read Only Watchpoint                                : Ok
22.2: Write Only Watchpoint                               : Ok
22.3: Read / Write Watchpoint                             : Ok
22.4: Modify Watchpoint                                   : Ok
23: Number of exit events of a simple workload            : Ok
24: Software clock events period values                   : Ok
25: Object code reading                                   : Ok
26: Sample parsing                                        : Ok
27: Use a dummy software event to keep tracking           : Ok
28: Parse with no sample_id_all bit set                   : Ok
29: Filter hist entries                                   : Ok
30: Lookup mmap thread                                    : Ok
31: Share thread maps                                     : Ok
32: Sort output of hist entries                           : Ok
33: Cumulate child hist entries                           : Ok
34: Track with sched_switch                               : Ok
35: Filter fds with revents mask in a fdarray             : Ok
36: Add fd to a fdarray, making it autogrow               : Ok
37: kmod_path__parse                                      : Ok
38: Thread map                                            : Ok
39: LLVM search and compile                               :
39.1: Basic BPF llvm compile                              : Skip
39.2: kbuild searching                                    : Skip
39.3: Compile source for BPF prologue generation          : Skip
39.4: Compile source for BPF relocation                   : Skip
40: Session topology                                      : FAILED!
41: BPF filter                                            :
41.1: Basic BPF filtering                                 : Skip
41.2: BPF pinning                                         : Skip
41.3: BPF prologue generation                             : Skip
41.4: BPF relocation checker                              : Skip
42: Synthesize thread map                                 : Ok
43: Remove thread map                                     : Ok
44: Synthesize cpu map                                    : Ok
45: Synthesize stat config                                : Ok
46: Synthesize stat                                       : Ok
47: Synthesize stat round                                 : Ok
48: Synthesize attr update                                : Ok
49: Event times                                           : Ok
50: Read backward ring buffer                             : FAILED!
51: Print cpu map                                         : Ok
52: Merge cpu map                                         : Ok
53: Probe SDT events                                      : Ok
54: is_printable_array                                    : Ok
55: Print bitmap                                          : Ok
56: perf hooks                          umber__scnprintf 
                : Ok
59: mem2node                                              : Ok
60: time utils                                            : Ok
61: Test jit_write_elf                                    : Ok
62: maps__merge_in                                        : Ok
63: DWARF unwind                                          : Ok
64: Check open filename arg using perf trace + vfs_getname: FAILED!
65: Add vfs_getname probe to get syscall args filenames   : FAILED!
66: Use vfs_getname probe to get syscall args filenames   : FAILED!
67: Zstd perf.data compression/decompression              : Ok
68: probe libc's inet_pton & backtrace it with ping       : Skip
john@ubuntu:~/linux$

I know that the perf tool definitely has issues for system topology for 
arm64, which I need to check on.

Maybe I can conscribe help internally to help check the rest...

Thanks,
john
Jiri Olsa Feb. 12, 2020, 12:16 p.m. UTC | #6
On Wed, Feb 12, 2020 at 10:08:44AM +0000, John Garry wrote:

SNIP

> > > 
> > > I wish to see some test for all this.. I can only think about having
> > > 'test' json files compiled with perf and 'perf test' that looks them
> > > up and checks that all is in the proper place
> > 
> > OK, let me consider this part for perf test support.
> 
> I will note that perf test has many issues on my arm64 board:
> 
> do] password for john:
>  1: vmlinux symtab matches kallsyms                       : Skip
>  2: Detect openat syscall event                           : FAILED!
>  3: Detect openat syscall event on all cpus               : FAILED!
>  4: Read samples using the mmap interface                 : FAILED!
>  5: Test data source output                               : Ok
>  6: Parse event definition strings                        : FAILED!
>  7: Simple expression parser                              : Ok
>  8: PERF_RECORD_* events & perf_sample fields             : Ok
>  9: Parse perf pmu format                                 : Ok
> 10: DSO data read                                         : Ok
> 11: DSO data cache                                        : Ok
> 12: DSO data reopen                                       : Ok
> 13: Roundtrip evsel->name                                 : Ok
> 14: Parse sched tracepoints fields                        : FAILED!
> 15: syscalls:sys_enter_openat event fields                : FAILED!

looks like some issue with tracepoints

> 16: Setup struct perf_event_attr                          : Skip
> 17: Match and link multiple hists                         : Ok
> 18: 'import perf' in python                               : Ok
> 21: Breakpoint accounting                                 : Ok
> 22: Watchpoint                                            :
> 22.1: Read Only Watchpoint                                : Ok
> 22.2: Write Only Watchpoint                               : Ok
> 22.3: Read / Write Watchpoint                             : Ok
> 22.4: Modify Watchpoint                                   : Ok
> 23: Number of exit events of a simple workload            : Ok
> 24: Software clock events period values                   : Ok
> 25: Object code reading                                   : Ok
> 26: Sample parsing                                        : Ok
> 27: Use a dummy software event to keep tracking           : Ok
> 28: Parse with no sample_id_all bit set                   : Ok
> 29: Filter hist entries                                   : Ok
> 30: Lookup mmap thread                                    : Ok
> 31: Share thread maps                                     : Ok
> 32: Sort output of hist entries                           : Ok
> 33: Cumulate child hist entries                           : Ok
> 34: Track with sched_switch                               : Ok
> 35: Filter fds with revents mask in a fdarray             : Ok
> 36: Add fd to a fdarray, making it autogrow               : Ok
> 37: kmod_path__parse                                      : Ok
> 38: Thread map                                            : Ok
> 39: LLVM search and compile                               :
> 39.1: Basic BPF llvm compile                              : Skip
> 39.2: kbuild searching                                    : Skip
> 39.3: Compile source for BPF prologue generation          : Skip
> 39.4: Compile source for BPF relocation                   : Skip

Skip is fine ;-)

> 40: Session topology                                      : FAILED!

I'd expect that one to fail if we don't have special
code to support arm in there

> 41: BPF filter                                            :
> 41.1: Basic BPF filtering                                 : Skip
> 41.2: BPF pinning                                         : Skip
> 41.3: BPF prologue generation                             : Skip
> 41.4: BPF relocation checker                              : Skip
> 42: Synthesize thread map                                 : Ok
> 43: Remove thread map                                     : Ok
> 44: Synthesize cpu map                                    : Ok
> 45: Synthesize stat config                                : Ok
> 46: Synthesize stat                                       : Ok
> 47: Synthesize stat round                                 : Ok
> 48: Synthesize attr update                                : Ok
> 49: Event times                                           : Ok
> 50: Read backward ring buffer                             : FAILED!

hum, I thought this was generic code that would work across archs

> 51: Print cpu map                                         : Ok
> 52: Merge cpu map                                         : Ok
> 53: Probe SDT events                                      : Ok
> 54: is_printable_array                                    : Ok
> 55: Print bitmap                                          : Ok
> 56: perf hooks                          umber__scnprintf                : Ok
> 59: mem2node                                              : Ok
> 60: time utils                                            : Ok
> 61: Test jit_write_elf                                    : Ok
> 62: maps__merge_in                                        : Ok
> 63: DWARF unwind                                          : Ok
> 64: Check open filename arg using perf trace + vfs_getname: FAILED!
> 65: Add vfs_getname probe to get syscall args filenames   : FAILED!
> 66: Use vfs_getname probe to get syscall args filenames   : FAILED!

with these we have always a problem across archs,
it's tricky to make script test that works everywhere :-\

> 67: Zstd perf.data compression/decompression              : Ok
> 68: probe libc's inet_pton & backtrace it with ping       : Skip
> john@ubuntu:~/linux$
> 
> I know that the perf tool definitely has issues for system topology for
> arm64, which I need to check on.
> 
> Maybe I can conscribe help internally to help check the rest...

the json/alias test would be also to make sure the x86 still works,
so regardless of some tests failing on arm, I think it's still better
to have that test

thanks,
jirka
John Garry Feb. 12, 2020, 12:24 p.m. UTC | #7
On 12/02/2020 12:16, Jiri Olsa wrote:
>>> et me consider this part for perf test support.
>> I will note that perf test has many issues on my arm64 board:
>>
>> do] password for john:
>>   1: vmlinux symtab matches kallsyms                       : Skip
>>   2: Detect openat syscall event                           : FAILED!
>>   3: Detect openat syscall event on all cpus               : FAILED!
>>   4: Read samples using the mmap interface                 : FAILED!
>>   5: Test data source output                               : Ok
>>   6: Parse event definition strings                        : FAILED!
>>   7: Simple expression parser                              : Ok
>>   8: PERF_RECORD_* events & perf_sample fields             : Ok
>>   9: Parse perf pmu format                                 : Ok
>> 10: DSO data read                                         : Ok
>> 11: DSO data cache                                        : Ok
>> 12: DSO data reopen                                       : Ok
>> 13: Roundtrip evsel->name                                 : Ok
>> 14: Parse sched tracepoints fields                        : FAILED!
>> 15: syscalls:sys_enter_openat event fields                : FAILED!
> looks like some issue with tracepoints
> 
>> 16: Setup struct perf_event_attr                          : Skip
>> 17: Match and link multiple hists                         : Ok
>> 18: 'import perf' in python                               : Ok
>> 21: Breakpoint accounting                                 : Ok
>> 22: Watchpoint                                            :
>> 22.1: Read Only Watchpoint                                : Ok
>> 22.2: Write Only Watchpoint                               : Ok
>> 22.3: Read / Write Watchpoint                             : Ok
>> 22.4: Modify Watchpoint                                   : Ok
>> 23: Number of exit events of a simple workload            : Ok
>> 24: Software clock events period values                   : Ok
>> 25: Object code reading                                   : Ok
>> 26: Sample parsing                                        : Ok
>> 27: Use a dummy software event to keep tracking           : Ok
>> 28: Parse with no sample_id_all bit set                   : Ok
>> 29: Filter hist entries                                   : Ok
>> 30: Lookup mmap thread                                    : Ok
>> 31: Share thread maps                                     : Ok
>> 32: Sort output of hist entries                           : Ok
>> 33: Cumulate child hist entries                           : Ok
>> 34: Track with sched_switch                               : Ok
>> 35: Filter fds with revents mask in a fdarray             : Ok
>> 36: Add fd to a fdarray, making it autogrow               : Ok
>> 37: kmod_path__parse                                      : Ok
>> 38: Thread map                                            : Ok
>> 39: LLVM search and compile                               :
>> 39.1: Basic BPF llvm compile                              : Skip
>> 39.2: kbuild searching                                    : Skip
>> 39.3: Compile source for BPF prologue generation          : Skip
>> 39.4: Compile source for BPF relocation                   : Skip
> Skip is fine;-)
> 
>> 40: Session topology                                      : FAILED!
> I'd expect that one to fail if we don't have special
> code to support arm in there
> 
>> 41: BPF filter                                            :
>> 41.1: Basic BPF filtering                                 : Skip
>> 41.2: BPF pinning                                         : Skip
>> 41.3: BPF prologue generation                             : Skip
>> 41.4: BPF relocation checker                              : Skip
>> 42: Synthesize thread map                                 : Ok
>> 43: Remove thread map                                     : Ok
>> 44: Synthesize cpu map                                    : Ok
>> 45: Synthesize stat config                                : Ok
>> 46: Synthesize stat                                       : Ok
>> 47: Synthesize stat round                                 : Ok
>> 48: Synthesize attr update                                : Ok
>> 49: Event times                                           : Ok
>> 50: Read backward ring buffer                             : FAILED!
> hum, I thought this was generic code that would work across archs
> 
>> 51: Print cpu map                                         : Ok
>> 52: Merge cpu map                                         : Ok
>> 53: Probe SDT events                                      : Ok
>> 54: is_printable_array                                    : Ok
>> 55: Print bitmap                                          : Ok
>> 56: perf hooks                          umber__scnprintf                : Ok
>> 59: mem2node                                              : Ok
>> 60: time utils                                            : Ok
>> 61: Test jit_write_elf                                    : Ok
>> 62: maps__merge_in                                        : Ok
>> 63: DWARF unwind                                          : Ok
>> 64: Check open filename arg using perf trace + vfs_getname: FAILED!
>> 65: Add vfs_getname probe to get syscall args filenames   : FAILED!
>> 66: Use vfs_getname probe to get syscall args filenames   : FAILED!
> with these we have always a problem across archs,
> it's tricky to make script test that works everywhere:-\
> 
>> 67: Zstd perf.data compression/decompression              : Ok
>> 68: probe libc's inet_pton & backtrace it with ping       : Skip
>> john@ubuntu:~/linux$
>>
>> I know that the perf tool definitely has issues for system topology for
>> arm64, which I need to check on.
>>
>> Maybe I can conscribe help internally to help check the rest...

Hi jirka,

> the json/alias test would be also to make sure the x86 still works,
> so regardless of some tests failing on arm, I think it's still better
> to have that test

OK, I can look at this separately now, and it won't be blocked like this 
series is on the kernel sysid issue.

Thanks,
john
diff mbox series

Patch

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 569aba4cec89..4d4fe0c1ae22 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -672,11 +672,78 @@  static char *perf_pmu__getcpuid(struct perf_pmu *pmu)
 	return cpuid;
 }
 
+static char *get_sysid_str(void)
+{
+	char *buf = NULL;
+	char path[PATH_MAX];
+	const char *sysfs = sysfs__mountpoint();
+	FILE *file;
+	int s, i;
+
+	if (!sysfs)
+		return NULL;
+
+	buf = malloc(PATH_MAX);
+	if (!buf) {
+		pr_err("%s alloc failed\n", __func__);
+		return NULL;
+	}
+
+	scnprintf(path, PATH_MAX, "%s/devices/soc0/machine", sysfs);
+
+	file = fopen(path, "r");
+	if (!file) {
+		pr_debug("fopen failed for file %s\n", path);
+		free(buf);
+		return NULL;
+	}
+
+	if (!fgets(buf, PATH_MAX, file)) {
+		fclose(file);
+		pr_debug("gets failed for file %s\n", path);
+		free(buf);
+		return NULL;
+	}
+	fclose(file);
+
+	/* Remove any whitespace, this could be from ACPI HID */
+	s = strlen(buf);
+	for (i = 0; i < s; i++) {
+		if (buf[i] == ' ') {
+			buf[i] = 0;
+			break;
+		};
+	}
+
+	return buf;
+}
+
+static char *perf_pmu__getsysid(void)
+{
+	char *sysid;
+	static bool printed;
+
+	sysid = getenv("PERF_SYSID");
+	if (sysid)
+		sysid = strdup(sysid);
+
+	if (!sysid)
+		sysid = get_sysid_str();
+	if (!sysid)
+		return NULL;
+
+	if (!printed) {
+		pr_debug("Using SYSID %s\n", sysid);
+		printed = true;
+	}
+	return sysid;
+}
+
 struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
 {
-	struct pmu_events_map *map;
+	struct pmu_events_map *map, *found_map = NULL;
 	char *cpuid = perf_pmu__getcpuid(pmu);
-	int i;
+	char *sysid;
 
 	/* on some platforms which uses cpus map, cpuid can be NULL for
 	 * PMUs other than CORE PMUs.
@@ -684,19 +751,35 @@  struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
 	if (!cpuid)
 		return NULL;
 
-	i = 0;
-	for (;;) {
-		map = &pmu_events_map[i++];
-		if (!map->table) {
-			map = NULL;
-			break;
+	sysid = perf_pmu__getsysid();
+
+	/*
+	 * Match sysid as first perference for uncore/sys PMUs.
+	 *
+	 * x86 uncore events match by cpuid, but we would not have map->socid
+	 * set for that arch (so any matching here would fail for that).
+	 */
+	if (pmu && pmu_is_uncore_or_sys(pmu->name) &&
+	    !is_arm_pmu_core(pmu->name) && sysid) {
+		for (map = &pmu_events_map[0]; map->table; map++) {
+			if (map->sysid && !strcmp(map->sysid, sysid)) {
+				found_map = map;
+				goto out;
+			}
 		}
+	}
 
-		if (!strcmp_cpuid_str(map->cpuid, cpuid))
-			break;
+	for (map = &pmu_events_map[0]; map->table; map++) {
+		if (map->cpuid && cpuid &&
+		    !strcmp_cpuid_str(map->cpuid, cpuid)) {
+			found_map = map;
+			goto out;
+		}
 	}
+out:
 	free(cpuid);
-	return map;
+	free(sysid); /* Can safely handle is sysid is NULL */
+	return found_map;
 }
 
 static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)