* [PATCH] tools/power turbostat: Allow execution to continue after perf_l2_init() failure
@ 2026-03-19 14:03 David Arcari
2026-04-09 19:13 ` Len Brown
0 siblings, 1 reply; 5+ messages in thread
From: David Arcari @ 2026-03-19 14:03 UTC (permalink / raw)
To: Len Brown; +Cc: David Arcari, linux-pm, linux-kernel
Currently, if perf_l2_init() fails turbostat exits after issuing the
following error (which was encountered on AlderLake):
turbostat: perf_l2_init(cpu0, 0x0, 0xff24) REFS: Invalid argument
This occurs because perf_l2_init() calls err(). However, the code has been
written in such a manner that it is able to perform cleanup and continue.
Therefore, this issue can be addressed by changing the appropriate calls
to err() to warnx().
Additionally, correct the PMU type arguments passed to the warning strings
in the ecore and lcore blocks so the logs accurately reflect the failing
counter type.
Signed-off-by: David Arcari <darcari@redhat.com>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-pm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
tools/power/x86/turbostat/turbostat.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 1a2671c28209..f1b8059a4eec 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -9403,13 +9403,13 @@ void perf_l2_init(void)
if (!is_hybrid) {
fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.uniform, perf_model_support->first.refs, -1, PERF_FORMAT_GROUP);
if (fd_l2_percpu[cpu] == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.refs);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.refs);
free_fd_l2_percpu();
return;
}
retval = open_perf_counter(cpu, perf_pmu_types.uniform, perf_model_support->first.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
if (retval == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.hits);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.hits);
free_fd_l2_percpu();
return;
}
@@ -9418,39 +9418,39 @@ void perf_l2_init(void)
if (perf_pcore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_pcore_set)) {
fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.pcore, perf_model_support->first.refs, -1, PERF_FORMAT_GROUP);
if (fd_l2_percpu[cpu] == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.refs);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.refs);
free_fd_l2_percpu();
return;
}
retval = open_perf_counter(cpu, perf_pmu_types.pcore, perf_model_support->first.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
if (retval == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.hits);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.hits);
free_fd_l2_percpu();
return;
}
} else if (perf_ecore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_ecore_set)) {
fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.ecore, perf_model_support->second.refs, -1, PERF_FORMAT_GROUP);
if (fd_l2_percpu[cpu] == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->second.refs);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.ecore, perf_model_support->second.refs);
free_fd_l2_percpu();
return;
}
retval = open_perf_counter(cpu, perf_pmu_types.ecore, perf_model_support->second.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
if (retval == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->second.hits);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.ecore, perf_model_support->second.hits);
free_fd_l2_percpu();
return;
}
} else if (perf_lcore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_lcore_set)) {
fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.lcore, perf_model_support->third.refs, -1, PERF_FORMAT_GROUP);
if (fd_l2_percpu[cpu] == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->third.refs);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.lcore, perf_model_support->third.refs);
free_fd_l2_percpu();
return;
}
retval = open_perf_counter(cpu, perf_pmu_types.lcore, perf_model_support->third.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
if (retval == -1) {
- err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->third.hits);
+ warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.lcore, perf_model_support->third.hits);
free_fd_l2_percpu();
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] tools/power turbostat: Allow execution to continue after perf_l2_init() failure
2026-03-19 14:03 [PATCH] tools/power turbostat: Allow execution to continue after perf_l2_init() failure David Arcari
@ 2026-04-09 19:13 ` Len Brown
2026-04-10 12:59 ` Len Brown
0 siblings, 1 reply; 5+ messages in thread
From: Len Brown @ 2026-04-09 19:13 UTC (permalink / raw)
To: David Arcari; +Cc: linux-pm, linux-kernel
Hmm, the check of perf_model_support covers unknown CPUs.
(and this code runs fine on my Alderlake)
So the failure you see must be from the kernel perf support failing?
What is the kernel config?
thanks,
-Len
On Thu, Mar 19, 2026 at 10:04 AM David Arcari <darcari@redhat.com> wrote:
>
> Currently, if perf_l2_init() fails turbostat exits after issuing the
> following error (which was encountered on AlderLake):
>
> turbostat: perf_l2_init(cpu0, 0x0, 0xff24) REFS: Invalid argument
>
> This occurs because perf_l2_init() calls err(). However, the code has been
> written in such a manner that it is able to perform cleanup and continue.
> Therefore, this issue can be addressed by changing the appropriate calls
> to err() to warnx().
>
> Additionally, correct the PMU type arguments passed to the warning strings
> in the ecore and lcore blocks so the logs accurately reflect the failing
> counter type.
>
> Signed-off-by: David Arcari <darcari@redhat.com>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-pm@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
> tools/power/x86/turbostat/turbostat.c | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
> index 1a2671c28209..f1b8059a4eec 100644
> --- a/tools/power/x86/turbostat/turbostat.c
> +++ b/tools/power/x86/turbostat/turbostat.c
> @@ -9403,13 +9403,13 @@ void perf_l2_init(void)
> if (!is_hybrid) {
> fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.uniform, perf_model_support->first.refs, -1, PERF_FORMAT_GROUP);
> if (fd_l2_percpu[cpu] == -1) {
> - err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.refs);
> + warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.refs);
> free_fd_l2_percpu();
> return;
> }
> retval = open_perf_counter(cpu, perf_pmu_types.uniform, perf_model_support->first.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
> if (retval == -1) {
> - err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.hits);
> + warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.hits);
> free_fd_l2_percpu();
> return;
> }
> @@ -9418,39 +9418,39 @@ void perf_l2_init(void)
> if (perf_pcore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_pcore_set)) {
> fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.pcore, perf_model_support->first.refs, -1, PERF_FORMAT_GROUP);
> if (fd_l2_percpu[cpu] == -1) {
> - err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.refs);
> + warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.refs);
> free_fd_l2_percpu();
> return;
> }
> retval = open_perf_counter(cpu, perf_pmu_types.pcore, perf_model_support->first.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
> if (retval == -1) {
> - err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.hits);
> + warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.hits);
> free_fd_l2_percpu();
> return;
> }
> } else if (perf_ecore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_ecore_set)) {
> fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.ecore, perf_model_support->second.refs, -1, PERF_FORMAT_GROUP);
> if (fd_l2_percpu[cpu] == -1) {
> - err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->second.refs);
> + warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.ecore, perf_model_support->second.refs);
> free_fd_l2_percpu();
> return;
> }
> retval = open_perf_counter(cpu, perf_pmu_types.ecore, perf_model_support->second.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
> if (retval == -1) {
> - err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->second.hits);
> + warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.ecore, perf_model_support->second.hits);
> free_fd_l2_percpu();
> return;
> }
> } else if (perf_lcore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_lcore_set)) {
> fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.lcore, perf_model_support->third.refs, -1, PERF_FORMAT_GROUP);
> if (fd_l2_percpu[cpu] == -1) {
> - err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->third.refs);
> + warnx("%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.lcore, perf_model_support->third.refs);
> free_fd_l2_percpu();
> return;
> }
> retval = open_perf_counter(cpu, perf_pmu_types.lcore, perf_model_support->third.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP);
> if (retval == -1) {
> - err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->third.hits);
> + warnx("%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.lcore, perf_model_support->third.hits);
> free_fd_l2_percpu();
> return;
> }
> --
> 2.53.0
>
>
--
Len Brown, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] tools/power turbostat: Allow execution to continue after perf_l2_init() failure
2026-04-09 19:13 ` Len Brown
@ 2026-04-10 12:59 ` Len Brown
2026-04-10 16:06 ` David Arcari
0 siblings, 1 reply; 5+ messages in thread
From: Len Brown @ 2026-04-10 12:59 UTC (permalink / raw)
To: David Arcari; +Cc: linux-pm, linux-kernel
Thank you for the patch, David, it is helpful.
I agree that turbostat should do its best to run properly when the
underlying kernel
doesn't have full support, and you found a configuration that I missed.
I'd like to understand how/why your kernel perf support is failing on alder lake
to be sure turbostat is coping the best it can.
If you can identify an upstream kernel version that fails this way,
that would be great.
You can poke with "perf stat" as well, but this will depend on what
.json counter list is compiled into
your version of perf.
probably a first sanity check would be if these commands for the LLC
and the L2 work:
sudo perf stat -e cache-misses sleep 1
sudo perf stat -e L2_REQUEST.ALL sleep 1
Also, with your L2 patch applied, does turbostat still successfully
show the LLC stats?
thanks,
Len Brown, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] tools/power turbostat: Allow execution to continue after perf_l2_init() failure
2026-04-10 12:59 ` Len Brown
@ 2026-04-10 16:06 ` David Arcari
2026-04-10 18:09 ` Len Brown
0 siblings, 1 reply; 5+ messages in thread
From: David Arcari @ 2026-04-10 16:06 UTC (permalink / raw)
To: Len Brown; +Cc: linux-pm, linux-kernel
Hi Len,
On 4/10/26 8:59 AM, Len Brown wrote:
> Thank you for the patch, David, it is helpful.
>
> I agree that turbostat should do its best to run properly when the
> underlying kernel
> doesn't have full support, and you found a configuration that I missed.
>
> I'd like to understand how/why your kernel perf support is failing on alder lake
> to be sure turbostat is coping the best it can.
>
> If you can identify an upstream kernel version that fails this way,
> that would be great.
I'm using a Fedora kernel:
vmlinuz-7.0.0-0.rc4.260320g0e4f8f1a3d08.40.eln155.x86_64
And turbostat is:
# turbostat -v
turbostat version 2026.02.14 - Len Brown <lenb@kernel.org>
>
> You can poke with "perf stat" as well, but this will depend on what
> .json counter list is compiled into
> your version of perf.
>
> probably a first sanity check would be if these commands for the LLC
> and the L2 work:
>
> sudo perf stat -e cache-misses sleep 1
> sudo perf stat -e L2_REQUEST.ALL sleep 1
# sudo perf stat -e cache-misses sleep 1
Performance counter stats for 'sleep 1':
<not supported> cpu_atom/cache-misses/
11,212 cpu_core/cache-misses/
1.001044852 seconds time elapsed
0.000793000 seconds user
0.000000000 seconds sys
# sudo perf stat -e L2_REQUEST.ALL sleep 1
Performance counter stats for 'sleep 1':
<not supported> cpu_atom/L2_REQUEST.ALL/
98,451 cpu_core/L2_REQUEST.ALL/
1.001072723 seconds time elapsed
0.000761000 seconds user
0.000000000 seconds sys
>
> Also, with your L2 patch applied, does turbostat still successfully
> show the LLC stats?
>
# ./turbostat --quiet -s Core,CPU,LLCMRPS,LLC%hit -n 1
Core CPU LLCMRPS LLC%hit
- - 1 91.33
0 0 0 93.48
0 1 0 86.86
1 2 0 90.68
1 3 0 98.61
2 4 0 98.59
2 5 0 98.79
3 6 0 90.86
3 7 0 97.64
4 8 0 97.52
4 9 0 99.33
5 10 0 85.54
5 11 0 90.85
Let me know if you need something else.
Thanks,
-DA
> thanks,
> Len Brown, Intel Open Source Technology Center
>
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] tools/power turbostat: Allow execution to continue after perf_l2_init() failure
2026-04-10 16:06 ` David Arcari
@ 2026-04-10 18:09 ` Len Brown
0 siblings, 0 replies; 5+ messages in thread
From: Len Brown @ 2026-04-10 18:09 UTC (permalink / raw)
To: David Arcari, dapeng1.mi; +Cc: Linux PM list, Linux Kernel Mailing List
On Fri, Apr 10, 2026 at 12:06 PM David Arcari <darcari@redhat.com> wrote:
> I'm using a Fedora kernel:
>
> vmlinuz-7.0.0-0.rc4.260320g0e4f8f1a3d08.40.eln155.x86_64
>
> And turbostat is:
>
> # turbostat -v
> turbostat version 2026.02.14 - Len Brown <lenb@kernel.org>
>
> >
> > You can poke with "perf stat" as well, but this will depend on what
> > .json counter list is compiled into
> > your version of perf.
> >
> > probably a first sanity check would be if these commands for the LLC
> > and the L2 work:
> >
> > sudo perf stat -e cache-misses sleep 1
> > sudo perf stat -e L2_REQUEST.ALL sleep 1
>
> # sudo perf stat -e cache-misses sleep 1
>
> Performance counter stats for 'sleep 1':
>
> <not supported> cpu_atom/cache-misses/
I think this should work. There may be an issue either with
the perf utility or the perf kernel support on that system.
I'll cc Dapeng. Already the weekend where he is, but maybe he
can give us some perf insight next week.
thx,
-Len
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-04-10 18:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-19 14:03 [PATCH] tools/power turbostat: Allow execution to continue after perf_l2_init() failure David Arcari
2026-04-09 19:13 ` Len Brown
2026-04-10 12:59 ` Len Brown
2026-04-10 16:06 ` David Arcari
2026-04-10 18:09 ` Len Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox