GNU Linux-libre 4.19.264-gnu1
[releases.git] / tools / perf / scripts / python / mem-phys-addr.py
1 # mem-phys-addr.py: Resolve physical address samples
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # Copyright (c) 2018, Intel Corporation.
5
6 from __future__ import division
7 import os
8 import sys
9 import struct
10 import re
11 import bisect
12 import collections
13
14 sys.path.append(os.environ['PERF_EXEC_PATH'] + \
15         '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
16
17 #physical address ranges for System RAM
18 system_ram = []
19 #physical address ranges for Persistent Memory
20 pmem = []
21 #file object for proc iomem
22 f = None
23 #Count for each type of memory
24 load_mem_type_cnt = collections.Counter()
25 #perf event name
26 event_name = None
27
28 def 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
40 def 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
50 def trace_begin():
51         parse_iomem()
52
53 def trace_end():
54         print_memory_type()
55         f.close()
56
57 def 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
64 def is_persistent_mem(phys_addr):
65         position = bisect.bisect(pmem, phys_addr)
66         if position % 2 == 0:
67                 return False
68         return True
69
70 def 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
87 def 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