Re: [PATCH v2 26/58] perf mem-phys-addr: Port mem-phys-addr to use python module

sashiko-bot
2026-04-23T04:10:28Z

Sashiko AI review found 3 potential issue(s):
- [High] Excessive error logging in `find_memory_type` can cause console spam and severe performance degradation.
- [Medium] Python API compatibility breakage due to Python 3.10+ specific features.
- [Medium] Logic error in binary search result handling leads to unintended negative indexing.
--

commit cd8c15e87c970c83acdb9decf2e94c2d6f8dbf59
Author: Ian Rogers <irogers@google.com>

perf mem-phys-addr: Port mem-phys-addr to use python module

This commit provides an example of using the perf python session API to
load a perf.data file and resolve physical address samples using
/proc/iomem.

> diff --git a/tools/perf/python/mem-phys-addr.py b/tools/perf/python/mem-phys-addr.py
> new file mode 100755
> index 0000000000000..ba874d7a2011c
> --- /dev/null
> +++ b/tools/perf/python/mem-phys-addr.py
> @@ -0,0 +1,117 @@

[ ... ]

> +import collections
> +from dataclasses import dataclass
> +import re
> +from typing import (Dict, Optional)
> +
> +import perf
> +
> +@dataclass(frozen=True)
> +class IomemEntry:
> + """Read from a line in /proc/iomem"""
> + begin: int
> + end: int
> + indent: int
> + label: str
> +
> +# Physical memory layout from /proc/iomem. Key is the indent and then
> +# a list of ranges.
> +iomem: Dict[int, list[IomemEntry]] = collections.defaultdict(list)

Will this break compatibility on older Python versions?

Generic built-in collections for type hinting like list[IomemEntry] were
added in Python 3.9. Running this on enterprise distributions that ship with
Python 3.6 to 3.8 might result in an immediate TypeError crash.

[ ... ]

> +def find_memory_type(phys_addr) -> Optional[IomemEntry]:
> + """Search iomem for the range containing phys_addr with the maximum indent"""
> + for i in range(max_indent, -1, -1):
> + if i not in iomem:
> + continue
> + position = bisect.bisect_right(iomem[i], phys_addr,
> + key=lambda entry: entry.begin)

The key parameter for bisect.bisect_right was introduced in Python 3.10. Could
this cause similar compatibility issues on older setups?

> + if position is None:
> + continue
> + iomem_entry = iomem[i][position-1]

Does this handle cases where phys_addr is smaller than the first element
correctly?

bisect.bisect_right always returns an integer, not None. If it returns 0,
position-1 becomes -1, which will wrap around and unintentionally access the
last element in the iomem[i] list.

> + if iomem_entry.begin <= phys_addr <= iomem_entry.end:
> + return iomem_entry
> + print(f"Didn't find {phys_addr}")

Can this cause console spam and slow down execution?

Since find_memory_type() is called for every sample event, printing to stdout
whenever an address cannot be mapped could flood the console. If there are
millions of unresolved addresses (for example, if addresses aren't recorded
or are missing from an unprivileged user's /proc/iomem), this might completely
bottleneck execution time.

> + return None

--
Sashiko AI review · https://sashiko.dev/#/patchset/20260423035526.1537178-1-irogers@google.com?part=26