1# mem-phys-addr.py: Resolve physical address samples 2# SPDX-License-Identifier: GPL-2.0 3# 4# Copyright (c) 2018, Intel Corporation. 5 6from __future__ import division 7from __future__ import print_function 8 9import os 10import sys 11import struct 12import re 13import bisect 14import collections 15 16sys.path.append(os.environ['PERF_EXEC_PATH'] + \ 17 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 18 19#physical address ranges for System RAM 20system_ram = [] 21#physical address ranges for Persistent Memory 22pmem = [] 23#file object for proc iomem 24f = None 25#Count for each type of memory 26load_mem_type_cnt = collections.Counter() 27#perf event name 28event_name = None 29 30def parse_iomem(): 31 global f 32 f = open('/proc/iomem', 'r') 33 for i, j in enumerate(f): 34 m = re.split('-|:',j,2) 35 if m[2].strip() == 'System RAM': 36 system_ram.append(int(m[0], 16)) 37 system_ram.append(int(m[1], 16)) 38 if m[2].strip() == 'Persistent Memory': 39 pmem.append(int(m[0], 16)) 40 pmem.append(int(m[1], 16)) 41 42def print_memory_type(): 43 print("Event: %s" % (event_name)) 44 print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='') 45 print("%-40s %10s %10s\n" % ("----------------------------------------", 46 "-----------", "-----------"), 47 end=''); 48 total = sum(load_mem_type_cnt.values()) 49 for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ 50 key = lambda kv: (kv[1], kv[0]), reverse = True): 51 print("%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total), 52 end='') 53 54def trace_begin(): 55 parse_iomem() 56 57def trace_end(): 58 print_memory_type() 59 f.close() 60 61def is_system_ram(phys_addr): 62 #/proc/iomem is sorted 63 position = bisect.bisect(system_ram, phys_addr) 64 if position % 2 == 0: 65 return False 66 return True 67 68def is_persistent_mem(phys_addr): 69 position = bisect.bisect(pmem, phys_addr) 70 if position % 2 == 0: 71 return False 72 return True 73 74def find_memory_type(phys_addr): 75 if phys_addr == 0: 76 return "N/A" 77 if is_system_ram(phys_addr): 78 return "System RAM" 79 80 if is_persistent_mem(phys_addr): 81 return "Persistent Memory" 82 83 #slow path, search all 84 f.seek(0, 0) 85 for j in f: 86 m = re.split('-|:',j,2) 87 if int(m[0], 16) <= phys_addr <= int(m[1], 16): 88 return m[2] 89 return "N/A" 90 91def process_event(param_dict): 92 name = param_dict["ev_name"] 93 sample = param_dict["sample"] 94 phys_addr = sample["phys_addr"] 95 96 global event_name 97 if event_name == None: 98 event_name = name 99 load_mem_type_cnt[find_memory_type(phys_addr)] += 1 100