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