License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 15:07:57 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2015-07-17 19:33:42 +03:00
|
|
|
#include <string.h>
|
perf pmu: Add PMU alias support
A perf uncore PMU may have two PMU names, a real name and an alias. The
alias is exported at /sys/bus/event_source/devices/uncore_*/alias.
The perf tool should support the alias as well.
Add alias_name in the struct perf_pmu to store the alias. For the PMU
which doesn't have an alias. It's NULL.
Introduce two X86 specific functions to retrieve the real name and the
alias separately.
Only go through the sysfs to retrieve the mapping between the real name
and the alias once. The result is cached in a list, uncore_pmu_list.
Nothing changed for the other ARCHs.
With the patch, the perf tool can monitor the PMU with either the real
name or the alias.
Use the real name,
$ perf stat -e uncore_cha_2/event=1/ -x,
4044879584,,uncore_cha_2/event=1/,2528059205,100.00,,
Use the alias,
$ perf stat -e uncore_type_0_2/event=1/ -x,
3659675336,,uncore_type_0_2/event=1/,2287306455,100.00,,
Committer notes:
Rename 'struct perf_pmu_alias_name' to 'pmu_alias', the 'perf_' prefix
should be used for libperf, things inside just tools/perf/ are being
moved away from that prefix.
Also 'pmu_alias' is shorter and reflects the abstraction.
Also don't use 'pmu' as the name for variables for that type, we should
use that for the 'struct perf_pmu' variables, avoiding confusion. Use
'pmu_alias' for 'struct pmu_alias' variables.
Co-developed-by: Jin Yao <yao.jin@linux.intel.com>
Co-developed-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.garry@huawei.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Link: http://lore.kernel.org/lkml/20210902065955.1299-2-yao.jin@linux.intel.com
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-09-02 14:59:54 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <fcntl.h>
|
2018-07-30 13:15:03 -03:00
|
|
|
#include <linux/stddef.h>
|
2015-07-17 19:33:42 +03:00
|
|
|
#include <linux/perf_event.h>
|
perf pmu: Add PMU alias support
A perf uncore PMU may have two PMU names, a real name and an alias. The
alias is exported at /sys/bus/event_source/devices/uncore_*/alias.
The perf tool should support the alias as well.
Add alias_name in the struct perf_pmu to store the alias. For the PMU
which doesn't have an alias. It's NULL.
Introduce two X86 specific functions to retrieve the real name and the
alias separately.
Only go through the sysfs to retrieve the mapping between the real name
and the alias once. The result is cached in a list, uncore_pmu_list.
Nothing changed for the other ARCHs.
With the patch, the perf tool can monitor the PMU with either the real
name or the alias.
Use the real name,
$ perf stat -e uncore_cha_2/event=1/ -x,
4044879584,,uncore_cha_2/event=1/,2528059205,100.00,,
Use the alias,
$ perf stat -e uncore_type_0_2/event=1/ -x,
3659675336,,uncore_type_0_2/event=1/,2287306455,100.00,,
Committer notes:
Rename 'struct perf_pmu_alias_name' to 'pmu_alias', the 'perf_' prefix
should be used for libperf, things inside just tools/perf/ are being
moved away from that prefix.
Also 'pmu_alias' is shorter and reflects the abstraction.
Also don't use 'pmu' as the name for variables for that type, we should
use that for the 'struct perf_pmu' variables, avoiding confusion. Use
'pmu_alias' for 'struct pmu_alias' variables.
Co-developed-by: Jin Yao <yao.jin@linux.intel.com>
Co-developed-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.garry@huawei.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Link: http://lore.kernel.org/lkml/20210902065955.1299-2-yao.jin@linux.intel.com
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-09-02 14:59:54 +08:00
|
|
|
#include <linux/zalloc.h>
|
|
|
|
#include <api/fs/fs.h>
|
perf pmu intel: Adjust cpumaks for sub-NUMA clusters on graniterapids
On graniterapids the cache home agent (CHA) and memory controller
(IMC) PMUs all have their cpumask set to per-socket information. In
order for per NUMA node aggregation to work correctly the PMUs cpumask
needs to be set to CPUs for the relevant sub-NUMA grouping.
For example, on a 2 socket graniterapids machine with sub NUMA
clustering of 3, for uncore_cha and uncore_imc PMUs the cpumask is
"0,120" leading to aggregation only on NUMA nodes 0 and 3:
```
$ perf stat --per-node -e 'UNC_CHA_CLOCKTICKS,UNC_M_CLOCKTICKS' -a sleep 1
Performance counter stats for 'system wide':
N0 1 277,835,681,344 UNC_CHA_CLOCKTICKS
N0 1 19,242,894,228 UNC_M_CLOCKTICKS
N3 1 277,803,448,124 UNC_CHA_CLOCKTICKS
N3 1 19,240,741,498 UNC_M_CLOCKTICKS
1.002113847 seconds time elapsed
```
By updating the PMUs cpumasks to "0,120", "40,160" and "80,200" then
the correctly 6 NUMA node aggregations are achieved:
```
$ perf stat --per-node -e 'UNC_CHA_CLOCKTICKS,UNC_M_CLOCKTICKS' -a sleep 1
Performance counter stats for 'system wide':
N0 1 92,748,667,796 UNC_CHA_CLOCKTICKS
N0 0 6,424,021,142 UNC_M_CLOCKTICKS
N1 0 92,753,504,424 UNC_CHA_CLOCKTICKS
N1 1 6,424,308,338 UNC_M_CLOCKTICKS
N2 0 92,751,170,084 UNC_CHA_CLOCKTICKS
N2 0 6,424,227,402 UNC_M_CLOCKTICKS
N3 1 92,745,944,144 UNC_CHA_CLOCKTICKS
N3 0 6,423,752,086 UNC_M_CLOCKTICKS
N4 0 92,725,793,788 UNC_CHA_CLOCKTICKS
N4 1 6,422,393,266 UNC_M_CLOCKTICKS
N5 0 92,717,504,388 UNC_CHA_CLOCKTICKS
N5 0 6,421,842,618 UNC_M_CLOCKTICKS
1.003406645 seconds time elapsed
```
In general, having the perf tool adjust cpumasks isn't desirable as
ideally the PMU driver would be advertising the correct cpumask.
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Tested-by: Weilin Wang <weilin.wang@intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Link: https://lore.kernel.org/r/20250515181417.491401-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2025-05-15 11:14:17 -07:00
|
|
|
#include <api/io_dir.h>
|
|
|
|
#include <internal/cpumap.h>
|
perf pmu: Add PMU alias support
A perf uncore PMU may have two PMU names, a real name and an alias. The
alias is exported at /sys/bus/event_source/devices/uncore_*/alias.
The perf tool should support the alias as well.
Add alias_name in the struct perf_pmu to store the alias. For the PMU
which doesn't have an alias. It's NULL.
Introduce two X86 specific functions to retrieve the real name and the
alias separately.
Only go through the sysfs to retrieve the mapping between the real name
and the alias once. The result is cached in a list, uncore_pmu_list.
Nothing changed for the other ARCHs.
With the patch, the perf tool can monitor the PMU with either the real
name or the alias.
Use the real name,
$ perf stat -e uncore_cha_2/event=1/ -x,
4044879584,,uncore_cha_2/event=1/,2528059205,100.00,,
Use the alias,
$ perf stat -e uncore_type_0_2/event=1/ -x,
3659675336,,uncore_type_0_2/event=1/,2287306455,100.00,,
Committer notes:
Rename 'struct perf_pmu_alias_name' to 'pmu_alias', the 'perf_' prefix
should be used for libperf, things inside just tools/perf/ are being
moved away from that prefix.
Also 'pmu_alias' is shorter and reflects the abstraction.
Also don't use 'pmu' as the name for variables for that type, we should
use that for the 'struct perf_pmu' variables, avoiding confusion. Use
'pmu_alias' for 'struct pmu_alias' variables.
Co-developed-by: Jin Yao <yao.jin@linux.intel.com>
Co-developed-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.garry@huawei.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Link: http://lore.kernel.org/lkml/20210902065955.1299-2-yao.jin@linux.intel.com
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-09-02 14:59:54 +08:00
|
|
|
#include <errno.h>
|
2015-07-17 19:33:42 +03:00
|
|
|
|
2020-03-05 23:11:08 -08:00
|
|
|
#include "../../../util/intel-pt.h"
|
|
|
|
#include "../../../util/intel-bts.h"
|
|
|
|
#include "../../../util/pmu.h"
|
perf pmu: Add PMU alias support
A perf uncore PMU may have two PMU names, a real name and an alias. The
alias is exported at /sys/bus/event_source/devices/uncore_*/alias.
The perf tool should support the alias as well.
Add alias_name in the struct perf_pmu to store the alias. For the PMU
which doesn't have an alias. It's NULL.
Introduce two X86 specific functions to retrieve the real name and the
alias separately.
Only go through the sysfs to retrieve the mapping between the real name
and the alias once. The result is cached in a list, uncore_pmu_list.
Nothing changed for the other ARCHs.
With the patch, the perf tool can monitor the PMU with either the real
name or the alias.
Use the real name,
$ perf stat -e uncore_cha_2/event=1/ -x,
4044879584,,uncore_cha_2/event=1/,2528059205,100.00,,
Use the alias,
$ perf stat -e uncore_type_0_2/event=1/ -x,
3659675336,,uncore_type_0_2/event=1/,2287306455,100.00,,
Committer notes:
Rename 'struct perf_pmu_alias_name' to 'pmu_alias', the 'perf_' prefix
should be used for libperf, things inside just tools/perf/ are being
moved away from that prefix.
Also 'pmu_alias' is shorter and reflects the abstraction.
Also don't use 'pmu' as the name for variables for that type, we should
use that for the 'struct perf_pmu' variables, avoiding confusion. Use
'pmu_alias' for 'struct pmu_alias' variables.
Co-developed-by: Jin Yao <yao.jin@linux.intel.com>
Co-developed-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.garry@huawei.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Link: http://lore.kernel.org/lkml/20210902065955.1299-2-yao.jin@linux.intel.com
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-09-02 14:59:54 +08:00
|
|
|
#include "../../../util/fncache.h"
|
2023-06-15 10:46:59 +05:30
|
|
|
#include "../../../util/pmus.h"
|
2024-01-23 10:50:30 -08:00
|
|
|
#include "mem-events.h"
|
perf pmu intel: Adjust cpumaks for sub-NUMA clusters on graniterapids
On graniterapids the cache home agent (CHA) and memory controller
(IMC) PMUs all have their cpumask set to per-socket information. In
order for per NUMA node aggregation to work correctly the PMUs cpumask
needs to be set to CPUs for the relevant sub-NUMA grouping.
For example, on a 2 socket graniterapids machine with sub NUMA
clustering of 3, for uncore_cha and uncore_imc PMUs the cpumask is
"0,120" leading to aggregation only on NUMA nodes 0 and 3:
```
$ perf stat --per-node -e 'UNC_CHA_CLOCKTICKS,UNC_M_CLOCKTICKS' -a sleep 1
Performance counter stats for 'system wide':
N0 1 277,835,681,344 UNC_CHA_CLOCKTICKS
N0 1 19,242,894,228 UNC_M_CLOCKTICKS
N3 1 277,803,448,124 UNC_CHA_CLOCKTICKS
N3 1 19,240,741,498 UNC_M_CLOCKTICKS
1.002113847 seconds time elapsed
```
By updating the PMUs cpumasks to "0,120", "40,160" and "80,200" then
the correctly 6 NUMA node aggregations are achieved:
```
$ perf stat --per-node -e 'UNC_CHA_CLOCKTICKS,UNC_M_CLOCKTICKS' -a sleep 1
Performance counter stats for 'system wide':
N0 1 92,748,667,796 UNC_CHA_CLOCKTICKS
N0 0 6,424,021,142 UNC_M_CLOCKTICKS
N1 0 92,753,504,424 UNC_CHA_CLOCKTICKS
N1 1 6,424,308,338 UNC_M_CLOCKTICKS
N2 0 92,751,170,084 UNC_CHA_CLOCKTICKS
N2 0 6,424,227,402 UNC_M_CLOCKTICKS
N3 1 92,745,944,144 UNC_CHA_CLOCKTICKS
N3 0 6,423,752,086 UNC_M_CLOCKTICKS
N4 0 92,725,793,788 UNC_CHA_CLOCKTICKS
N4 1 6,422,393,266 UNC_M_CLOCKTICKS
N5 0 92,717,504,388 UNC_CHA_CLOCKTICKS
N5 0 6,421,842,618 UNC_M_CLOCKTICKS
1.003406645 seconds time elapsed
```
In general, having the perf tool adjust cpumasks isn't desirable as
ideally the PMU driver would be advertising the correct cpumask.
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Tested-by: Weilin Wang <weilin.wang@intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Link: https://lore.kernel.org/r/20250515181417.491401-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2025-05-15 11:14:17 -07:00
|
|
|
#include "util/debug.h"
|
2024-10-15 23:23:56 -07:00
|
|
|
#include "util/env.h"
|
perf pmu intel: Adjust cpumaks for sub-NUMA clusters on graniterapids
On graniterapids the cache home agent (CHA) and memory controller
(IMC) PMUs all have their cpumask set to per-socket information. In
order for per NUMA node aggregation to work correctly the PMUs cpumask
needs to be set to CPUs for the relevant sub-NUMA grouping.
For example, on a 2 socket graniterapids machine with sub NUMA
clustering of 3, for uncore_cha and uncore_imc PMUs the cpumask is
"0,120" leading to aggregation only on NUMA nodes 0 and 3:
```
$ perf stat --per-node -e 'UNC_CHA_CLOCKTICKS,UNC_M_CLOCKTICKS' -a sleep 1
Performance counter stats for 'system wide':
N0 1 277,835,681,344 UNC_CHA_CLOCKTICKS
N0 1 19,242,894,228 UNC_M_CLOCKTICKS
N3 1 277,803,448,124 UNC_CHA_CLOCKTICKS
N3 1 19,240,741,498 UNC_M_CLOCKTICKS
1.002113847 seconds time elapsed
```
By updating the PMUs cpumasks to "0,120", "40,160" and "80,200" then
the correctly 6 NUMA node aggregations are achieved:
```
$ perf stat --per-node -e 'UNC_CHA_CLOCKTICKS,UNC_M_CLOCKTICKS' -a sleep 1
Performance counter stats for 'system wide':
N0 1 92,748,667,796 UNC_CHA_CLOCKTICKS
N0 0 6,424,021,142 UNC_M_CLOCKTICKS
N1 0 92,753,504,424 UNC_CHA_CLOCKTICKS
N1 1 6,424,308,338 UNC_M_CLOCKTICKS
N2 0 92,751,170,084 UNC_CHA_CLOCKTICKS
N2 0 6,424,227,402 UNC_M_CLOCKTICKS
N3 1 92,745,944,144 UNC_CHA_CLOCKTICKS
N3 0 6,423,752,086 UNC_M_CLOCKTICKS
N4 0 92,725,793,788 UNC_CHA_CLOCKTICKS
N4 1 6,422,393,266 UNC_M_CLOCKTICKS
N5 0 92,717,504,388 UNC_CHA_CLOCKTICKS
N5 0 6,421,842,618 UNC_M_CLOCKTICKS
1.003406645 seconds time elapsed
```
In general, having the perf tool adjust cpumasks isn't desirable as
ideally the PMU driver would be advertising the correct cpumask.
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Tested-by: Weilin Wang <weilin.wang@intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Link: https://lore.kernel.org/r/20250515181417.491401-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2025-05-15 11:14:17 -07:00
|
|
|
#include "util/header.h"
|
|
|
|
|
|
|
|
static bool x86__is_intel_graniterapids(void)
|
|
|
|
{
|
|
|
|
static bool checked_if_graniterapids;
|
|
|
|
static bool is_graniterapids;
|
|
|
|
|
|
|
|
if (!checked_if_graniterapids) {
|
|
|
|
const char *graniterapids_cpuid = "GenuineIntel-6-A[DE]";
|
|
|
|
char *cpuid = get_cpuid_str((struct perf_cpu){0});
|
|
|
|
|
|
|
|
is_graniterapids = cpuid && strcmp_cpuid_str(graniterapids_cpuid, cpuid) == 0;
|
|
|
|
free(cpuid);
|
|
|
|
checked_if_graniterapids = true;
|
|
|
|
}
|
|
|
|
return is_graniterapids;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct perf_cpu_map *read_sysfs_cpu_map(const char *sysfs_path)
|
|
|
|
{
|
|
|
|
struct perf_cpu_map *cpus;
|
|
|
|
char *buf = NULL;
|
|
|
|
size_t buf_len;
|
|
|
|
|
|
|
|
if (sysfs__read_str(sysfs_path, &buf, &buf_len) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
cpus = perf_cpu_map__new(buf);
|
|
|
|
free(buf);
|
|
|
|
return cpus;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int snc_nodes_per_l3_cache(void)
|
|
|
|
{
|
|
|
|
static bool checked_snc;
|
|
|
|
static int snc_nodes;
|
|
|
|
|
|
|
|
if (!checked_snc) {
|
|
|
|
struct perf_cpu_map *node_cpus =
|
|
|
|
read_sysfs_cpu_map("devices/system/node/node0/cpulist");
|
|
|
|
struct perf_cpu_map *cache_cpus =
|
|
|
|
read_sysfs_cpu_map("devices/system/cpu/cpu0/cache/index3/shared_cpu_list");
|
|
|
|
|
|
|
|
snc_nodes = perf_cpu_map__nr(cache_cpus) / perf_cpu_map__nr(node_cpus);
|
|
|
|
perf_cpu_map__put(cache_cpus);
|
|
|
|
perf_cpu_map__put(node_cpus);
|
|
|
|
checked_snc = true;
|
|
|
|
}
|
|
|
|
return snc_nodes;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool starts_with(const char *str, const char *prefix)
|
|
|
|
{
|
|
|
|
return !strncmp(prefix, str, strlen(prefix));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int num_chas(void)
|
|
|
|
{
|
|
|
|
static bool checked_chas;
|
|
|
|
static int num_chas;
|
|
|
|
|
|
|
|
if (!checked_chas) {
|
|
|
|
int fd = perf_pmu__event_source_devices_fd();
|
|
|
|
struct io_dir dir;
|
|
|
|
struct io_dirent64 *dent;
|
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
io_dir__init(&dir, fd);
|
|
|
|
|
|
|
|
while ((dent = io_dir__readdir(&dir)) != NULL) {
|
|
|
|
/* Note, dent->d_type will be DT_LNK and so isn't a useful filter. */
|
|
|
|
if (starts_with(dent->d_name, "uncore_cha_"))
|
|
|
|
num_chas++;
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
checked_chas = true;
|
|
|
|
}
|
|
|
|
return num_chas;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_SNCS 6
|
|
|
|
|
|
|
|
static int uncore_cha_snc(struct perf_pmu *pmu)
|
|
|
|
{
|
|
|
|
// CHA SNC numbers are ordered correspond to the CHAs number.
|
|
|
|
unsigned int cha_num;
|
|
|
|
int num_cha, chas_per_node, cha_snc;
|
|
|
|
int snc_nodes = snc_nodes_per_l3_cache();
|
|
|
|
|
|
|
|
if (snc_nodes <= 1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
num_cha = num_chas();
|
|
|
|
if (num_cha <= 0) {
|
|
|
|
pr_warning("Unexpected: no CHAs found\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compute SNC for PMU. */
|
|
|
|
if (sscanf(pmu->name, "uncore_cha_%u", &cha_num) != 1) {
|
|
|
|
pr_warning("Unexpected: unable to compute CHA number '%s'\n", pmu->name);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
chas_per_node = num_cha / snc_nodes;
|
|
|
|
cha_snc = cha_num / chas_per_node;
|
|
|
|
|
|
|
|
/* Range check cha_snc. for unexpected out of bounds. */
|
|
|
|
return cha_snc >= MAX_SNCS ? 0 : cha_snc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int uncore_imc_snc(struct perf_pmu *pmu)
|
|
|
|
{
|
|
|
|
// Compute the IMC SNC using lookup tables.
|
|
|
|
unsigned int imc_num;
|
|
|
|
int snc_nodes = snc_nodes_per_l3_cache();
|
|
|
|
const u8 snc2_map[] = {1, 1, 0, 0, 1, 1, 0, 0};
|
|
|
|
const u8 snc3_map[] = {1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2};
|
|
|
|
const u8 *snc_map;
|
|
|
|
size_t snc_map_len;
|
|
|
|
|
|
|
|
switch (snc_nodes) {
|
|
|
|
case 2:
|
|
|
|
snc_map = snc2_map;
|
|
|
|
snc_map_len = ARRAY_SIZE(snc2_map);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
snc_map = snc3_map;
|
|
|
|
snc_map_len = ARRAY_SIZE(snc3_map);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Error or no lookup support for SNC with >3 nodes. */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compute SNC for PMU. */
|
|
|
|
if (sscanf(pmu->name, "uncore_imc_%u", &imc_num) != 1) {
|
|
|
|
pr_warning("Unexpected: unable to compute IMC number '%s'\n", pmu->name);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (imc_num >= snc_map_len) {
|
|
|
|
pr_warning("Unexpected IMC %d for SNC%d mapping\n", imc_num, snc_nodes);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return snc_map[imc_num];
|
|
|
|
}
|
|
|
|
|
|
|
|
static int uncore_cha_imc_compute_cpu_adjust(int pmu_snc)
|
|
|
|
{
|
|
|
|
static bool checked_cpu_adjust[MAX_SNCS];
|
|
|
|
static int cpu_adjust[MAX_SNCS];
|
|
|
|
struct perf_cpu_map *node_cpus;
|
|
|
|
char node_path[] = "devices/system/node/node0/cpulist";
|
|
|
|
|
|
|
|
/* Was adjust already computed? */
|
|
|
|
if (checked_cpu_adjust[pmu_snc])
|
|
|
|
return cpu_adjust[pmu_snc];
|
|
|
|
|
|
|
|
/* SNC0 doesn't need an adjust. */
|
|
|
|
if (pmu_snc == 0) {
|
|
|
|
cpu_adjust[0] = 0;
|
|
|
|
checked_cpu_adjust[0] = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use NUMA topology to compute first CPU of the NUMA node, we want to
|
|
|
|
* adjust CPU 0 to be this and similarly for other CPUs if there is >1
|
|
|
|
* socket.
|
|
|
|
*/
|
|
|
|
assert(pmu_snc >= 0 && pmu_snc <= 9);
|
|
|
|
node_path[24] += pmu_snc; // Shift node0 to be node<pmu_snc>.
|
|
|
|
node_cpus = read_sysfs_cpu_map(node_path);
|
|
|
|
cpu_adjust[pmu_snc] = perf_cpu_map__cpu(node_cpus, 0).cpu;
|
|
|
|
if (cpu_adjust[pmu_snc] < 0) {
|
|
|
|
pr_debug("Failed to read valid CPU list from <sysfs>/%s\n", node_path);
|
|
|
|
cpu_adjust[pmu_snc] = 0;
|
|
|
|
} else {
|
|
|
|
checked_cpu_adjust[pmu_snc] = true;
|
|
|
|
}
|
|
|
|
perf_cpu_map__put(node_cpus);
|
|
|
|
return cpu_adjust[pmu_snc];
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gnr_uncore_cha_imc_adjust_cpumask_for_snc(struct perf_pmu *pmu, bool cha)
|
|
|
|
{
|
|
|
|
// With sub-NUMA clustering (SNC) there is a NUMA node per SNC in the
|
|
|
|
// topology. For example, a two socket graniterapids machine may be set
|
|
|
|
// up with 3-way SNC meaning there are 6 NUMA nodes that should be
|
|
|
|
// displayed with --per-node. The cpumask of the CHA and IMC PMUs
|
|
|
|
// reflects per-socket information meaning, for example, uncore_cha_60
|
|
|
|
// on a two socket graniterapids machine with 120 cores per socket will
|
|
|
|
// have a cpumask of "0,120". This cpumask needs adjusting to "40,160"
|
|
|
|
// to reflect that uncore_cha_60 is used for the 2nd SNC of each
|
|
|
|
// socket. Without the adjustment events on uncore_cha_60 will appear in
|
|
|
|
// node 0 and node 3 (in our example 2 socket 3-way set up), but with
|
|
|
|
// the adjustment they will appear in node 1 and node 4. The number of
|
|
|
|
// CHAs is typically larger than the number of cores. The CHA numbers
|
|
|
|
// are assumed to split evenly and inorder wrt core numbers. There are
|
|
|
|
// fewer memory IMC PMUs than cores and mapping is handled using lookup
|
|
|
|
// tables.
|
|
|
|
static struct perf_cpu_map *cha_adjusted[MAX_SNCS];
|
|
|
|
static struct perf_cpu_map *imc_adjusted[MAX_SNCS];
|
|
|
|
struct perf_cpu_map **adjusted = cha ? cha_adjusted : imc_adjusted;
|
|
|
|
int idx, pmu_snc, cpu_adjust;
|
|
|
|
struct perf_cpu cpu;
|
|
|
|
bool alloc;
|
|
|
|
|
|
|
|
// Cpus from the kernel holds first CPU of each socket. e.g. 0,120.
|
|
|
|
if (perf_cpu_map__cpu(pmu->cpus, 0).cpu != 0) {
|
|
|
|
pr_debug("Ignoring cpumask adjust for %s as unexpected first CPU\n", pmu->name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pmu_snc = cha ? uncore_cha_snc(pmu) : uncore_imc_snc(pmu);
|
|
|
|
if (pmu_snc == 0) {
|
|
|
|
// No adjustment necessary for the first SNC.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
alloc = adjusted[pmu_snc] == NULL;
|
|
|
|
if (alloc) {
|
|
|
|
// Hold onto the perf_cpu_map globally to avoid recomputation.
|
|
|
|
cpu_adjust = uncore_cha_imc_compute_cpu_adjust(pmu_snc);
|
|
|
|
adjusted[pmu_snc] = perf_cpu_map__empty_new(perf_cpu_map__nr(pmu->cpus));
|
|
|
|
if (!adjusted[pmu_snc])
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
perf_cpu_map__for_each_cpu(cpu, idx, pmu->cpus) {
|
|
|
|
// Compute the new cpu map values or if not allocating, assert
|
|
|
|
// that they match expectations. asserts will be removed to
|
|
|
|
// avoid overhead in NDEBUG builds.
|
|
|
|
if (alloc) {
|
|
|
|
RC_CHK_ACCESS(adjusted[pmu_snc])->map[idx].cpu = cpu.cpu + cpu_adjust;
|
|
|
|
} else if (idx == 0) {
|
|
|
|
cpu_adjust = perf_cpu_map__cpu(adjusted[pmu_snc], idx).cpu - cpu.cpu;
|
|
|
|
assert(uncore_cha_imc_compute_cpu_adjust(pmu_snc) == cpu_adjust);
|
|
|
|
} else {
|
|
|
|
assert(perf_cpu_map__cpu(adjusted[pmu_snc], idx).cpu ==
|
|
|
|
cpu.cpu + cpu_adjust);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
perf_cpu_map__put(pmu->cpus);
|
|
|
|
pmu->cpus = perf_cpu_map__get(adjusted[pmu_snc]);
|
|
|
|
}
|
perf pmu: Add PMU alias support
A perf uncore PMU may have two PMU names, a real name and an alias. The
alias is exported at /sys/bus/event_source/devices/uncore_*/alias.
The perf tool should support the alias as well.
Add alias_name in the struct perf_pmu to store the alias. For the PMU
which doesn't have an alias. It's NULL.
Introduce two X86 specific functions to retrieve the real name and the
alias separately.
Only go through the sysfs to retrieve the mapping between the real name
and the alias once. The result is cached in a list, uncore_pmu_list.
Nothing changed for the other ARCHs.
With the patch, the perf tool can monitor the PMU with either the real
name or the alias.
Use the real name,
$ perf stat -e uncore_cha_2/event=1/ -x,
4044879584,,uncore_cha_2/event=1/,2528059205,100.00,,
Use the alias,
$ perf stat -e uncore_type_0_2/event=1/ -x,
3659675336,,uncore_type_0_2/event=1/,2287306455,100.00,,
Committer notes:
Rename 'struct perf_pmu_alias_name' to 'pmu_alias', the 'perf_' prefix
should be used for libperf, things inside just tools/perf/ are being
moved away from that prefix.
Also 'pmu_alias' is shorter and reflects the abstraction.
Also don't use 'pmu' as the name for variables for that type, we should
use that for the 'struct perf_pmu' variables, avoiding confusion. Use
'pmu_alias' for 'struct pmu_alias' variables.
Co-developed-by: Jin Yao <yao.jin@linux.intel.com>
Co-developed-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.garry@huawei.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Link: http://lore.kernel.org/lkml/20210902065955.1299-2-yao.jin@linux.intel.com
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-09-02 14:59:54 +08:00
|
|
|
|
2025-04-29 03:59:37 +00:00
|
|
|
void perf_pmu__arch_init(struct perf_pmu *pmu)
|
2015-07-17 19:33:42 +03:00
|
|
|
{
|
2025-04-29 03:59:37 +00:00
|
|
|
struct perf_pmu_caps *ldlat_cap;
|
|
|
|
|
2015-07-17 19:33:42 +03:00
|
|
|
#ifdef HAVE_AUXTRACE_SUPPORT
|
2023-03-11 18:15:35 -08:00
|
|
|
if (!strcmp(pmu->name, INTEL_PT_PMU_NAME)) {
|
|
|
|
pmu->auxtrace = true;
|
2023-10-12 10:56:40 -07:00
|
|
|
pmu->selectable = true;
|
2023-10-12 10:56:45 -07:00
|
|
|
pmu->perf_event_attr_init_default = intel_pt_pmu_default_config;
|
2023-03-11 18:15:35 -08:00
|
|
|
}
|
|
|
|
if (!strcmp(pmu->name, INTEL_BTS_PMU_NAME)) {
|
|
|
|
pmu->auxtrace = true;
|
perf tools: Add Intel BTS support
Intel BTS support fits within the new auxtrace infrastructure. Recording is
supporting by identifying the Intel BTS PMU, parsing options and setting up
events.
Decoding is supported by queuing up trace data by thread and then decoding
synchronously delivering synthesized event samples into the session processing
for tools to consume.
Committer note:
E.g:
[root@felicio ~]# perf record --per-thread -e intel_bts// ls
anaconda-ks.cfg apctest.output bin kernel-rt-3.10.0-298.rt56.171.el7.x86_64.rpm libexec lock_page.bpf.c perf.data perf.data.old
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 4.367 MB perf.data ]
[root@felicio ~]# perf evlist -v
intel_bts//: type: 6, size: 112, { sample_period, sample_freq }: 1, sample_type: IP|TID|IDENTIFIER, read_format: ID, disabled: 1, enable_on_exec: 1, sample_id_all: 1, exclude_guest: 1
dummy:u: type: 1, size: 112, config: 0x9, { sample_period, sample_freq }: 1, sample_type: IP|TID|IDENTIFIER, read_format: ID, disabled: 1, exclude_kernel: 1, exclude_hv: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, mmap2: 1, comm_exec: 1
[root@felicio ~]# perf script # the navigate in the pager to some interesting place:
ls 1843 1 branches: ffffffff810a60cb flush_signal_handlers ([kernel.kallsyms]) => ffffffff8121a522 setup_new_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8121a529 setup_new_exec ([kernel.kallsyms]) => ffffffff8122fa30 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fa5d do_close_on_exec ([kernel.kallsyms]) => ffffffff81767ae0 _raw_spin_lock ([kernel.kallsyms])
ls 1843 1 branches: ffffffff81767af4 _raw_spin_lock ([kernel.kallsyms]) => ffffffff8122fa62 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fa8e do_close_on_exec ([kernel.kallsyms]) => ffffffff8122faf0 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122faf7 do_close_on_exec ([kernel.kallsyms]) => ffffffff8122fa8b do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fa8e do_close_on_exec ([kernel.kallsyms]) => ffffffff8122faf0 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122faf7 do_close_on_exec ([kernel.kallsyms]) => ffffffff8122fa8b do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fa8e do_close_on_exec ([kernel.kallsyms]) => ffffffff8122faf0 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122faf7 do_close_on_exec ([kernel.kallsyms]) => ffffffff8122fa8b do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fa8e do_close_on_exec ([kernel.kallsyms]) => ffffffff8122faf0 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122faf7 do_close_on_exec ([kernel.kallsyms]) => ffffffff8122fa8b do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fa8e do_close_on_exec ([kernel.kallsyms]) => ffffffff8122faf0 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122faf7 do_close_on_exec ([kernel.kallsyms]) => ffffffff8122fa8b do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fa8e do_close_on_exec ([kernel.kallsyms]) => ffffffff8122faf0 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122faf7 do_close_on_exec ([kernel.kallsyms]) => ffffffff8122fa8b do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fac9 do_close_on_exec ([kernel.kallsyms]) => ffffffff8122fad2 do_close_on_exec ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8122fadd do_close_on_exec ([kernel.kallsyms]) => ffffffff8120fc80 filp_close ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8120fcaf filp_close ([kernel.kallsyms]) => ffffffff8120fcb6 filp_close ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8120fcc2 filp_close ([kernel.kallsyms]) => ffffffff812547f0 dnotify_flush ([kernel.kallsyms])
ls 1843 1 branches: ffffffff81254823 dnotify_flush ([kernel.kallsyms]) => ffffffff8120fcc7 filp_close ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8120fccd filp_close ([kernel.kallsyms]) => ffffffff81261790 locks_remove_posix ([kernel.kallsyms])
ls 1843 1 branches: ffffffff812617a3 locks_remove_posix ([kernel.kallsyms]) => ffffffff812617b9 locks_remove_posix ([kernel.kallsyms])
ls 1843 1 branches: ffffffff812617b9 locks_remove_posix ([kernel.kallsyms]) => ffffffff8120fcd2 filp_close ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8120fcd5 filp_close ([kernel.kallsyms]) => ffffffff812142c0 fput ([kernel.kallsyms])
ls 1843 1 branches: ffffffff812142d6 fput ([kernel.kallsyms]) => ffffffff812142df fput ([kernel.kallsyms])
ls 1843 1 branches: ffffffff8121430c fput ([kernel.kallsyms]) => ffffffff810b6580 task_work_add ([kernel.kallsyms])
ls 1843 1 branches: ffffffff810b65ad task_work_add ([kernel.kallsyms]) => ffffffff810b65b1 task_work_add ([kernel.kallsyms])
ls 1843 1 branches: ffffffff810b65c1 task_work_add ([kernel.kallsyms]) => ffffffff810bc710 kick_process ([kernel.kallsyms])
ls 1843 1 branches: ffffffff810bc725 kick_process ([kernel.kallsyms]) => ffffffff810bc742 kick_process ([kernel.kallsyms])
ls 1843 1 branches: ffffffff810bc742 kick_process ([kernel.kallsyms]) => ffffffff810b65c6 task_work_add ([kernel.kallsyms])
ls 1843 1 branches: ffffffff810b65c9 task_work_add ([kernel.kallsyms]) => ffffffff81214311 fput ([kernel.kallsyms])
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-9-git-send-email-adrian.hunter@intel.com
[ Merged sample->time fix for bug found after first round of testing on slightly older kernel ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-07-17 19:33:43 +03:00
|
|
|
pmu->selectable = true;
|
2023-03-11 18:15:35 -08:00
|
|
|
}
|
2015-07-17 19:33:42 +03:00
|
|
|
#endif
|
2024-01-23 10:50:30 -08:00
|
|
|
|
|
|
|
if (x86__is_amd_cpu()) {
|
2025-04-29 03:59:37 +00:00
|
|
|
if (strcmp(pmu->name, "ibs_op"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
pmu->mem_events = perf_mem_events_amd;
|
|
|
|
|
|
|
|
if (!perf_pmu__caps_parse(pmu))
|
|
|
|
return;
|
|
|
|
|
|
|
|
ldlat_cap = perf_pmu__get_cap(pmu, "ldlat");
|
|
|
|
if (!ldlat_cap || strcmp(ldlat_cap->value, "1"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
perf_mem_events__loads_ldlat = 0;
|
|
|
|
pmu->mem_events = perf_mem_events_amd_ldlat;
|
perf pmu intel: Adjust cpumaks for sub-NUMA clusters on graniterapids
On graniterapids the cache home agent (CHA) and memory controller
(IMC) PMUs all have their cpumask set to per-socket information. In
order for per NUMA node aggregation to work correctly the PMUs cpumask
needs to be set to CPUs for the relevant sub-NUMA grouping.
For example, on a 2 socket graniterapids machine with sub NUMA
clustering of 3, for uncore_cha and uncore_imc PMUs the cpumask is
"0,120" leading to aggregation only on NUMA nodes 0 and 3:
```
$ perf stat --per-node -e 'UNC_CHA_CLOCKTICKS,UNC_M_CLOCKTICKS' -a sleep 1
Performance counter stats for 'system wide':
N0 1 277,835,681,344 UNC_CHA_CLOCKTICKS
N0 1 19,242,894,228 UNC_M_CLOCKTICKS
N3 1 277,803,448,124 UNC_CHA_CLOCKTICKS
N3 1 19,240,741,498 UNC_M_CLOCKTICKS
1.002113847 seconds time elapsed
```
By updating the PMUs cpumasks to "0,120", "40,160" and "80,200" then
the correctly 6 NUMA node aggregations are achieved:
```
$ perf stat --per-node -e 'UNC_CHA_CLOCKTICKS,UNC_M_CLOCKTICKS' -a sleep 1
Performance counter stats for 'system wide':
N0 1 92,748,667,796 UNC_CHA_CLOCKTICKS
N0 0 6,424,021,142 UNC_M_CLOCKTICKS
N1 0 92,753,504,424 UNC_CHA_CLOCKTICKS
N1 1 6,424,308,338 UNC_M_CLOCKTICKS
N2 0 92,751,170,084 UNC_CHA_CLOCKTICKS
N2 0 6,424,227,402 UNC_M_CLOCKTICKS
N3 1 92,745,944,144 UNC_CHA_CLOCKTICKS
N3 0 6,423,752,086 UNC_M_CLOCKTICKS
N4 0 92,725,793,788 UNC_CHA_CLOCKTICKS
N4 1 6,422,393,266 UNC_M_CLOCKTICKS
N5 0 92,717,504,388 UNC_CHA_CLOCKTICKS
N5 0 6,421,842,618 UNC_M_CLOCKTICKS
1.003406645 seconds time elapsed
```
In general, having the perf tool adjust cpumasks isn't desirable as
ideally the PMU driver would be advertising the correct cpumask.
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Tested-by: Weilin Wang <weilin.wang@intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Link: https://lore.kernel.org/r/20250515181417.491401-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2025-05-15 11:14:17 -07:00
|
|
|
} else {
|
|
|
|
if (pmu->is_core) {
|
|
|
|
if (perf_pmu__have_event(pmu, "mem-loads-aux"))
|
|
|
|
pmu->mem_events = perf_mem_events_intel_aux;
|
|
|
|
else
|
|
|
|
pmu->mem_events = perf_mem_events_intel;
|
|
|
|
} else if (x86__is_intel_graniterapids()) {
|
|
|
|
if (starts_with(pmu->name, "uncore_cha_"))
|
|
|
|
gnr_uncore_cha_imc_adjust_cpumask_for_snc(pmu, /*cha=*/true);
|
|
|
|
else if (starts_with(pmu->name, "uncore_imc_"))
|
|
|
|
gnr_uncore_cha_imc_adjust_cpumask_for_snc(pmu, /*cha=*/false);
|
|
|
|
}
|
2024-01-23 10:50:32 -08:00
|
|
|
}
|
2015-07-17 19:33:42 +03:00
|
|
|
}
|