forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.4 KiB
100 lines
2.4 KiB
# 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
|
|
|