* [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py
@ 2026-09-25 20:47 Arnaldo Carvalho de Melo
2026-09-25 20:54 ` sashiko-bot
2026-09-25 20:57 ` Ian Rogers
0 siblings, 2 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-09-25 20:47 UTC (permalink / raw)
To: Ian Rogers
Cc: Adrian Hunter, James Clark, Jiri Olsa, Namhyung Kim,
linux-perf-users
perf's build still accepts Python 3.6: Makefile.config only rejects
interpreters older than 3.6 and jevents.py keeps its own removesuffix()
shim for it, but two recently added constructs are evaluated when the
module or the function is defined and only work on newer interpreters.
PEP 585's list[...] became subscriptable in Python 3.9, so the module
level annotations in jevents.py make Kbuild die at import time:
TypeError: 'type' object is not subscriptable
make[3]: *** [pmu-events/Build:176: .../test-empty-pmu-events.c] Error 1
as seen on almalinux:8 with its python3.6.8, and the list[str]
parameters of util/setup.py's functions fail the same way when the
python binding is built.
ProcessPoolExecutor(initializer=, initargs=) was added in Python 3.7,
so generating pmu-events.c dies when the pool is created.
Use the typing generics that exist on every supported interpreter and
only pass initializer/initargs when the interpreter has them: on 3.6
the default fork start method already leaves the worker processes with
the parent's _arch_std_events, which is what _init_worker() sets up
for spawn semantics.
Tested with Python 3.6.15: make -C tools/perf completes, generating
pmu-events.c and the python binding.
Fixes: cda907c2c3f99 ("perf jevents: Add python type annotations")
Fixes: 1fa8d81be1eb ("perf python: Clean up and restructure setup.py")
Fixes: eaab2eb09dc2 ("perf pmu-events: Parallelize JSON and metric pre-computation in jevents.py")
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/pmu-events/jevents.py | 24 +++++++++++++++---------
tools/perf/util/setup.py | 5 +++--
2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 074daae5308b110b..bdc89ec197680c1b 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -8,19 +8,19 @@ import json
import metric
import os
import sys
-from typing import (Callable, Dict, Optional, Sequence, Set, Tuple)
+from typing import (Any, Callable, Dict, List, Optional, Sequence, Set, Tuple)
import collections
# Global command line arguments.
_args = None
# List of regular event tables.
-_event_tables: list[str] = []
+_event_tables: List[str] = []
# List of event tables generated from "/sys" directories.
-_sys_event_tables: list[str] = []
+_sys_event_tables: List[str] = []
# List of regular metric tables.
-_metric_tables: list[str] = []
+_metric_tables: List[str] = []
# List of metric tables generated from "/sys" directories.
-_sys_metric_tables: list[str] = []
+_sys_metric_tables: List[str] = []
# Mapping between sys event table names and sys metric table names.
_sys_event_table_to_metric_table_mapping = {}
# Map from an event name to an architecture standard
@@ -28,11 +28,11 @@ _sys_event_table_to_metric_table_mapping = {}
# f'{_args.starting_dir}/{_args.arch}' directory.
_arch_std_events: Dict[str, "JsonEvent"] = {}
# Events to write out when the table is closed
-_pending_events: list["JsonEvent"] = []
+_pending_events: List["JsonEvent"] = []
# Name of events table to be written out
_pending_events_tblname: Optional[str] = None
# Metrics to write out when the table is closed
-_pending_metrics: list["JsonEvent"] = []
+_pending_metrics: List["JsonEvent"] = []
# Name of metrics table to be written out
_pending_metrics_tblname: Optional[str] = None
# Global BigCString shared by all structures.
@@ -1556,9 +1556,15 @@ struct pmu_table_entry {
preprocess_arch_std_files(arch_path)
ftw(arch_path, [], collect_json)
+ # ProcessPoolExecutor's initializer/initargs need Python 3.7, on 3.6 the
+ # fork start method already leaves the workers with the parent's
+ # _arch_std_events, i.e. what _init_worker would set up.
+ executor_kwargs: Dict[str, Any] = {}
+ if sys.version_info >= (3, 7):
+ executor_kwargs = dict(initializer=_init_worker,
+ initargs=(_arch_std_events,))
with concurrent.futures.ProcessPoolExecutor(max_workers=_parallel_worker_count(len(tasks)),
- initializer=_init_worker,
- initargs=(_arch_std_events,)) as executor:
+ **executor_kwargs) as executor:
for path, topic, events in executor.map(_parallel_read_json_events, tasks):
_json_cache[(path, topic)] = events
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index 8380980ade4c486f..ad904b374ec6eaba 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -11,13 +11,14 @@ import shlex
import shutil
import subprocess
import sysconfig
+from typing import List
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext as _build_ext
from setuptools.command.install_lib import install_lib as _install_lib
-def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option: str) -> bool:
+def clang_has_option(cc: str, cc_args: List[str], src_feature_tests: str, option: str) -> bool:
"""Check if clang supports a specific option.
Args:
@@ -47,7 +48,7 @@ def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option
return not any(any(error in line for error in error_substrings) for line in cc_output)
-def filter_clang_options(cc: str, cc_args: list[str], src_feature_tests: str) -> None:
+def filter_clang_options(cc: str, cc_args: List[str], src_feature_tests: str) -> None:
"""Filter out unsupported clang options from sysconfig CFLAGS and OPT.
Args:
--
2.55.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py
2026-09-25 20:47 [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py Arnaldo Carvalho de Melo
@ 2026-09-25 20:54 ` sashiko-bot
2026-09-25 20:57 ` Ian Rogers
1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-09-25 20:54 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
> perf's build still accepts Python 3.6: Makefile.config only rejects
> interpreters older than 3.6 and jevents.py keeps its own removesuffix()
> shim for it, but two recently added constructs are evaluated when the
> module or the function is defined and only work on newer interpreters.
>
> PEP 585's list[...] became subscriptable in Python 3.9, so the module
> level annotations in jevents.py make Kbuild die at import time:
>
> TypeError: 'type' object is not subscriptable
> make[3]: *** [pmu-events/Build:176: .../test-empty-pmu-events.c] Error 1
>
> as seen on almalinux:8 with its python3.6.8, and the list[str]
> parameters of util/setup.py's functions fail the same way when the
> python binding is built.
>
> [ ... ]
> Fixes: cda907c2c3f99 ("perf jevents: Add python type annotations")
> Fixes: 1fa8d81be1eb ("perf python: Clean up and restructure setup.py")
> Fixes: eaab2eb09dc2 ("perf pmu-events: Parallelize JSON and metric pre-computation in jevents.py")
> Assisted-by: LLM
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/arbd4TJm4s9MVjN-@x2?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py
2026-09-25 20:47 [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py Arnaldo Carvalho de Melo
2026-09-25 20:54 ` sashiko-bot
@ 2026-09-25 20:57 ` Ian Rogers
2026-09-25 21:14 ` Arnaldo Carvalho de Melo
1 sibling, 1 reply; 7+ messages in thread
From: Ian Rogers @ 2026-09-25 20:57 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Adrian Hunter, James Clark, Jiri Olsa, Namhyung Kim,
linux-perf-users
On Fri, Sep 25, 2026 at 1:47 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> perf's build still accepts Python 3.6: Makefile.config only rejects
> interpreters older than 3.6 and jevents.py keeps its own removesuffix()
> shim for it, but two recently added constructs are evaluated when the
> module or the function is defined and only work on newer interpreters.
Could we remove the shim and bump the minimum Python version to 3.9 to
be in line with the rest of the kernel build?
https://github.com/torvalds/linux/blob/master/Documentation/process/changes.rst
Thanks,
Ian
> PEP 585's list[...] became subscriptable in Python 3.9, so the module
> level annotations in jevents.py make Kbuild die at import time:
>
> TypeError: 'type' object is not subscriptable
> make[3]: *** [pmu-events/Build:176: .../test-empty-pmu-events.c] Error 1
>
> as seen on almalinux:8 with its python3.6.8, and the list[str]
> parameters of util/setup.py's functions fail the same way when the
> python binding is built.
>
> ProcessPoolExecutor(initializer=, initargs=) was added in Python 3.7,
> so generating pmu-events.c dies when the pool is created.
>
> Use the typing generics that exist on every supported interpreter and
> only pass initializer/initargs when the interpreter has them: on 3.6
> the default fork start method already leaves the worker processes with
> the parent's _arch_std_events, which is what _init_worker() sets up
> for spawn semantics.
>
> Tested with Python 3.6.15: make -C tools/perf completes, generating
> pmu-events.c and the python binding.
>
> Fixes: cda907c2c3f99 ("perf jevents: Add python type annotations")
> Fixes: 1fa8d81be1eb ("perf python: Clean up and restructure setup.py")
> Fixes: eaab2eb09dc2 ("perf pmu-events: Parallelize JSON and metric pre-computation in jevents.py")
> Assisted-by: LLM
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
> tools/perf/pmu-events/jevents.py | 24 +++++++++++++++---------
> tools/perf/util/setup.py | 5 +++--
> 2 files changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
> index 074daae5308b110b..bdc89ec197680c1b 100755
> --- a/tools/perf/pmu-events/jevents.py
> +++ b/tools/perf/pmu-events/jevents.py
> @@ -8,19 +8,19 @@ import json
> import metric
> import os
> import sys
> -from typing import (Callable, Dict, Optional, Sequence, Set, Tuple)
> +from typing import (Any, Callable, Dict, List, Optional, Sequence, Set, Tuple)
> import collections
>
> # Global command line arguments.
> _args = None
> # List of regular event tables.
> -_event_tables: list[str] = []
> +_event_tables: List[str] = []
> # List of event tables generated from "/sys" directories.
> -_sys_event_tables: list[str] = []
> +_sys_event_tables: List[str] = []
> # List of regular metric tables.
> -_metric_tables: list[str] = []
> +_metric_tables: List[str] = []
> # List of metric tables generated from "/sys" directories.
> -_sys_metric_tables: list[str] = []
> +_sys_metric_tables: List[str] = []
> # Mapping between sys event table names and sys metric table names.
> _sys_event_table_to_metric_table_mapping = {}
> # Map from an event name to an architecture standard
> @@ -28,11 +28,11 @@ _sys_event_table_to_metric_table_mapping = {}
> # f'{_args.starting_dir}/{_args.arch}' directory.
> _arch_std_events: Dict[str, "JsonEvent"] = {}
> # Events to write out when the table is closed
> -_pending_events: list["JsonEvent"] = []
> +_pending_events: List["JsonEvent"] = []
> # Name of events table to be written out
> _pending_events_tblname: Optional[str] = None
> # Metrics to write out when the table is closed
> -_pending_metrics: list["JsonEvent"] = []
> +_pending_metrics: List["JsonEvent"] = []
> # Name of metrics table to be written out
> _pending_metrics_tblname: Optional[str] = None
> # Global BigCString shared by all structures.
> @@ -1556,9 +1556,15 @@ struct pmu_table_entry {
> preprocess_arch_std_files(arch_path)
> ftw(arch_path, [], collect_json)
>
> + # ProcessPoolExecutor's initializer/initargs need Python 3.7, on 3.6 the
> + # fork start method already leaves the workers with the parent's
> + # _arch_std_events, i.e. what _init_worker would set up.
> + executor_kwargs: Dict[str, Any] = {}
> + if sys.version_info >= (3, 7):
> + executor_kwargs = dict(initializer=_init_worker,
> + initargs=(_arch_std_events,))
> with concurrent.futures.ProcessPoolExecutor(max_workers=_parallel_worker_count(len(tasks)),
> - initializer=_init_worker,
> - initargs=(_arch_std_events,)) as executor:
> + **executor_kwargs) as executor:
> for path, topic, events in executor.map(_parallel_read_json_events, tasks):
> _json_cache[(path, topic)] = events
>
> diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
> index 8380980ade4c486f..ad904b374ec6eaba 100644
> --- a/tools/perf/util/setup.py
> +++ b/tools/perf/util/setup.py
> @@ -11,13 +11,14 @@ import shlex
> import shutil
> import subprocess
> import sysconfig
> +from typing import List
>
> from setuptools import setup, Extension
> from setuptools.command.build_ext import build_ext as _build_ext
> from setuptools.command.install_lib import install_lib as _install_lib
>
>
> -def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option: str) -> bool:
> +def clang_has_option(cc: str, cc_args: List[str], src_feature_tests: str, option: str) -> bool:
> """Check if clang supports a specific option.
>
> Args:
> @@ -47,7 +48,7 @@ def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option
> return not any(any(error in line for error in error_substrings) for line in cc_output)
>
>
> -def filter_clang_options(cc: str, cc_args: list[str], src_feature_tests: str) -> None:
> +def filter_clang_options(cc: str, cc_args: List[str], src_feature_tests: str) -> None:
> """Filter out unsupported clang options from sysconfig CFLAGS and OPT.
>
> Args:
> --
> 2.55.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py
2026-09-25 20:57 ` Ian Rogers
@ 2026-09-25 21:14 ` Arnaldo Carvalho de Melo
2026-09-25 21:29 ` Ian Rogers
0 siblings, 1 reply; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-09-25 21:14 UTC (permalink / raw)
To: Ian Rogers
Cc: Adrian Hunter, James Clark, Jiri Olsa, Namhyung Kim,
linux-perf-users
On Fri, Sep 25, 2026 at 01:57:06PM -0700, Ian Rogers wrote:
> On Fri, Sep 25, 2026 at 1:47 PM Arnaldo Carvalho de Melo
> <acme@kernel.org> wrote:
> >
> > perf's build still accepts Python 3.6: Makefile.config only rejects
> > interpreters older than 3.6 and jevents.py keeps its own removesuffix()
> > shim for it, but two recently added constructs are evaluated when the
> > module or the function is defined and only work on newer interpreters.
>
> Could we remove the shim and bump the minimum Python version to 3.9 to
> be in line with the rest of the kernel build?
> https://github.com/torvalds/linux/blob/master/Documentation/process/changes.rst
Since RHEL8 based systems will still be in use for a long time and new
perf versions can be useful in solving problems in such systems, maybe
we should keep the support on 3.6 as is now :-\
This patch is not that big and fixes the only cases where python 3.6 was
breaking, so maybe this is not unreasonable to do.
- Arnaldo
> Thanks,
> Ian
>
> > PEP 585's list[...] became subscriptable in Python 3.9, so the module
> > level annotations in jevents.py make Kbuild die at import time:
> >
> > TypeError: 'type' object is not subscriptable
> > make[3]: *** [pmu-events/Build:176: .../test-empty-pmu-events.c] Error 1
> >
> > as seen on almalinux:8 with its python3.6.8, and the list[str]
> > parameters of util/setup.py's functions fail the same way when the
> > python binding is built.
> >
> > ProcessPoolExecutor(initializer=, initargs=) was added in Python 3.7,
> > so generating pmu-events.c dies when the pool is created.
> >
> > Use the typing generics that exist on every supported interpreter and
> > only pass initializer/initargs when the interpreter has them: on 3.6
> > the default fork start method already leaves the worker processes with
> > the parent's _arch_std_events, which is what _init_worker() sets up
> > for spawn semantics.
> >
> > Tested with Python 3.6.15: make -C tools/perf completes, generating
> > pmu-events.c and the python binding.
> >
> > Fixes: cda907c2c3f99 ("perf jevents: Add python type annotations")
> > Fixes: 1fa8d81be1eb ("perf python: Clean up and restructure setup.py")
> > Fixes: eaab2eb09dc2 ("perf pmu-events: Parallelize JSON and metric pre-computation in jevents.py")
> > Assisted-by: LLM
> > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > ---
> > tools/perf/pmu-events/jevents.py | 24 +++++++++++++++---------
> > tools/perf/util/setup.py | 5 +++--
> > 2 files changed, 18 insertions(+), 11 deletions(-)
> >
> > diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
> > index 074daae5308b110b..bdc89ec197680c1b 100755
> > --- a/tools/perf/pmu-events/jevents.py
> > +++ b/tools/perf/pmu-events/jevents.py
> > @@ -8,19 +8,19 @@ import json
> > import metric
> > import os
> > import sys
> > -from typing import (Callable, Dict, Optional, Sequence, Set, Tuple)
> > +from typing import (Any, Callable, Dict, List, Optional, Sequence, Set, Tuple)
> > import collections
> >
> > # Global command line arguments.
> > _args = None
> > # List of regular event tables.
> > -_event_tables: list[str] = []
> > +_event_tables: List[str] = []
> > # List of event tables generated from "/sys" directories.
> > -_sys_event_tables: list[str] = []
> > +_sys_event_tables: List[str] = []
> > # List of regular metric tables.
> > -_metric_tables: list[str] = []
> > +_metric_tables: List[str] = []
> > # List of metric tables generated from "/sys" directories.
> > -_sys_metric_tables: list[str] = []
> > +_sys_metric_tables: List[str] = []
> > # Mapping between sys event table names and sys metric table names.
> > _sys_event_table_to_metric_table_mapping = {}
> > # Map from an event name to an architecture standard
> > @@ -28,11 +28,11 @@ _sys_event_table_to_metric_table_mapping = {}
> > # f'{_args.starting_dir}/{_args.arch}' directory.
> > _arch_std_events: Dict[str, "JsonEvent"] = {}
> > # Events to write out when the table is closed
> > -_pending_events: list["JsonEvent"] = []
> > +_pending_events: List["JsonEvent"] = []
> > # Name of events table to be written out
> > _pending_events_tblname: Optional[str] = None
> > # Metrics to write out when the table is closed
> > -_pending_metrics: list["JsonEvent"] = []
> > +_pending_metrics: List["JsonEvent"] = []
> > # Name of metrics table to be written out
> > _pending_metrics_tblname: Optional[str] = None
> > # Global BigCString shared by all structures.
> > @@ -1556,9 +1556,15 @@ struct pmu_table_entry {
> > preprocess_arch_std_files(arch_path)
> > ftw(arch_path, [], collect_json)
> >
> > + # ProcessPoolExecutor's initializer/initargs need Python 3.7, on 3.6 the
> > + # fork start method already leaves the workers with the parent's
> > + # _arch_std_events, i.e. what _init_worker would set up.
> > + executor_kwargs: Dict[str, Any] = {}
> > + if sys.version_info >= (3, 7):
> > + executor_kwargs = dict(initializer=_init_worker,
> > + initargs=(_arch_std_events,))
> > with concurrent.futures.ProcessPoolExecutor(max_workers=_parallel_worker_count(len(tasks)),
> > - initializer=_init_worker,
> > - initargs=(_arch_std_events,)) as executor:
> > + **executor_kwargs) as executor:
> > for path, topic, events in executor.map(_parallel_read_json_events, tasks):
> > _json_cache[(path, topic)] = events
> >
> > diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
> > index 8380980ade4c486f..ad904b374ec6eaba 100644
> > --- a/tools/perf/util/setup.py
> > +++ b/tools/perf/util/setup.py
> > @@ -11,13 +11,14 @@ import shlex
> > import shutil
> > import subprocess
> > import sysconfig
> > +from typing import List
> >
> > from setuptools import setup, Extension
> > from setuptools.command.build_ext import build_ext as _build_ext
> > from setuptools.command.install_lib import install_lib as _install_lib
> >
> >
> > -def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option: str) -> bool:
> > +def clang_has_option(cc: str, cc_args: List[str], src_feature_tests: str, option: str) -> bool:
> > """Check if clang supports a specific option.
> >
> > Args:
> > @@ -47,7 +48,7 @@ def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option
> > return not any(any(error in line for error in error_substrings) for line in cc_output)
> >
> >
> > -def filter_clang_options(cc: str, cc_args: list[str], src_feature_tests: str) -> None:
> > +def filter_clang_options(cc: str, cc_args: List[str], src_feature_tests: str) -> None:
> > """Filter out unsupported clang options from sysconfig CFLAGS and OPT.
> >
> > Args:
> > --
> > 2.55.0
> >
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py
2026-09-25 21:14 ` Arnaldo Carvalho de Melo
@ 2026-09-25 21:29 ` Ian Rogers
2026-09-25 21:52 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 7+ messages in thread
From: Ian Rogers @ 2026-09-25 21:29 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Adrian Hunter, James Clark, Jiri Olsa, Namhyung Kim,
linux-perf-users
On Fri, Sep 25, 2026 at 2:14 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> On Fri, Sep 25, 2026 at 01:57:06PM -0700, Ian Rogers wrote:
> > On Fri, Sep 25, 2026 at 1:47 PM Arnaldo Carvalho de Melo
> > <acme@kernel.org> wrote:
> > >
> > > perf's build still accepts Python 3.6: Makefile.config only rejects
> > > interpreters older than 3.6 and jevents.py keeps its own removesuffix()
> > > shim for it, but two recently added constructs are evaluated when the
> > > module or the function is defined and only work on newer interpreters.
> >
> > Could we remove the shim and bump the minimum Python version to 3.9 to
> > be in line with the rest of the kernel build?
> > https://github.com/torvalds/linux/blob/master/Documentation/process/changes.rst
>
> Since RHEL8 based systems will still be in use for a long time and new
> perf versions can be useful in solving problems in such systems, maybe
> we should keep the support on 3.6 as is now :-\
>
> This patch is not that big and fixes the only cases where python 3.6 was
> breaking, so maybe this is not unreasonable to do.
Could we update the review prompts for this then? Currently the
prompts load from changes.rst:
https://github.com/masoncl/review-prompts/blob/main/kernel/subsystem/build.md
and so Python 3.9. We can then comment that we're doing this for RHEL8 support.
RHEL8 appears to be in maintenance mode:
https://endoflife.date/rhel
which means "New functionality and new hardware enablement are not
planned for availability in the Maintenance Support Phase."
https://access.redhat.com/support/policy/updates/errata#Maintenance_Support_Phase
So is RHEL8 support only necessary for people building the code
themselves? In that case, they could also update their Python?
Thanks,
Ian
> - Arnaldo
>
> > Thanks,
> > Ian
> >
> > > PEP 585's list[...] became subscriptable in Python 3.9, so the module
> > > level annotations in jevents.py make Kbuild die at import time:
> > >
> > > TypeError: 'type' object is not subscriptable
> > > make[3]: *** [pmu-events/Build:176: .../test-empty-pmu-events.c] Error 1
> > >
> > > as seen on almalinux:8 with its python3.6.8, and the list[str]
> > > parameters of util/setup.py's functions fail the same way when the
> > > python binding is built.
> > >
> > > ProcessPoolExecutor(initializer=, initargs=) was added in Python 3.7,
> > > so generating pmu-events.c dies when the pool is created.
> > >
> > > Use the typing generics that exist on every supported interpreter and
> > > only pass initializer/initargs when the interpreter has them: on 3.6
> > > the default fork start method already leaves the worker processes with
> > > the parent's _arch_std_events, which is what _init_worker() sets up
> > > for spawn semantics.
> > >
> > > Tested with Python 3.6.15: make -C tools/perf completes, generating
> > > pmu-events.c and the python binding.
> > >
> > > Fixes: cda907c2c3f99 ("perf jevents: Add python type annotations")
> > > Fixes: 1fa8d81be1eb ("perf python: Clean up and restructure setup.py")
> > > Fixes: eaab2eb09dc2 ("perf pmu-events: Parallelize JSON and metric pre-computation in jevents.py")
> > > Assisted-by: LLM
> > > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > > ---
> > > tools/perf/pmu-events/jevents.py | 24 +++++++++++++++---------
> > > tools/perf/util/setup.py | 5 +++--
> > > 2 files changed, 18 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
> > > index 074daae5308b110b..bdc89ec197680c1b 100755
> > > --- a/tools/perf/pmu-events/jevents.py
> > > +++ b/tools/perf/pmu-events/jevents.py
> > > @@ -8,19 +8,19 @@ import json
> > > import metric
> > > import os
> > > import sys
> > > -from typing import (Callable, Dict, Optional, Sequence, Set, Tuple)
> > > +from typing import (Any, Callable, Dict, List, Optional, Sequence, Set, Tuple)
> > > import collections
> > >
> > > # Global command line arguments.
> > > _args = None
> > > # List of regular event tables.
> > > -_event_tables: list[str] = []
> > > +_event_tables: List[str] = []
> > > # List of event tables generated from "/sys" directories.
> > > -_sys_event_tables: list[str] = []
> > > +_sys_event_tables: List[str] = []
> > > # List of regular metric tables.
> > > -_metric_tables: list[str] = []
> > > +_metric_tables: List[str] = []
> > > # List of metric tables generated from "/sys" directories.
> > > -_sys_metric_tables: list[str] = []
> > > +_sys_metric_tables: List[str] = []
> > > # Mapping between sys event table names and sys metric table names.
> > > _sys_event_table_to_metric_table_mapping = {}
> > > # Map from an event name to an architecture standard
> > > @@ -28,11 +28,11 @@ _sys_event_table_to_metric_table_mapping = {}
> > > # f'{_args.starting_dir}/{_args.arch}' directory.
> > > _arch_std_events: Dict[str, "JsonEvent"] = {}
> > > # Events to write out when the table is closed
> > > -_pending_events: list["JsonEvent"] = []
> > > +_pending_events: List["JsonEvent"] = []
> > > # Name of events table to be written out
> > > _pending_events_tblname: Optional[str] = None
> > > # Metrics to write out when the table is closed
> > > -_pending_metrics: list["JsonEvent"] = []
> > > +_pending_metrics: List["JsonEvent"] = []
> > > # Name of metrics table to be written out
> > > _pending_metrics_tblname: Optional[str] = None
> > > # Global BigCString shared by all structures.
> > > @@ -1556,9 +1556,15 @@ struct pmu_table_entry {
> > > preprocess_arch_std_files(arch_path)
> > > ftw(arch_path, [], collect_json)
> > >
> > > + # ProcessPoolExecutor's initializer/initargs need Python 3.7, on 3.6 the
> > > + # fork start method already leaves the workers with the parent's
> > > + # _arch_std_events, i.e. what _init_worker would set up.
> > > + executor_kwargs: Dict[str, Any] = {}
> > > + if sys.version_info >= (3, 7):
> > > + executor_kwargs = dict(initializer=_init_worker,
> > > + initargs=(_arch_std_events,))
> > > with concurrent.futures.ProcessPoolExecutor(max_workers=_parallel_worker_count(len(tasks)),
> > > - initializer=_init_worker,
> > > - initargs=(_arch_std_events,)) as executor:
> > > + **executor_kwargs) as executor:
> > > for path, topic, events in executor.map(_parallel_read_json_events, tasks):
> > > _json_cache[(path, topic)] = events
> > >
> > > diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
> > > index 8380980ade4c486f..ad904b374ec6eaba 100644
> > > --- a/tools/perf/util/setup.py
> > > +++ b/tools/perf/util/setup.py
> > > @@ -11,13 +11,14 @@ import shlex
> > > import shutil
> > > import subprocess
> > > import sysconfig
> > > +from typing import List
> > >
> > > from setuptools import setup, Extension
> > > from setuptools.command.build_ext import build_ext as _build_ext
> > > from setuptools.command.install_lib import install_lib as _install_lib
> > >
> > >
> > > -def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option: str) -> bool:
> > > +def clang_has_option(cc: str, cc_args: List[str], src_feature_tests: str, option: str) -> bool:
> > > """Check if clang supports a specific option.
> > >
> > > Args:
> > > @@ -47,7 +48,7 @@ def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option
> > > return not any(any(error in line for error in error_substrings) for line in cc_output)
> > >
> > >
> > > -def filter_clang_options(cc: str, cc_args: list[str], src_feature_tests: str) -> None:
> > > +def filter_clang_options(cc: str, cc_args: List[str], src_feature_tests: str) -> None:
> > > """Filter out unsupported clang options from sysconfig CFLAGS and OPT.
> > >
> > > Args:
> > > --
> > > 2.55.0
> > >
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py
2026-09-25 21:29 ` Ian Rogers
@ 2026-09-25 21:52 ` Arnaldo Carvalho de Melo
2026-09-25 22:20 ` Ian Rogers
0 siblings, 1 reply; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-09-25 21:52 UTC (permalink / raw)
To: Ian Rogers
Cc: Adrian Hunter, James Clark, Jiri Olsa, Namhyung Kim,
linux-perf-users
On Fri, Sep 25, 2026 at 02:29:12PM -0700, Ian Rogers wrote:
> On Fri, Sep 25, 2026 at 2:14 PM Arnaldo Carvalho de Melo
> <acme@kernel.org> wrote:
> >
> > On Fri, Sep 25, 2026 at 01:57:06PM -0700, Ian Rogers wrote:
> > > On Fri, Sep 25, 2026 at 1:47 PM Arnaldo Carvalho de Melo
> > > <acme@kernel.org> wrote:
> > > >
> > > > perf's build still accepts Python 3.6: Makefile.config only rejects
> > > > interpreters older than 3.6 and jevents.py keeps its own removesuffix()
> > > > shim for it, but two recently added constructs are evaluated when the
> > > > module or the function is defined and only work on newer interpreters.
> > >
> > > Could we remove the shim and bump the minimum Python version to 3.9 to
> > > be in line with the rest of the kernel build?
> > > https://github.com/torvalds/linux/blob/master/Documentation/process/changes.rst
> >
> > Since RHEL8 based systems will still be in use for a long time and new
> > perf versions can be useful in solving problems in such systems, maybe
> > we should keep the support on 3.6 as is now :-\
> >
> > This patch is not that big and fixes the only cases where python 3.6 was
> > breaking, so maybe this is not unreasonable to do.
>
> Could we update the review prompts for this then? Currently the
> prompts load from changes.rst:
> https://github.com/masoncl/review-prompts/blob/main/kernel/subsystem/build.md
> and so Python 3.9. We can then comment that we're doing this for RHEL8 support.
I didn't know about python 3.9 being the minimal version for kernel
python usage.
> RHEL8 appears to be in maintenance mode:
> https://endoflife.date/rhel
> which means "New functionality and new hardware enablement are not
> planned for availability in the Maintenance Support Phase."
> https://access.redhat.com/support/policy/updates/errata#Maintenance_Support_Phase
> So is RHEL8 support only necessary for people building the code
> themselves? In that case, they could also update their Python?
Fair enough, I'm reworking the patch to instead make 3.9 be the minimal
for perf as well.
- Arnaldo
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py
2026-09-25 21:52 ` Arnaldo Carvalho de Melo
@ 2026-09-25 22:20 ` Ian Rogers
0 siblings, 0 replies; 7+ messages in thread
From: Ian Rogers @ 2026-09-25 22:20 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Adrian Hunter, James Clark, Jiri Olsa, Namhyung Kim,
linux-perf-users
On Fri, Sep 25, 2026 at 2:52 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> On Fri, Sep 25, 2026 at 02:29:12PM -0700, Ian Rogers wrote:
> > On Fri, Sep 25, 2026 at 2:14 PM Arnaldo Carvalho de Melo
> > <acme@kernel.org> wrote:
> > >
> > > On Fri, Sep 25, 2026 at 01:57:06PM -0700, Ian Rogers wrote:
> > > > On Fri, Sep 25, 2026 at 1:47 PM Arnaldo Carvalho de Melo
> > > > <acme@kernel.org> wrote:
> > > > >
> > > > > perf's build still accepts Python 3.6: Makefile.config only rejects
> > > > > interpreters older than 3.6 and jevents.py keeps its own removesuffix()
> > > > > shim for it, but two recently added constructs are evaluated when the
> > > > > module or the function is defined and only work on newer interpreters.
> > > >
> > > > Could we remove the shim and bump the minimum Python version to 3.9 to
> > > > be in line with the rest of the kernel build?
> > > > https://github.com/torvalds/linux/blob/master/Documentation/process/changes.rst
> > >
> > > Since RHEL8 based systems will still be in use for a long time and new
> > > perf versions can be useful in solving problems in such systems, maybe
> > > we should keep the support on 3.6 as is now :-\
> > >
> > > This patch is not that big and fixes the only cases where python 3.6 was
> > > breaking, so maybe this is not unreasonable to do.
> >
> > Could we update the review prompts for this then? Currently the
> > prompts load from changes.rst:
> > https://github.com/masoncl/review-prompts/blob/main/kernel/subsystem/build.md
> > and so Python 3.9. We can then comment that we're doing this for RHEL8 support.
>
> I didn't know about python 3.9 being the minimal version for kernel
> python usage.
>
> > RHEL8 appears to be in maintenance mode:
> > https://endoflife.date/rhel
> > which means "New functionality and new hardware enablement are not
> > planned for availability in the Maintenance Support Phase."
> > https://access.redhat.com/support/policy/updates/errata#Maintenance_Support_Phase
> > So is RHEL8 support only necessary for people building the code
> > themselves? In that case, they could also update their Python?
>
> Fair enough, I'm reworking the patch to instead make 3.9 be the minimal
> for perf as well.
Thanks! In the python series:
https://lore.kernel.org/linux-perf-users/cover.1789880842.git.irogers@google.com/
I enabled mypy and pylint checking to ensure we have some standards.
This would catch features supported in 3.9 but not in 3.6. It's nice
to have less __future__ type things by using 3.9.
Ian
> - Arnaldo
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-25 22:20 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-25 20:47 [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py Arnaldo Carvalho de Melo
2026-09-25 20:54 ` sashiko-bot
2026-09-25 20:57 ` Ian Rogers
2026-09-25 21:14 ` Arnaldo Carvalho de Melo
2026-09-25 21:29 ` Ian Rogers
2026-09-25 21:52 ` Arnaldo Carvalho de Melo
2026-09-25 22:20 ` Ian Rogers
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.