xref: /openbmc/linux/tools/perf/scripts/python/mem-phys-addr.py (revision 597473720f4dc69749542bfcfed4a927a43d935e)
141013f0cSKan Liang# mem-phys-addr.py: Resolve physical address samples
241013f0cSKan Liang# SPDX-License-Identifier: GPL-2.0
341013f0cSKan Liang#
441013f0cSKan Liang# Copyright (c) 2018, Intel Corporation.
541013f0cSKan Liang
641013f0cSKan Liangfrom __future__ import division
7e4d053ddSTony Jonesfrom __future__ import print_function
8e4d053ddSTony Jones
941013f0cSKan Liangimport os
1041013f0cSKan Liangimport sys
1141013f0cSKan Liangimport struct
1241013f0cSKan Liangimport re
1341013f0cSKan Liangimport bisect
1441013f0cSKan Liangimport collections
1541013f0cSKan Liang
1641013f0cSKan Liangsys.path.append(os.environ['PERF_EXEC_PATH'] + \
1741013f0cSKan Liang	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
1841013f0cSKan Liang
1941013f0cSKan Liang#physical address ranges for System RAM
2041013f0cSKan Liangsystem_ram = []
2141013f0cSKan Liang#physical address ranges for Persistent Memory
2241013f0cSKan Liangpmem = []
2341013f0cSKan Liang#file object for proc iomem
2441013f0cSKan Liangf = None
2541013f0cSKan Liang#Count for each type of memory
2641013f0cSKan Liangload_mem_type_cnt = collections.Counter()
2741013f0cSKan Liang#perf event name
2841013f0cSKan Liangevent_name = None
2941013f0cSKan Liang
3041013f0cSKan Liangdef parse_iomem():
3141013f0cSKan Liang	global f
3241013f0cSKan Liang	f = open('/proc/iomem', 'r')
3341013f0cSKan Liang	for i, j in enumerate(f):
3441013f0cSKan Liang		m = re.split('-|:',j,2)
3541013f0cSKan Liang		if m[2].strip() == 'System RAM':
36e4d053ddSTony Jones			system_ram.append(int(m[0], 16))
37e4d053ddSTony Jones			system_ram.append(int(m[1], 16))
3841013f0cSKan Liang		if m[2].strip() == 'Persistent Memory':
39e4d053ddSTony Jones			pmem.append(int(m[0], 16))
40e4d053ddSTony Jones			pmem.append(int(m[1], 16))
4141013f0cSKan Liang
4241013f0cSKan Liangdef print_memory_type():
43e4d053ddSTony Jones	print("Event: %s" % (event_name))
44e4d053ddSTony Jones	print("%-40s  %10s  %10s\n" % ("Memory type", "count", "percentage"), end='')
45e4d053ddSTony Jones	print("%-40s  %10s  %10s\n" % ("----------------------------------------",
4641013f0cSKan Liang					"-----------", "-----------"),
47e4d053ddSTony Jones					end='');
4841013f0cSKan Liang	total = sum(load_mem_type_cnt.values())
4941013f0cSKan Liang	for mem_type, count in sorted(load_mem_type_cnt.most_common(), \
50e4d053ddSTony Jones					key = lambda kv: (kv[1], kv[0]), reverse = True):
51*b504d7f6STony Jones		print("%-40s  %10d  %10.1f%%\n" %
52*b504d7f6STony Jones			(mem_type, count, 100 * count / total),
53e4d053ddSTony Jones			end='')
5441013f0cSKan Liang
5541013f0cSKan Liangdef trace_begin():
5641013f0cSKan Liang	parse_iomem()
5741013f0cSKan Liang
5841013f0cSKan Liangdef trace_end():
5941013f0cSKan Liang	print_memory_type()
6041013f0cSKan Liang	f.close()
6141013f0cSKan Liang
6241013f0cSKan Liangdef is_system_ram(phys_addr):
6341013f0cSKan Liang	#/proc/iomem is sorted
6441013f0cSKan Liang	position = bisect.bisect(system_ram, phys_addr)
6541013f0cSKan Liang	if position % 2 == 0:
6641013f0cSKan Liang		return False
6741013f0cSKan Liang	return True
6841013f0cSKan Liang
6941013f0cSKan Liangdef is_persistent_mem(phys_addr):
7041013f0cSKan Liang	position = bisect.bisect(pmem, phys_addr)
7141013f0cSKan Liang	if position % 2 == 0:
7241013f0cSKan Liang		return False
7341013f0cSKan Liang	return True
7441013f0cSKan Liang
7541013f0cSKan Liangdef find_memory_type(phys_addr):
7641013f0cSKan Liang	if phys_addr == 0:
7741013f0cSKan Liang		return "N/A"
7841013f0cSKan Liang	if is_system_ram(phys_addr):
7941013f0cSKan Liang		return "System RAM"
8041013f0cSKan Liang
8141013f0cSKan Liang	if is_persistent_mem(phys_addr):
8241013f0cSKan Liang		return "Persistent Memory"
8341013f0cSKan Liang
8441013f0cSKan Liang	#slow path, search all
8541013f0cSKan Liang	f.seek(0, 0)
8641013f0cSKan Liang	for j in f:
8741013f0cSKan Liang		m = re.split('-|:',j,2)
88e4d053ddSTony Jones		if int(m[0], 16) <= phys_addr <= int(m[1], 16):
8941013f0cSKan Liang			return m[2]
9041013f0cSKan Liang	return "N/A"
9141013f0cSKan Liang
9241013f0cSKan Liangdef process_event(param_dict):
9341013f0cSKan Liang	name       = param_dict["ev_name"]
9441013f0cSKan Liang	sample     = param_dict["sample"]
9541013f0cSKan Liang	phys_addr  = sample["phys_addr"]
9641013f0cSKan Liang
9741013f0cSKan Liang	global event_name
9841013f0cSKan Liang	if event_name == None:
9941013f0cSKan Liang		event_name = name
10041013f0cSKan Liang	load_mem_type_cnt[find_memory_type(phys_addr)] += 1
101