| # mem-phys-addr.py: Resolve physical address samples |
| # SPDX-License-Identifier: GPL-2.0 |
| # |
| # Copyright (c) 2018, Intel Corporation. |
| |
| from __future__ import division |
| from __future__ import print_function |
| |
| import os |
| import sys |
| import struct |
| import re |
| import bisect |
| import collections |
| |
| sys.path.append(os.environ['PERF_EXEC_PATH'] + \ |
| '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') |
| |
| #physical address ranges for System RAM |
| system_ram = [] |
| #physical address ranges for Persistent Memory |
| pmem = [] |
| #file object for proc iomem |
| f = None |
| #Count for each type of memory |
| load_mem_type_cnt = collections.Counter() |
| #perf event name |
| event_name = None |
| |
| def parse_iomem(): |
| global f |
| f = open('/proc/iomem', 'r') |
| for i, j in enumerate(f): |
| m = re.split('-|:',j,2) |
| if m[2].strip() == 'System RAM': |
| system_ram.append(int(m[0], 16)) |
| system_ram.append(int(m[1], 16)) |
| if m[2].strip() == 'Persistent Memory': |
| pmem.append(int(m[0], 16)) |
| pmem.append(int(m[1], 16)) |
| |
| def print_memory_type(): |
| print("Event: %s" % (event_name)) |
| print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='') |
| print("%-40s %10s %10s\n" % ("----------------------------------------", |
| "-----------", "-----------"), |
| end=''); |
| total = sum(load_mem_type_cnt.values()) |
| for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ |
| key = lambda kv: (kv[1], kv[0]), reverse = True): |
| print("%-40s %10d %10.1f%%\n" % |
| (mem_type, count, 100 * count / total), |
| end='') |
| |
| def trace_begin(): |
| parse_iomem() |
| |
| def trace_end(): |
| print_memory_type() |
| f.close() |
| |
| def is_system_ram(phys_addr): |
| #/proc/iomem is sorted |
| position = bisect.bisect(system_ram, phys_addr) |
| if position % 2 == 0: |
| return False |
| return True |
| |
| def is_persistent_mem(phys_addr): |
| position = bisect.bisect(pmem, phys_addr) |
| if position % 2 == 0: |
| return False |
| return True |
| |
| def find_memory_type(phys_addr): |
| if phys_addr == 0: |
| return "N/A" |
| if is_system_ram(phys_addr): |
| return "System RAM" |
| |
| if is_persistent_mem(phys_addr): |
| return "Persistent Memory" |
| |
| #slow path, search all |
| f.seek(0, 0) |
| for j in f: |
| m = re.split('-|:',j,2) |
| if int(m[0], 16) <= phys_addr <= int(m[1], 16): |
| return m[2] |
| return "N/A" |
| |
| def process_event(param_dict): |
| name = param_dict["ev_name"] |
| sample = param_dict["sample"] |
| phys_addr = sample["phys_addr"] |
| |
| global event_name |
| if event_name == None: |
| event_name = name |
| load_mem_type_cnt[find_memory_type(phys_addr)] += 1 |