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