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